osate / osate2

Open Source AADL2 Tool Environment
http://osate.org
Eclipse Public License 2.0
36 stars 8 forks source link

Null pointer exception in end to end flow instantiation #2287

Closed stevevestal closed 4 years ago

stevevestal commented 4 years ago

Summary

When I instantiate System Impl Example.Low in the attached model, a popup appears with subject message. There are no error markers on the model before instantiation. No other errors appear as markers or in the Problems tab. This behavior repeats after repeated project cleans.

Expected and Current Behavior

I would expect it to either instantiate without the popup notice or issue a more informative error message with markers on the instance file or AADL model.

Steps to Reproduce

Model attached

package Refinement
public

    feature group HighLevel
    end HighLevel;

    system HighLeft
        features
            outgroup: feature group HighLevel;
        flows
            outflow: flow source outgroup;
    end HighLeft;

    system HighRight
        features
            ingroup: feature group inverse of HighLevel;
        flows
            inflow: flow sink ingroup;          
    end HighRight;  

    system Example
    end Example;

    system implementation Example.High
        subcomponents
            left: system HighLeft;
            right: system HighRight;
--      connections
--          lr: feature left.outgroup -> right.ingroup;
--      flows
--          leftright: end to end flow left.outflow -> lr -> right.inflow;
    end Example.High;

    feature group LowLevel extends HighLevel
        features
            msg1: feature;
            msg2: feature;
    end LowLevel;

    system LowLeft extends HighLeft
        features
            outgroup: refined to feature group LowLevel{ Classifier_Substitution_Rule => Type_Extension; };
        flows
            outflow: refined to flow source; -- outgroup;
    end LowLeft;

    system LowRight extends HighRight
        features
            ingroup: refined to feature group inverse of LowLevel{ Classifier_Substitution_Rule => Type_Extension; };
        flows
            inflow: refined to flow sink; -- ingroup;           
    end LowRight;       

    system implementation Example.Low extends Example.High
        subcomponents
            left: refined to system LowLeft{ Classifier_Substitution_Rule => Type_Extension; };
            right: refined to system LowRight{ Classifier_Substitution_Rule => Type_Extension; };           
        connections
            lr1: feature left.outgroup.msg1 -> right.ingroup.msg1;
        flows
            leftright1: end to end flow left.outflow -> lr1 -> right.inflow;
    end Example.Low;

end Refinement;

Environment

lwrage commented 4 years ago

In OSATE 2.7.1 exceptions during instantiation are properly reported.

This model results in an NPE during flow instantiation.

java.lang.NullPointerException
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch.isValidContinuation(CreateEndToEndFlowsSwitch.java:643)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch.processFlowStep(CreateEndToEndFlowsSwitch.java:513)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch.processFlowStep(CreateEndToEndFlowsSwitch.java:470)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch.processSubcomponentFlow(CreateEndToEndFlowsSwitch.java:370)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch.processETESegment(CreateEndToEndFlowsSwitch.java:327)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch.continueFlow(CreateEndToEndFlowsSwitch.java:1091)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch.processFlowStep(CreateEndToEndFlowsSwitch.java:479)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch.processFlowStep(CreateEndToEndFlowsSwitch.java:470)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch.processSubcomponentFlow(CreateEndToEndFlowsSwitch.java:370)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch.processETESegment(CreateEndToEndFlowsSwitch.java:327)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch.processETE(CreateEndToEndFlowsSwitch.java:293)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch.instantiateEndToEndFlow(CreateEndToEndFlowsSwitch.java:285)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch$1.caseComponentInstance(CreateEndToEndFlowsSwitch.java:235)
    at org.osate.aadl2.instantiation.CreateEndToEndFlowsSwitch$1.caseComponentInstance(CreateEndToEndFlowsSwitch.java:1)
    at org.osate.aadl2.instance.util.InstanceSwitch.doSwitch(InstanceSwitch.java:370)
    at org.eclipse.emf.ecore.util.Switch.doSwitch(Switch.java:53)
    at org.eclipse.emf.ecore.util.Switch.doSwitch(Switch.java:69)
    at org.osate.aadl2.modelsupport.modeltraversal.AadlProcessingSwitch.process(AadlProcessingSwitch.java:159)
    at org.osate.aadl2.modelsupport.modeltraversal.ForAllElement.processObject(ForAllElement.java:278)
    at org.osate.aadl2.modelsupport.modeltraversal.PreOrderTraversal.visitRoot(PreOrderTraversal.java:42)
    at org.osate.aadl2.modelsupport.modeltraversal.ForAllElement.processPreOrderAll(ForAllElement.java:545)
    at org.osate.aadl2.instantiation.InstantiateModel.fillSystemInstance(InstantiateModel.java:460)
    at org.osate.aadl2.instantiation.InstantiateModel.createSystemInstanceInt(InstantiateModel.java:421)
    at org.osate.aadl2.instantiation.InstantiateModel.createSystemInstance(InstantiateModel.java:375)
    at org.osate.aadl2.instantiation.InstantiateModel.buildInstanceModelFile(InstantiateModel.java:240)
    at org.osate.ui.handlers.InstantiationHandler$InstantiationJob.runInWorkspace(InstantiationHandler.java:243)
...
AaronGreenhouse commented 4 years ago

When I instantiate Example.Low, I get the following

Now, of course, is the question of why do we get this.

AaronGreenhouse commented 4 years ago

This caused by the refinement of the flow specification. The refined model object doesn't have the data we need. We need to climb up to the original non-refined flow specification.

I'm not sure if this problem is going to come up in another spot in this code.

AaronGreenhouse commented 4 years ago

Exception comes from isValidContinuation(EndToEndFlowInstance etei, ConnectionInstance conni, FlowSpecification fspec).

This is called by processFlowStep(). We could also get an error message in the error reporting in this method where we call flowSpec.getInEnd():

                    if (flowFilter == null && nextFlowImpl == null) {
                        final FlowSpecification flowSpec = (FlowSpecification) leaf;
                        error(etei.getContainingComponentInstance(), "Cannot create end to end flow '" + etei.getName()
                                + "' because there are no semantic connections that connect to the start of the flow '"
                                + flowSpec.getName() + "' at feature '" + flowSpec.getInEnd().getFeature().getName()
                                + "'");
                    } else {

I think these are the only spots where this would be a problem.

AaronGreenhouse commented 4 years ago

Easy to fix, I think. Just replace getInEnd() with getAllInEnd()

AaronGreenhouse commented 4 years ago

That seems to fix things.

Need to add unit test

AaronGreenhouse commented 4 years ago

Fixed. Added test.