eclipse / epsilon

Epsilon is a family of Java-based scripting languages for automating common model-based software engineering tasks, such as code generation, model-to-model transformation and model validation, that work out of the box with EMF (including Xtext and Sirius), UML (including Cameo/MagicDraw), Simulink, XML and other types of models.
https://eclipse.org/epsilon
Eclipse Public License 2.0
66 stars 10 forks source link

Loading the same model twice and then disposing all models causes an error #68

Closed agarciadom closed 9 months ago

agarciadom commented 9 months ago

While trying to reproduce #67, I noticed that running this simple build.xml produced an error message:

<project default="main" xmlns:ivy="antlib:org.apache.ivy.ant">
  <target name="main">
    <epsilon.emf.loadModel name="ModelA"
      modelFile="TestModel.flexmi" 
      metamodelFile="metamodel.emf" 
      read="true" store="false" />
  <epsilon.emf.loadModel name="ModelB"
    modelFile="TestModel.flexmi" 
    metamodelFile="metamodel.emf" 
    read="true" store="false" />
  <epsilon.disposeModels />
</target>
</project>

The error message is as follows:

main:
[epsilon.disposeModels] Cannot find meta-class 'Element' in model 'ModelA'
[epsilon.disposeModels]     at org.eclipse.epsilon.emc.emf.AbstractEmfModel.classForName(AbstractEmfModel.java:268)
[epsilon.disposeModels]     at org.eclipse.epsilon.emc.emf.AbstractEmfModel.getCacheKeyForType(AbstractEmfModel.java:253)
[epsilon.disposeModels]     at org.eclipse.epsilon.eol.models.CachedModel.removeFromCache(CachedModel.java:187)
[epsilon.disposeModels]     at org.eclipse.epsilon.emc.emf.EmfModel.forceRemoveFromCache(EmfModel.java:318)
[epsilon.disposeModels]     at org.eclipse.epsilon.emc.emf.EmfModel$CachedContentsAdapter.handle(EmfModel.java:243)
[epsilon.disposeModels]     at org.eclipse.epsilon.emc.emf.EmfModel$CachedContentsAdapter.notifyChanged(EmfModel.java:186)
[epsilon.disposeModels]     at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:424)
[epsilon.disposeModels]     at org.eclipse.emf.common.notify.impl.NotifyingListImpl.dispatchNotification(NotifyingListImpl.java:261)
[epsilon.disposeModels]     at org.eclipse.emf.common.notify.impl.NotifyingListImpl.clear(NotifyingListImpl.java:1099)
[epsilon.disposeModels]     at org.eclipse.emf.ecore.resource.impl.ResourceImpl.doUnload(ResourceImpl.java:1699)
[epsilon.disposeModels]     at org.eclipse.emf.ecore.resource.impl.ResourceImpl.unload(ResourceImpl.java:1721)
[epsilon.disposeModels]     at org.eclipse.epsilon.emc.emf.CachedResourceSet$Cache.returnResource(CachedResourceSet.java:123)
[epsilon.disposeModels]     at org.eclipse.epsilon.emc.emf.AbstractEmfModel.disposeModel(AbstractEmfModel.java:404)
[epsilon.disposeModels]     at org.eclipse.epsilon.eol.models.CachedModel.dispose(CachedModel.java:312)
[epsilon.disposeModels]     at org.eclipse.epsilon.workflow.tasks.DisposeModelsTask.executeImpl(DisposeModelsTask.java:20)
[epsilon.disposeModels]     at org.eclipse.epsilon.workflow.tasks.EpsilonTask.execute(EpsilonTask.java:42)
[epsilon.disposeModels]     at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:299)
[epsilon.disposeModels]     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[epsilon.disposeModels]     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[epsilon.disposeModels]     at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[epsilon.disposeModels]     at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[epsilon.disposeModels]     at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:99)
[epsilon.disposeModels]     at org.apache.tools.ant.Task.perform(Task.java:350)
[epsilon.disposeModels]     at org.apache.tools.ant.Target.execute(Target.java:449)
[epsilon.disposeModels]     at org.apache.tools.ant.Target.performTasks(Target.java:470)
[epsilon.disposeModels]     at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1401)
[epsilon.disposeModels]     at org.apache.tools.ant.Project.executeTarget(Project.java:1374)
[epsilon.disposeModels]     at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
[epsilon.disposeModels]     at org.eclipse.ant.internal.core.ant.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:34)
[epsilon.disposeModels]     at org.apache.tools.ant.Project.executeTargets(Project.java:1264)
[epsilon.disposeModels]     at org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRunner.java:712)
[epsilon.disposeModels]     at org.eclipse.ant.internal.core.ant.InternalAntRunner.run(InternalAntRunner.java:532)
[epsilon.disposeModels]     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[epsilon.disposeModels]     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[epsilon.disposeModels]     at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[epsilon.disposeModels]     at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[epsilon.disposeModels]     at org.eclipse.ant.core.AntRunner.run(AntRunner.java:369)
[epsilon.disposeModels]     at org.eclipse.ant.internal.launching.launchConfigurations.AntLaunchDelegate.lambda$0(AntLaunchDelegate.java:271)
[epsilon.disposeModels]     at java.base/java.lang.Thread.run(Thread.java:829)

The build still passes, but it really should not be raising this error.

agarciadom commented 9 months ago

Weirdly enough, this build passes because we simply print out the exception but continue regardless:

https://github.com/eclipse/epsilon/blob/5e0f131407ea7875766a852ebef77e193129226d/plugins/org.eclipse.epsilon.emc.emf/src/org/eclipse/epsilon/emc/emf/EmfModel.java#L250C2-L252C2

micfort commented 9 months ago

I solved this problem by registering the EPackages of the metamodel.

agarciadom commented 9 months ago

I solved this problem by registering the EPackages of the metamodel.

That's more of a workaround, but I'm working on a fix :-). We do a bit of setup to cache Type.all, and we should undo that setup while clearing the cache. It's hard to get caching right on the first try!