Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » ATL » Need help with programmatic ATL module loading...(Running into an exception while loading a test ATL EMFTVM module from a standalone Java application.)
Need help with programmatic ATL module loading... [message #1817616] Tue, 26 November 2019 17:53 Go to next message
Olivier Hurez-Martin is currently offline Olivier Hurez-MartinFriend
Messages: 20
Registered: May 2019
Junior Member
Hello,

Please bare with me: I am relatively new to ATL...

I am trying to run multiple ATL transformations from a standalone Java application developed using Eclipse 2019-09, EMF SDK 2.19, and ATL 4.1.0 (incidentally, on Windows) and built with Maven.

The core ATL runner is inspired from:



Thank you very much to the authors of these examples!

I had to update the versions to match the application requirements, which may be part of my problem.

While attempting to load the compiled ATL module, I run into an exception:

org.eclipse.m2m.atl.emftvm.util.VMException: Error during module loading: Cannot create a resource for 'd:\Dev\LoadModule\target\test-classes\test\Class2Relational.emftvm'; a registered resource factory is needed
	at org.eclipse.m2m.atl.emftvm.impl.ExecEnvImpl.loadModule(ExecEnvImpl.java:1270)
[...]
Caused by: java.lang.RuntimeException: Cannot create a resource for 'd:\Dev\LoadModule\target\test-classes\test\Class2Relational.emftvm'; a registered resource factory is needed
	at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResource(ResourceSetImpl.java:403)
	at org.eclipse.m2m.atl.emftvm.util.DefaultModuleResolver.resolveModule(DefaultModuleResolver.java:67)
	at org.eclipse.m2m.atl.emftvm.impl.ExecEnvImpl.loadModule(ExecEnvImpl.java:1243)


Yet, the code loads the required factories. I tried many variations - global registry or locally to the resource set passed into the module resolver. The populated maps are visible under debug. I also tried the ClassModuleResolver, as the application may eventually have to run multiple translations in parallel, but could not get that to work either (is there a working example, beyond code snippets in the doc?)

Something must be off in the environment! I spent a a lot of time trying to figure it out and reached my wits end :-/

I attached a trimmed Eclipse Maven Java project that isolates the issue in a JUnit test while preserving the relevant parts of the project structure, namely the updated dependencies (I'd welcome a documentation update with a coherent set of dependencies in their latest versions ;-)

The single, failing test case included is com.vistology.m2m.AtlRunTests.test_load_emftvm_module()
(for more independence, the transformation itself is borrowed from the ATLrunner test case)

Could someone please point out what I am doing wrong?

Thank you!

-- Olivier H.Martin.





[Updated on: Tue, 26 November 2019 18:57]

Report message to a moderator

Re: Need help with programmatic ATL module loading... [message #1817683 is a reply to message #1817616] Wed, 27 November 2019 20:03 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 581
Registered: September 2012
Location: Belgium
Senior Member

I get this error instead when running AtlRunTests:

org.eclipse.m2m.atl.emftvm.util.VMException: Error during module loading: Metamodel Relational not found
	at org.eclipse.m2m.atl.emftvm.impl.ExecEnvImpl.loadModule(ExecEnvImpl.java:1270)
	at org.eclipse.m2m.atl.emftvm.impl.ExecEnvImpl.loadModule(ExecEnvImpl.java:1222)
	at com.vistology.m2m.AtlRunTests.test_load_emftvm_module(AtlRunTests.java:69)
Caused by: java.lang.IllegalArgumentException: Metamodel Relational not found
	at org.eclipse.m2m.atl.emftvm.impl.ExecEnvImpl.findType(ExecEnvImpl.java:2068)
	at org.eclipse.m2m.atl.emftvm.impl.ExecEnvImpl.findEClassifier(ExecEnvImpl.java:2159)
	at org.eclipse.m2m.atl.emftvm.impl.ExecEnvImpl.registerFeature(ExecEnvImpl.java:1322)
	at org.eclipse.m2m.atl.emftvm.impl.ExecEnvImpl.loadModule(ExecEnvImpl.java:1247)
	... 67 more


This error is caused by the fact that you need to do env.registerMetaModel() first: the meta-classes declared in the EMFTVM module are linked against the loaded metamodel at load time, so metamodels must be present in the ExecEnv before loading any EMFTVM modules.


Cheers,
Dennis

[Updated on: Wed, 27 November 2019 20:08]

Report message to a moderator

Re: Need help with programmatic ATL module loading... [message #1817686 is a reply to message #1817616] Wed, 27 November 2019 20:30 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 581
Registered: September 2012
Location: Belgium
Senior Member

I've attached the fixed Eclipse project that works for me on my Linux machine. Chances are this still won't work for you, because EMF's URI class is not happy with Windows file paths. As you move to packaging your Maven project as a JAR file, things become gradually worse. That's why the ClassModuleResolver exists: it is robust over all stages of your development/deployment, and works cross-platform.

(In fact, I may attach a second version of the project that uses ClassModuleResolver...)


Cheers,
Dennis
Re: Need help with programmatic ATL module loading... [message #1817687 is a reply to message #1817686] Wed, 27 November 2019 20:39 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 581
Registered: September 2012
Location: Belgium
Senior Member

And here's the version that uses ClassModuleResolver.

Cheers,
Dennis
Re: Need help with programmatic ATL module loading... [message #1817825 is a reply to message #1817687] Fri, 29 November 2019 18:21 Go to previous messageGo to next message
Olivier Hurez-Martin is currently offline Olivier Hurez-MartinFriend
Messages: 20
Registered: May 2019
Junior Member
Neat!
I'll try and integrate that in my project and let you know....

Thank you Dennis!
Re: Need help with programmatic ATL module loading... [message #1817826 is a reply to message #1817825] Fri, 29 November 2019 18:30 Go to previous messageGo to next message
Olivier Hurez-Martin is currently offline Olivier Hurez-MartinFriend
Messages: 20
Registered: May 2019
Junior Member
BTW, any reason (other than perhaps historical precedence) why EMF uses its own URI interface rather than java.net.URI ?
I found out the hard way that the string representations are not fully compatible...
If historical indeed, and preserved for backwards compatibility, perhaps should the EMF URI interface provide a couple of methods for back and forth conversions!

Cheers,

-- Olivier.
Re: Need help with programmatic ATL module loading... [message #1817832 is a reply to message #1817826] Fri, 29 November 2019 23:58 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 581
Registered: September 2012
Location: Belgium
Senior Member

The primary purpose of EMF's URI class was probably to provide integration with the Eclipse platform ("platform:/..." style URIs), and at the same time allow standalone usage ("file:/...", "http://..."). It does not integrate with Java's classloading/-resolving features, as found in the java.net.URL class. To bridge that gap, you have to provide an EMF's Resource content as an InputStream, which can be provided by java.net.URL.

Cheers,
Dennis
Re: Need help with programmatic ATL module loading... [message #1817838 is a reply to message #1817832] Sat, 30 November 2019 12:14 Go to previous messageGo to next message
Olivier Hurez-Martin is currently offline Olivier Hurez-MartinFriend
Messages: 20
Registered: May 2019
Junior Member
About the URI... Thank you for the clarification, it makes good sense.

On the demos for DefaultModuleResolver and ClassModuleResolver:

The ClassModuleResolver method worked well on Windows, with the caveat that we lose the ability to let the user decide about the location of the transformation files.

The DefaultModuleResolver method however appears broken on Windows, as you foresaw, perhaps due to some issue with EMF URIs on Windows.

The strange part, though, is I still get the same exception about missing a resource factory registration, although all needed resource factories are registered the same way in both examples!
And the URI.createURI() method appears to work alright when registering factories and metamodels with the resource set. As a matter of fact, the part of the code that retrieves the transformation module name works well, while using the windows style URI "file:/D:/Dev/Tests/TestLoadModule/target/test-classes/test/Class2Relational.emftvm".


Here are the exception details:

org.eclipse.m2m.atl.emftvm.util.VMException: Error during module loading: Cannot create a resource for 'd:\Dev\Tests\TestLoadModule\target\test-classes\test\Class2Relational.emftvm'; a registered resource factory is needed
	at org.eclipse.m2m.atl.emftvm.impl.ExecEnvImpl.loadModule(ExecEnvImpl.java:1270)
	at org.eclipse.m2m.atl.emftvm.impl.ExecEnvImpl.loadModule(ExecEnvImpl.java:1222)
	at com.vistology.m2m.AtlRunTests.test_load_emftvm_module(AtlRunTests.java:91)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137)
	at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Caused by: java.lang.RuntimeException: Cannot create a resource for 'd:\Dev\Tests\TestLoadModule\target\test-classes\test\Class2Relational.emftvm'; a registered resource factory is needed
	at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResource(ResourceSetImpl.java:403)
	at org.eclipse.m2m.atl.emftvm.util.DefaultModuleResolver.resolveModule(DefaultModuleResolver.java:67)
	at org.eclipse.m2m.atl.emftvm.impl.ExecEnvImpl.loadModule(ExecEnvImpl.java:1243)
	... 67 more



Thanks,

-- Olivier.

[Updated on: Sat, 30 November 2019 12:39]

Report message to a moderator

Re: Need help with programmatic ATL module loading... [message #1817905 is a reply to message #1817838] Mon, 02 December 2019 21:21 Go to previous messageGo to next message
Olivier Hurez-Martin is currently offline Olivier Hurez-MartinFriend
Messages: 20
Registered: May 2019
Junior Member
Both methods now work on Windows...

For whomever running into the same issue on Windows, working code for both methods: DefaultModuleResolver and ClassModuleResolver, is included as distinct JUnit test cases within the attached project.

It ought to work on other platforms as well, as we stick to platform independent URIs to locate resources.

Thank you Dennis for providing the full solution with ClassModuleResolver, and the correct method using DefaultModuleResolver for Linux, which made the adaptation to Windows trivial!

Cheers,

-- Olivier.


[Updated on: Tue, 03 December 2019 20:50]

Report message to a moderator

Re: Need help with programmatic ATL module loading... [message #1818058 is a reply to message #1817905] Wed, 04 December 2019 22:18 Go to previous message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 581
Registered: September 2012
Location: Belgium
Senior Member

You're welcome! Thank you for sharing your solution!

Cheers,
Dennis
Previous Topic:Issue with string comparison in helper...
Next Topic:ATL 4.2.0 has been released!
Goto Forum:
  


Current Time: Sat Nov 11 08:18:17 GMT 2023

Powered by FUDForum. Page generated in 0.02037 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top