Community
Participate
Working Groups
Trying to validate a file with nodes containing references to external files fails with the following error trail. !MESSAGE Validation failed !STACK 0 java.lang.NullPointerException at org.eclipse.epsilon.evl.emf.validation.EvlValidator.validate(EvlValidator.java:149) at org.eclipse.epsilon.evl.emf.validation.EvlValidator.validate(EvlValidator.java:73) at org.eclipse.epsilon.evl.emf.validation.CompositeEValidator.validate(CompositeEValidator.java:44) at org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostician.java:165) at org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostician.java:143) at org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostician.java:114) at gsnModel.diagram.part.ValidateAction.runEMFValidator(ValidateAction.java:148) at gsnModel.diagram.part.ValidateAction.validate(ValidateAction.java:163) at gsnModel.diagram.part.ValidateAction.access$0(ValidateAction.java:156) at gsnModel.diagram.part.ValidateAction$2.run(ValidateAction.java:132) at gsnModel.diagram.providers.GsnModelValidationProvider$1.run(GsnModelValidationProvider.java:36) at org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl.runExclusive(TransactionalEditingDomainImpl.java:328) at gsnModel.diagram.providers.GsnModelValidationProvider.runWithConstraints(GsnModelValidationProvider.java:44) at gsnModel.diagram.part.ValidateAction.runValidation(ValidateAction.java:129) at gsnModel.diagram.part.ValidateAction$1.run(ValidateAction.java:75) at org.eclipse.ui.actions.WorkspaceModifyDelegatingOperation.execute(WorkspaceModifyDelegatingOperation.java:69) at org.eclipse.ui.actions.WorkspaceModifyOperation$1.run(WorkspaceModifyOperation.java:106) at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2344) at org.eclipse.ui.actions.WorkspaceModifyOperation.run(WorkspaceModifyOperation.java:118) at gsnModel.diagram.part.ValidateAction.run(ValidateAction.java:78) at org.eclipse.jface.action.Action.runWithEvent(Action.java:498) at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584) at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501) at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:411) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4165) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3754) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2696) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2660) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494) at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577) at org.eclipse.equinox.launcher.Main.run(Main.java:1410) at org.eclipse.equinox.launcher.Main.main(Main.java:1386) This error is reproducable. Create the following .emfatic model (just a shortcut here). @gmf.node(label="identifier", border.width="2", border.color="0,0,0", size="130,50", figure="rectangle", label.icon="false") class Goal{ attr String identifier; @gmf.link(target.decoration="filledclosedarrow", color="0,0,0") ref AwayGoal[*] SupportingAwaySubgoalsOfGoal; ref AwayGoal[*]#ReferencedGoal isReferencedByAwayGoals; } @gmf.node(label="identifier", border.width="1", border.color="0,0,0", size="130,50", label.icon="false", figure="rectangle") class AwayGoal { ref Goal[1]#isReferencedByAwayGoals ReferencedGoal; attr String AwayGoalModuleIdentifier; } This creates a bidirectional connection between the nodes Goal and AwayGoal. Now create an evl plugin like in the tutorial here : http://www.eclipse.org/gmt/epsilon/doc/articles/evl-gmf-integration/ wit the following content in the evl file: context Goal { constraint identifierIsSet { check : self.identifier.isDefined() message : 'Goal identifier is not set.' } Now do the following. Create FileA adding an AwayGoal to it. Create FileB adding a Goal to it, and dont set the Goal identifier. So the constraint in evl file have to show up. Open FileA, choose load resource action and load FileB. Set the reference ReferencedGoal from AwayGoal to the only goal in FileB. Now run validation on File A. The error shows up. When inspecting the code and debugging it shows up that the error is contained in EvlValidator.class. In line 149 there is the following instruction: for (EvlUnsatisfiedConstraint unsatisfied : module.getContext().getUnsatisfiedConstraints()) { results.get(unsatisfied.getInstance()).add(unsatisfied); } The UnsatisfiedConstraints contains all found constraints in all files. This result map seems to contain only objects from the main file (File A) from which the validation started and so this returns null for any object in external files. Would be really happy about a fix or workaround.
There exist also a post in the epsilon forums, which explains this again. Maybe this thread is more readable. http://www.eclipse.org/forums/index.php/mv/msg/275288/777525/#msg_777525
Created attachment 211454 [details] Minimal Eclipse project - manual EVL launch does work I can't reproduce this bug using a manual EVL launch, using the same two-model split (test files attached). I think it's only triggered when validating from a GMF diagram.
Created attachment 211455 [details] Plugins for the GMF-based graphical editor for goals
Created attachment 211456 [details] Models created using the GMF-based graphical editor And here are the models and its diagrams with the contents specified by Snakebyte. These do reproduce the described behaviour. Looks like I'll need to have a look at the differences between running a manual EVL launch and running the validation from a GMF diagram. For some reason, it's not following the cross-model reference in the second case.
The validation itself is performed normally, and detects the same issue as a manual EVL launch. The problem comes later, in this code (also pointed out by Snakebyte): TreeIterator<EObject> allContents = resource.getAllContents(); while (allContents.hasNext()) { EObject eObject = allContents.next(); ArrayList<EvlUnsatisfiedConstraint> unsatisfied = new ArrayList<EvlUnsatisfiedConstraint>(); results.put(eObject, unsatisfied); } for (EvlUnsatisfiedConstraint unsatisfied : module.getContext().getUnsatisfiedConstraints()) { results.get(unsatisfied.getInstance()).add(unsatisfied); } The main issue with this code is that it assumes that all the violations come from the EMF resource being validated. This is clearly not the case for the FileA model, and produces the described NullPointerException. The thing is: how should we really fix this? I could add a simple null check or a containsKey(...) call to the body of the second loop, but that'd mask all validation errors coming from external models. That would mislead users. I'd rather just add these messages to the Problems view, even if we can't give them a decorator marker, as they're not anywhere in the diagram. I'll look into implementing this fix tomorrow, then :-).
I have committed a fix to SVN. EVL errors in external models shouldn't produce NullPointerExceptions now, and they will show up in the Problems view prefixed with the URL of the actual resource they belong to.
This has been fixed in the latest interim version.
Fixed in 1.0