eclipse-ocl / org.eclipse.ocl

Eclipse Public License 2.0
0 stars 0 forks source link

Evaluation of a custom oclstdlib operation fails #1676

Closed eclipse-ocl-bot closed 2 hours ago

eclipse-ocl-bot commented 2 hours ago

| --- | --- | | Bugzilla Link | 489310 | | Status | RESOLVED FIXED | | Importance | P3 normal | | Reported | Mar 09, 2016 13:36 EDT | | Modified | Mar 12, 2016 16:25 EDT | | Reporter | Marcus Huewe |

Description

Created attachment 260186\ testcase for reproduction

Currently, it is not possible to evaluate an OCL query that uses an\ operation of a custom oclstdlib.\ For a concrete testcase see 0001-Added-testcase-for-the-evaluation-of-a-custom-oclstd.patch.

The problem is that no classloader is registered that could load the referenced\ class. The attached patch fixes this by explicitly registering a classloader,\ which uses the correct Bundle to load the class (see 0002-Fixed-the-evaluation-of-a-custom-oclstdlib-operation.patch).\ Note: the current approach only works for a CSResource that is backed up by a\ platform:/plugin/ URI (I couldn't find a way how to find the correct bundle\ based on, e.g., a file:/ URI).

:notepad_spiral: 0001-Added-testcase-for-the-evaluation-of-a-custom-oclstd.patch

eclipse-ocl-bot commented 2 hours ago

By Marcus Huewe on Mar 09, 2016 13:37

Created attachment 260187 0002-Fixed-the-evaluation-of-a-custom-oclstdlib-operation.patch

:notepad_spiral: 0002-Fixed-the-evaluation-of-a-custom-oclstdlib-operation.patch

eclipse-ocl-bot commented 2 hours ago

By Ed Willink on Mar 12, 2016 09:30

Thanks.

Really nice to get problem + JUnit test + fix in apply-patchable form.

Unfortunately your test passes only as a plugin test; not as a standalone test. Anyway you point at in interesting implementation hole.

Please sign the "CLA" so that I can use your code. (Follow the CLA link next to your name on one of the comments.)

eclipse-ocl-bot commented 2 hours ago

By Ed Willink on Mar 12, 2016 10:29

(In reply to Marcus Huewe from comment #0)

The problem is that no classloader is registered that could load the referenced class.

Not exactly.

The problem is that the oclstdlib plugin class loader is used, rather than the user's class loader, whose classpath should reference everything interesting.

eclipse-ocl-bot commented 2 hours ago

By Ed Willink on Mar 12, 2016 16:25

(In reply to Ed Willink from comment #3)\ Potentially we know that the OCL facade was constructed by the user and so could have a good ClassLoader if it was also loaded in order to construct. BUt there is no navigation bck to the OCL so once we lose the OCL, we cannot use it to find a good ClassLoader.

The ImplementationManager under the supervision of the MetaModelManager has a class loader list. We just need to use it to configure the JavaClassScope.

But more ClassLoaders in a JavaClassScope will make Bug 456235 even worse; better fix it first.

OCLstdlibScopeProvider.getScope has the comment

// Should already be there so this fall-back classLoader is not used.

on a ClassLoader fixup from the csResource. It's REsourceSet might be a bit better, but realistically we just need

ocl.getMetamodelManager().addClassLoader(getClass().getClassLoader());

in the user test code so that user's ClassLoader is known. In the specific case of ocl.getMetamodelManager() thsi might be hidden, but ocl.getEnvironmentFactory().getMetamodelManager() wouldn't hide it.

Seems users will have to learn to register their class loaders. It's a little less opaque as in the test:

public void testImport_CompleteOCL_custom_OCLstdlib_eval() throws Exception {\
    BaseLinkingService.DEBUG_RETRY.setState(true);\
    TestOCL ocl = createOCL();\
    String customLibrary =\
        "library lib : lib = 'http://custom.oclstdlib' {\n" + \
        "   type Real : PrimitiveType {\n" + \
        "       operation spacedOut() : String => 'org.eclipse.ocl.examples.test.xtext.ImportTests$SpacedOut';\n" + \
        "   }\n" + \
        "}";\
    ClassLoader classLoader = org.eclipse.ocl.examples.test.xtext.ImportTests.SpacedOut.class.getClassLoader();\
    assert classLoader != null;\
    ocl.getMetamodelManager().addClassLoader(classLoader);\
    doLoadFromString(ocl, "custom.oclstdlib", customLibrary);\
    ocl.assertQueryEquals(null, "42", "42.spacedOut()");\
    ocl.dispose();\
}

commit 0eb8c90713711f8abc5396f275b8d92e35e40af5 pushed to master for M6