Systems-Modeling / SysML-v2-Pilot-Implementation

Proof-of-concept pilot implementation of the SysML v2 textual notation and visualization
GNU Lesser General Public License v3.0
114 stars 23 forks source link

NullPointerException when Loading Resource in Standalone Transpiler #483

Closed ammrat13 closed 1 year ago

ammrat13 commented 1 year ago

I am attempting to write a standalone "transpiler" for SysMLv2. The idea is to traverse the generated model to automatically generate some configuration files. I'm new to Xtext as a whole, so I haven't made much progress. Currently, I'm just trying to load a SysML file and dump the model.

My code is:

package io.github.ammrat13.sysml.test;

import org.eclipse.emf.common.util.URI;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.omg.sysml.lang.sysml.SysMLPackage;
import org.omg.sysml.xtext.SysMLStandaloneSetup;

public class Test {

    public static void main(String[] args) {

        // Register file extensions for SysML, as well as the actual EMF package
        // See: https://wiki.eclipse.org/EMF/FAQ#How_do_I_use_EMF_in_standalone_applications_.28such_as_an_ordinary_main.29.3F
        SysMLStandaloneSetup.doSetup();
        SysMLPackage.eINSTANCE.eClass();

        // Create the resource set we're going to use for compiling
        XtextResourceSet resourceSet = new XtextResourceSet();

        // Load all the files given in the arguments as resources
        for (String arg : args) {
            // Dump the file we're loading
            System.err.println("Loading: " + arg);
            // Create the resource
            URI uri = URI.createFileURI(arg);
            resourceSet.getResource(uri, true);
        }
    }

}

The printout is:

Loading: /home/ammrat13/Desktop/test.sysml
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.eclipse.emf.ecore.EStructuralFeature$Internal$DynamicValueHolder.dynamicGet(int)" because "settings" is null
    at org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSettingDelegateSingleEObject.dynamicSet(EStructuralFeatureImpl.java:2664)
    at org.omg.sysml.lang.sysml.impl.OwningMembershipImpl.setOwnedMemberElement(OwningMembershipImpl.java:276)
    at org.omg.sysml.lang.sysml.impl.OwningMembershipImpl.setMemberElement(OwningMembershipImpl.java:238)
    at org.omg.sysml.lang.sysml.impl.MembershipImpl.eUnset(MembershipImpl.java:596)
    at org.omg.sysml.lang.sysml.impl.OwningMembershipImpl.eUnset(OwningMembershipImpl.java:465)
    at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eUnset(BasicEObjectImpl.java:1197)
    at org.eclipse.xtext.linking.impl.AbstractCleaningLinker.clearReference(AbstractCleaningLinker.java:120)
    at org.omg.kerml.xtext.scoping.KerMLLinker.clearReference(KerMLLinker.java:77)
    at org.eclipse.xtext.linking.impl.AbstractCleaningLinker.clearReferences(AbstractCleaningLinker.java:115)
    at org.omg.kerml.xtext.scoping.KerMLLinker.clearReferences(KerMLLinker.java:42)
    at org.eclipse.xtext.linking.lazy.LazyLinker.access$200(LazyLinker.java:63)
    at org.eclipse.xtext.linking.lazy.LazyLinker$2.process(LazyLinker.java:102)
    at org.eclipse.xtext.linking.lazy.LazyLinker$2.process(LazyLinker.java:94)
    at org.eclipse.xtext.util.concurrent.IUnitOfWork$Void.exec(IUnitOfWork.java:38)
    at org.eclipse.xtext.util.OnChangeEvictingCache.execWithoutCacheClear(OnChangeEvictingCache.java:145)
    at org.eclipse.xtext.linking.lazy.LazyLinker.doLinkModel(LazyLinker.java:94)
    at org.eclipse.xtext.linking.impl.AbstractCleaningLinker.linkModel(AbstractCleaningLinker.java:52)
    at org.eclipse.xtext.resource.XtextResource.doLinking(XtextResource.java:353)
    at org.eclipse.xtext.linking.lazy.LazyLinkingResource.doLinking(LazyLinkingResource.java:122)
    at org.eclipse.xtext.resource.XtextResource.updateInternalState(XtextResource.java:304)
    at org.eclipse.xtext.resource.DerivedStateAwareResource.updateInternalState(DerivedStateAwareResource.java:171)
    at org.eclipse.xtext.resource.XtextResource.updateInternalState(XtextResource.java:292)
    at org.eclipse.xtext.resource.DerivedStateAwareResource.updateInternalState(DerivedStateAwareResource.java:163)
    at org.eclipse.xtext.resource.XtextResource.doLoad(XtextResource.java:182)
    at org.eclipse.xtext.linking.lazy.LazyLinkingResource.doLoad(LazyLinkingResource.java:115)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1563)
    at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1342)
    at org.eclipse.xtext.resource.persistence.StorageAwareResource.load(StorageAwareResource.java:95)
    at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoad(ResourceSetImpl.java:259)
    at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoadHelper(ResourceSetImpl.java:274)
    at org.eclipse.xtext.resource.XtextResourceSet.getResource(XtextResourceSet.java:266)
    at org.aerospace.sysml.test.Test.main(Test.java:26)

I don't know if this is an issue with SysML's code. I believe it is since the code for OwningMembershipImpl.java calls:

@Override
public void setOwnedMemberElement(Element newOwnedMemberElement) {
    OWNED_MEMBER_ELEMENT__ESETTING_DELEGATE.dynamicSet(this, null, 0, newOwnedMemberElement);
}

while the callee assumes that the second parameter settings is not null. It is likely not a version issue since I'm using Eclipse 2022-09 with SysMLv2 Release 2023-02. Most likely though is that I'm not registering something that I'm supposed to. What might that be?

ammrat13 commented 1 year ago

Strangely, regenerating the model files from SysML_.genmodel (not SysML.genmodel) seems to resolve this particular issue, at the expense of creating many more. Specifically, many methods that are supposed to be of the form isX() are actually isIsX().

seidewitz commented 1 year ago

Properly initializing the SysML setup is not simple. Luckily, the pilot implementation includes some utility classes to help with this. Unfortunately, it is probably not at all clear what and where these are!

To start with, I would suggest you look at org.omg.sysml.util.SysMLUtil, which we use as the base class for pretty much all standalone utilities that use KerML and SysML resources. You can see how this is used with Xtext in the classes in org.omg.kerml.xtext.util and org.omg.sysml.xtext.util.

However, the easiest way to programmatically access the pilot implementation environment is to use the org.omg.sysml.interactive.SysMLInteractive class that is the basis for implementing the Jupyter kernel for SysML. This has been discussed previously in the SysML v2 Google Group. If you would like to discuss this further, please post your issue there, and I can repost the example of how to use SysMLInteractive.

PS: Don't use SysML_.genmodel. This is just a work around for some problems with getting the Xtext work flows to run.

ammrat13 commented 1 year ago

See: https://groups.google.com/g/sysml-v2-release/c/LlEl8tHTP8o