How to use Pivot OCL thread-safely? [message #1715724] |
Wed, 25 November 2015 13:41 |
Denis Nikiforov Messages: 344 Registered: August 2013 |
Senior Member |
|
|
Hi
We need to parse several OCL constraints (contained in some UML models) in parallel. Here is a test project: https://github.com/AresEkb/test_par_ocl
package test_par_ocl;
import java.io.File;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.ocl.pivot.ExpressionInOCL;
import org.eclipse.ocl.pivot.uml.UMLStandaloneSetup;
import org.eclipse.ocl.pivot.utilities.OCL;
import org.eclipse.ocl.pivot.utilities.ParserException;
import org.eclipse.ocl.xtext.essentialocl.EssentialOCLStandaloneSetup;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.resources.util.UMLResourcesUtil;
public class Main {
public static void main(String[] args) {
final String input = "model/my.uml";
ResourceSet rs = new ResourceSetImpl();
System.out.println("Initialization");
rs.setURIConverter(new CustomURIConverter());
System.out.println(" UML");
UMLResourcesUtil.init(rs);
System.out.println(" OCL");
EssentialOCLStandaloneSetup.doSetup();
UMLStandaloneSetup.init();
try {
System.out.println("Loading model " + input);
Resource resource = rs.getResource(createFileURI(input), true);
EObject model = resource.getContents().get(0);
// Uncomment the following lines and everything will work
// OCL ocl = OCL.newInstance();
// ocl.getMetamodelManager().getASOf(org.eclipse.ocl.pivot.Package.class, model);
// Parallel code
IntStream.rangeClosed(1, 10).boxed().collect(Collectors.toList()).parallelStream().forEach(i -> {
parseConstraints(model);
});
System.out.println("Done!");
} catch (Exception e) {
e.printStackTrace();
}
}
private static URI createFileURI(String relativePath) {
return URI.createFileURI(new File(relativePath).getAbsolutePath());
}
private static void parseConstraints(EObject model) {
model.eAllContents().forEachRemaining(obj -> {
if (obj instanceof Constraint) {
OCL ocl = OCL.newInstance();
ExpressionInOCL expr = null;
try {
org.eclipse.ocl.pivot.Constraint asConstraint = ocl.getMetamodelManager()
.getASOf(org.eclipse.ocl.pivot.Constraint.class, obj);
expr = ocl.getSpecification(asConstraint);
System.out.println(expr);
} catch (ParserException e) {
e.printStackTrace();
}
}
});
}
}
The problem is that we get the following exceptions:
org.eclipse.ocl.pivot.utilities.ParserException: Failed to load 'file:/C:/Work/workspace-test_par_qvto/test_par_ocl/model/my.uml.oclas' : null
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2AS$Outer.getASModel(UML2AS.java:603)
at org.eclipse.ocl.pivot.uml.internal.resource.UMLASResourceFactory.getASElement(UMLASResourceFactory.java:94)
at org.eclipse.ocl.pivot.internal.manager.PivotMetamodelManager.getASOf(PivotMetamodelManager.java:805)
at test_par_ocl.Main.lambda$1(Main.java:66)
at java.util.Iterator.forEachRemaining(Unknown Source)
at test_par_ocl.Main.parseConstraints(Main.java:60)
at test_par_ocl.Main.lambda$0(Main.java:46)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.ForEachOps$ForEachTask.compute(Unknown Source)
at java.util.concurrent.CountedCompleter.exec(Unknown Source)
at java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(Unknown Source)
at java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
at java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2ASUseSwitch.caseInstanceValue(UML2ASUseSwitch.java:192)
at org.eclipse.uml2.uml.util.UMLSwitch.doSwitch(UMLSwitch.java:4198)
at org.eclipse.emf.ecore.util.Switch.doSwitch(Switch.java:53)
at org.eclipse.emf.ecore.util.Switch.doSwitch(Switch.java:69)
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2ASUseSwitch.caseProperty(UML2ASUseSwitch.java:431)
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2ASUseSwitch.caseProperty(UML2ASUseSwitch.java:1)
at org.eclipse.uml2.uml.util.UMLSwitch.doSwitch(UMLSwitch.java:779)
at org.eclipse.emf.ecore.util.Switch.doSwitch(Switch.java:53)
at org.eclipse.emf.ecore.util.Switch.doSwitch(Switch.java:69)
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2AS$Outer.installUsers(UML2AS.java:854)
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2AS$Outer.getASModel(UML2AS.java:596)
... 15 more
org.eclipse.ocl.pivot.utilities.ParserException: Failed to load 'file:/C:/Work/workspace-test_par_qvto/test_par_ocl/model/my.uml.oclas' : 2
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2AS$Outer.getASModel(UML2AS.java:603)
at org.eclipse.ocl.pivot.uml.internal.resource.UMLASResourceFactory.getASElement(UMLASResourceFactory.java:94)
at org.eclipse.ocl.pivot.internal.manager.PivotMetamodelManager.getASOf(PivotMetamodelManager.java:805)
at test_par_ocl.Main.lambda$1(Main.java:66)
at java.util.Iterator.forEachRemaining(Unknown Source)
at test_par_ocl.Main.parseConstraints(Main.java:60)
at test_par_ocl.Main.lambda$0(Main.java:46)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.ForEachOps$ForEachTask.compute(Unknown Source)
at java.util.concurrent.CountedCompleter.exec(Unknown Source)
at java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(Unknown Source)
at java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
at java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 2
at org.eclipse.emf.ecore.impl.DynamicEObjectImpl.dynamicGet(DynamicEObjectImpl.java:292)
at org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSettingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.java:2194)
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1027)
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1011)
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1003)
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:998)
at org.eclipse.uml2.uml.internal.operations.ElementOperations.getValue(ElementOperations.java:603)
at org.eclipse.uml2.uml.internal.impl.ElementImpl.getValue(ElementImpl.java:297)
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2ASDeclarationSwitch.copyPackage(UML2ASDeclarationSwitch.java:722)
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2ASDeclarationSwitch.casePackage(UML2ASDeclarationSwitch.java:378)
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2ASDeclarationSwitch.casePackage(UML2ASDeclarationSwitch.java:1)
at org.eclipse.uml2.uml.util.UMLSwitch.doSwitch(UMLSwitch.java:1837)
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2ASDeclarationSwitch.doInPackageSwitch(UML2ASDeclarationSwitch.java:948)
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2ASDeclarationSwitch.doSwitch(UML2ASDeclarationSwitch.java:956)
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2AS.installDeclarations(UML2AS.java:1035)
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2AS$Outer.installImports(UML2AS.java:742)
at org.eclipse.ocl.pivot.uml.internal.es2as.UML2AS$Outer.getASModel(UML2AS.java:592)
... 15 more
But If I parse constraints not in parallel at first time, than everithing works fine. After that I can run parseConstraints() in parallel.
How to use Pivot OCL thread safely?
[Updated on: Wed, 25 November 2015 13:51] Report message to a moderator
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03061 seconds