Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » OCL » Problems with OCL validation and derived properties
Problems with OCL validation and derived properties [message #1827281] Tue, 12 May 2020 08:55 Go to next message
Andrzej Wąsowski is currently offline Andrzej WąsowskiFriend
Messages: 21
Registered: November 2019
Junior Member
After my instances have been nicely passing all OCL validation, I have now added a derived attribute "isInitial" to my ecore model using the following oclinecore:

    <eStructuralFeatures xsi:type="ecore:EAttribute" name="isInitial" 
        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean" volatile="true"
        derived="true">
      <eAnnotations source="http://www.eclipse.org/emf/2002/Ecore/OCL/Pivot">
        <details key="derivation" value="machine.initial = self"/>
      </eAnnotations>
    </eStructuralFeatures>


The full meta-model is available here: https://bitbucket.org/dsldesign/dsldesign/src/derived_attr/mdsebook.fsm/model/fsm.ecore (in a temporary branch). The derived property is not used in any invariants. It is just hanging there.

The code generation seems to work, the generated code compiles, and I checked it contains some code for the new property. Unfortunately the validation without OCL seems to be failing on the very same instances on which it was not failing before the derived property has been added to the meta-model. This kinda contradicts my understanding of derived properties, but the problem is hopefully not fundamental, but related to some technicalities.

I narrowed down the problem to this exception activated during OCL validation:
  java.lang.NullPointerException:
  at org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSettingDelegateSingleData.dynamicIsSet(EStructuralFeatureImpl.java:2293)
  at mdsebook.fsm.impl.StateImpl.eIsSet(StateImpl.java:302)
  at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eIsSet(BasicEObjectImpl.java:1280)
  at org.eclipse.emf.ecore.util.EObjectValidator.validate_DataValueConforms(EObjectValidator.java:832)
  at org.eclipse.emf.ecore.util.EObjectValidator.validate_EveryDataValueConforms(EObjectValidator.java:820)
  at mdsebook.fsm.util.FsmValidator.validateState(FsmValidator.java:343)
  at mdsebook.fsm.util.FsmValidator.validate(FsmValidator.java:103)
  at org.eclipse.emf.ecore.util.EObjectValidator.validate(EObjectValidator.java:324)
  at org.eclipse.emf.ecore.util.Diagnostician.doValidate(Diagnostician.java:257)
  at org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostician.java:244)


The exception disappears when I remove the derived property. I am truly puzzled. It might be caused by the derived property failing to compute on the instances (I will check), but why would this matter, if it is not even called? Any suggestions how to deal with it?
Re: Problems with OCL validation and derived properties [message #1827283 is a reply to message #1827281] Tue, 12 May 2020 09:13 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

Getting into trouble in EMF's InternalSettingDelegate usually means that the test that diverted the control flow to OCL has failed and some unsatisfactory EMF fallback has taken over.

The failing line is:

Object setting = settings.dynamicGet(index);


so settings must have been computed as null in StateImpl.eIsSet

Glancing at the ecore, initial appears to have a lower bound of 1, so it is guaranteed to be non-null. However the EMF default is null, so the OCL won't null-check it, which might explain the NPE.

If you need further help please identify a JUnit test or main() to run and create the stack trace.

Regards

Ed Willink

[Updated on: Tue, 12 May 2020 09:15]

Report message to a moderator

Re: Problems with OCL validation and derived properties [message #1827286 is a reply to message #1827283] Tue, 12 May 2020 09:22 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

Please identify a JUnit test or main() to run and create the stack trace since I think you should have got better diagnostics than a crash.

EMF assumes that all 'helper' code is exception proof, which the auto-generated Java for EMF is. Checking for exceptions everywhere would degrade EMF performance undesirably.

Unfortunately the OCL 'helper' functionality can be rather more complicated and so exceptions happen. Therefore every entry point from EMF to OCL must be Exception checked to ensure that the user gets an extra helpful validation error rather than an unhelpful stack trace. It looks like you've found an unguarded way in.

Regards

Ed Willink
Re: Problems with OCL validation and derived properties [message #1827288 is a reply to message #1827286] Tue, 12 May 2020 09:49 Go to previous messageGo to next message
Andrzej Wąsowski is currently offline Andrzej WąsowskiFriend
Messages: 21
Registered: November 2019
Junior Member
Apologies for messing up. I have slightly misrepresented the error message above. With the meta-model as in the quote, so without a lower bound the error is as reported:

  java.lang.NullPointerException:
  at org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSettingDelegateSingleData.dynamicIsSet(EStructuralFeatureImpl.java:2293)
  at mdsebook.fsm.impl.StateImpl.eIsSet(StateImpl.java:302)
  at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eIsSet(BasicEObjectImpl.java:1280)
  at org.eclipse.emf.ecore.util.EObjectValidator.validate_DataValueConforms(EObjectValidator.java:832)
  at org.eclipse.emf.ecore.util.EObjectValidator.validate_EveryDataValueConforms(EObjectValidator.java:820)
  at mdsebook.fsm.util.FsmValidator.validateState(FsmValidator.java:343)
  at mdsebook.fsm.util.FsmValidator.validate(FsmValidator.java:103)
  at org.eclipse.emf.ecore.util.EObjectValidator.validate(EObjectValidator.java:324)
  at org.eclipse.emf.ecore.util.Diagnostician.doValidate(Diagnostician.java:257)
  at org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostician.java:244)
  ...


The error message for the meta-model as in the linked repo (so with a lower bound constraint added) the error message is then slightly different:

  java.lang.NullPointerException:
  at org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSettingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.java:2199)
  at mdsebook.fsm.impl.StateImpl.isIsInitial(StateImpl.java:151)
  at mdsebook.fsm.impl.StateImpl.eGet(StateImpl.java:234)
  at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1050)
  at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1042)
  at org.eclipse.emf.ecore.util.EObjectValidator.validate_MultiplicityConforms(EObjectValidator.java:721)
  at org.eclipse.emf.ecore.util.EObjectValidator.validate_EveryMultiplicityConforms(EObjectValidator.java:579)
  at mdsebook.fsm.util.FsmValidator.validateState(FsmValidator.java:342)
  at mdsebook.fsm.util.FsmValidator.validate(FsmValidator.java:103)
  at org.eclipse.emf.ecore.util.EObjectValidator.validate(EObjectValidator.java:324)
  ...


The difference seems to be that in the second case the "isIsInitial" is actually invoked (Yes - I know a stupid property name). Not sure if it helps to diagnose things. In the meantime, I am digging into your feedabck, to see whether I can learn more.

Re: Problems with OCL validation and derived properties [message #1827291 is a reply to message #1827288] Tue, 12 May 2020 10:32 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

Changing the lower bound causing the exception to move between EveryDataValueConforms and EveryMultiplicityConforms confirms that we're close, but without anything to run on my machine. Your code's line numbers do not match mine. I cannot help further. I need the generated Java and (failing) JUnit test.

I note that

OCL: initial: machine.initial = self;

generates

Java: final /*@NonInvalid*/ boolean eq = initial.equals(this);

giving an NPE opportunity that would not occur if the arguments were reversed to self = machine.initial.

Ah! Currently there is an if-necessary try-catch around all OCL-based validate methods. The access to an OCL-based getter method by eIsSet in an EMF-based validate method was one I overlooked.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=563092 raised

You should find that the problem goes away once you avoid the null navigation.

Using non-zero lower bounds for EReferences is very dangerous, since EMF provides no way to guarantee a non-null default making it easy for OCL to tun on an ill-formed model.

Regards

Ed Willink
Re: Problems with OCL validation and derived properties [message #1827307 is a reply to message #1827291] Tue, 12 May 2020 18:15 Go to previous messageGo to next message
Andrzej Wąsowski is currently offline Andrzej WąsowskiFriend
Messages: 21
Registered: November 2019
Junior Member
Sorry, these are good hints. I am just constantly distracted by gazillion other tasks, so you are helping faster than I can use your help. Give me a few days to fix it, and if not, I will create a minimal example for you. All the code is on the repo, but you do not want to weave through all that ...
Re: Problems with OCL validation and derived properties [message #1827327 is a reply to message #1827307] Wed, 13 May 2020 07:27 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

If you subscribe to https://bugs.eclipse.org/bugs/show_bug.cgi?id=563092 or read https://www.eclipse.org/forums/index.php?t=msg&th=1103748&goto=1827325&#msg_1827325 you will see that your problem is now well-understood. I do not need a repro.

For your particular model, it was the incorrect lowerbound on State::machine and FiniteStateMachine::initial that give two alternative crashes. It is bad Diagnostician::validate() functionality that makes EMF unable to diagnose it.

Regards

Ed Willink
Re: Problems with OCL validation and derived properties [message #1827373 is a reply to message #1827327] Wed, 13 May 2020 19:31 Go to previous messageGo to next message
Andrzej Wąsowski is currently offline Andrzej WąsowskiFriend
Messages: 21
Registered: November 2019
Junior Member
I just did two things:

* switch the OCL from machine.initial = self to self = machine.initial. This seems to have no impact on the result. Strange?
* I then tried to make a minimal test case for you, but when I got (almost) there, I realized that the test started to pass. So I changed something that has an effect. And it seems to be related to the fixture code loading some other model files. Perhaps I do not understand what validation does; apparently some other models loaded, influence the validation of my model in questions (these other instances may indeed violate the lowerbound constraint). I am puzzled why. This will require more attention - while preparing a case for you, I might solve the problem :P. I shall retry tomorrow.

[Updated on: Wed, 13 May 2020 19:35]

Report message to a moderator

Re: Problems with OCL validation and derived properties [message #1827400 is a reply to message #1827373] Thu, 14 May 2020 07:14 Go to previous messageGo to next message
Andrzej Wąsowski is currently offline Andrzej WąsowskiFriend
Messages: 21
Registered: November 2019
Junior Member
I have managed to clean it up to some extent, narrowing down the issue a bit. Look here: https://bitbucket.org/dsldesign/dsldesign/src/ed/ (a temporary branch called ed).

You should be able to run it by doing ./gradlew test from the main repository (or gradle.bat accordingly). The test should fail as above. The single test is in ./mdsebook.scala/src/test/scala/mdsebook/scala/EMFScalaSpec.scala . I quote it here:

    
    mdsebook.fsm.FsmPackage.eINSTANCE.eClass
    Resource.Factory.Registry.INSTANCE
      .getExtensionToFactoryMap
      .put("xmi", new XMIResourceFactoryImpl )

    val file = "../mdsebook.fsm/test-files/CoffeeMachine.xmi"
  	val r = (new ResourceSetImpl) getResource (URI createURI file, true)
    val M = r.getContents().get(0).asInstanceOf[mdsebook.fsm.Model]

    Diagnostician.INSTANCE.validate (M)


The test case file is in "./mdsebook.fsm/test-files/CoffeeMachine.xmi". I can translate it to Java, but not before late tonight, as life is calling me to do some actual work. Sigh.
Re: Problems with OCL validation and derived properties [message #1827403 is a reply to message #1827373] Thu, 14 May 2020 07:26 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

Quote:
For your particular model, it was the incorrect lowerbound on State::machine and FiniteStateMachine::initial


Correction, defining State::machine as [1] multiplicity is 99% ok and probably a good idea, since State::machine is the opposite of the only permissible containment relationship. In any reasonable system (99%) a State is always contained by a FiniteStateMachine. However it is just possible (1%) that an orphan State might arise during some transformation and possibly be persisted at the root of a model. This orphan could provoke a validation crash and even a save failure if eIsSet crashes during save.

Quote:
switch the OCL from machine.initial = self to self = machine.initial. This seems to have no impact on the result. Strange?


You haven't identified the model that you validate or the mechanism by which Diagnostician.validate was invoked or what you consider to be the result so it is very hard to comment on your perspective on the problems.

I can only comment on my reconstruction of your problems for which the exchange of argument order switches to Java code that dos not actually crash.

Obviously without further info I cannot comment on other files beyond observing that validate causes all proxies to be resolved and so all referenced models to be loaded.

Regards

Ed Willink
Re: Problems with OCL validation and derived properties [message #1827404 is a reply to message #1827403] Thu, 14 May 2020 07:31 Go to previous messageGo to next message
Andrzej Wąsowski is currently offline Andrzej WąsowskiFriend
Messages: 21
Registered: November 2019
Junior Member
Thanks. The coffe machine instance model is now in the testing branch that I have sent to you in a post that I wrote, while you were writing yours.
Re: Problems with OCL validation and derived properties [message #1827426 is a reply to message #1827404] Thu, 14 May 2020 10:15 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
See https://www.eclipse.org/forums/index.php/mv/msg/1103748/1827425/#msg_1827425 for an example of how EMF could be diagnosing your bad model.
Re: Problems with OCL validation and derived properties [message #1827430 is a reply to message #1827426] Thu, 14 May 2020 11:14 Go to previous messageGo to next message
Andrzej Wąsowski is currently offline Andrzej WąsowskiFriend
Messages: 21
Registered: November 2019
Junior Member
This looks very cool indeed!
Re: Problems with OCL validation and derived properties [message #1827518 is a reply to message #1827430] Sat, 16 May 2020 18:42 Go to previous message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
hi

Quote:
However it is just possible (1%) that an orphan State might arise during some transformation and possibly be persisted at the root of a model.


Interesting example. I'm inclined to recommend a 0 lowerbound when that is remotely possible and an "InitialStateRequired" constraint to impose the semantics.

Regards

Ed Willink

[Updated on: Mon, 18 May 2020 07:16]

Report message to a moderator

Previous Topic:OCL jars from Maven
Next Topic:Reuse OCL - access Ecore metamodel entities in runtime
Goto Forum:
  


Current Time: Sun May 05 15:15:16 GMT 2024

Powered by FUDForum. Page generated in 0.04328 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top