Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » OCL » Class CastException in OCLinEcore generated code
Class CastException in OCLinEcore generated code [message #1833521] Thu, 15 October 2020 14:57 Go to next message
Stefan John is currently offline Stefan JohnFriend
Messages: 17
Registered: March 2018
Junior Member
Hi,

I encountered a ClassCastException running Java code generated by OCLinEcore for a derived attribute. The respective OCLExpression works fine in the Interactive OCL console, though.

Here is an excerpt of the ecore model as well as the stacktrace:

class Plan
{
  property stakeholders : Stakeholder[*|1] { ordered composes };
  property backlog : Backlog[1] { composes };
  property sprints : Sprint[*|1] { ordered composes };
  attribute minTeamVelocity : ecore::EInt[1];
  attribute maxTeamVelocity : ecore::EInt[1];
  attribute derivedMinSprintCount : ecore::EInt[1] { derived volatile }
  {
    initial: 
      let 
        totalEffort : ecore::EInt = self.backlog.workitems->collect(Effort)->sum(),
        dividedByMaxVelo : ecore::EInt = totalEffort.div(maxTeamVelocity)
      in 
       if totalEffort.mod(maxTeamVelocity) > 0	
       then dividedByMaxVelo + 1
       else dividedByMaxVelo
       endif;
  }
}


Exception in thread "main" java.lang.ClassCastException: class org.eclipse.ocl.pivot.internal.values.RealValueImpl cannot be cast to class org.eclipse.ocl.pivot.values.IntegerValue (org.eclipse.ocl.pivot.internal.values.RealValueImpl and org.eclipse.ocl.pivot.values.IntegerValue are in unnamed module of loader 'app')
	at SprintPlanning.impl.PlanImpl.getDerivedMinSprintCount(PlanImpl.java:352)
	at SprintPlanning.impl.PlanImpl.eGet(PlanImpl.java:420)
	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.impl.BasicEObjectImpl.eGet(BasicEObjectImpl.java:1037)
	at org.eclipse.emf.henshin.interpreter.matching.constraints.AttributeConstraint.check(AttributeConstraint.java:97)
	at org.eclipse.emf.henshin.interpreter.matching.constraints.DomainSlot.checkAttributeConstraint(DomainSlot.java:450)
	at org.eclipse.emf.henshin.interpreter.matching.constraints.DomainSlot.instantiate(DomainSlot.java:197)
	at org.eclipse.emf.henshin.interpreter.matching.conditions.ApplicationCondition.findMatch(ApplicationCondition.java:113)
	at org.eclipse.emf.henshin.interpreter.matching.conditions.ApplicationCondition.findGraph(ApplicationCondition.java:74)
	at org.eclipse.emf.henshin.interpreter.matching.constraints.SolutionFinder.findSolution(SolutionFinder.java:74)
	at org.eclipse.emf.henshin.interpreter.matching.constraints.SolutionFinder.getNextSolution(SolutionFinder.java:91)
	at org.eclipse.emf.henshin.interpreter.impl.EngineImpl$MatchFinder.computeNextMatch(EngineImpl.java:402)
	at org.eclipse.emf.henshin.interpreter.impl.EngineImpl$MatchFinder.hasNext(EngineImpl.java:361)
	at org.eclipse.emf.henshin.interpreter.impl.EngineImpl$MatchFinder.next(EngineImpl.java:374)
	at org.eclipse.emf.henshin.interpreter.impl.EngineImpl$MatchFinder.next(EngineImpl.java:1)
	at org.eclipse.emf.henshin.interpreter.impl.RuleApplicationImpl.execute(RuleApplicationImpl.java:105)
	at org.eclipse.emf.henshin.interpreter.impl.UnitApplicationImpl.executeRule(UnitApplicationImpl.java:190)
	at org.eclipse.emf.henshin.interpreter.impl.UnitApplicationImpl.doExecute(UnitApplicationImpl.java:114)
	at org.eclipse.emf.henshin.interpreter.impl.UnitApplicationImpl.execute(UnitApplicationImpl.java:98)
	at utils.ExecuteHenshinRule.main(ExecuteHenshinRule.java:64)


If a bug report makes sense, I will provide a MWE. However, I might also be doing something terribly wrong, therefore, I prefer asking on the forums, first.

Regards,
Stefan
Re: Class CastException in OCLinEcore generated code [message #1833525 is a reply to message #1833521] Thu, 15 October 2020 16:59 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7665
Registered: July 2009
Senior Member
Hi

A CCE is obviously a bug. Looking at the code around PlanImpl.java:353 will probably show where a type conversion has been omitted by the code generator and where you could insert a let variable and a round() to work around the problem.

OMG OCL works with Integer and Real and has no knowledge of EInt. The Pivot OCL converts known Ecore types to their 'behavioral' equivalents. If you use Integer the problem might go away.; still a bug though.

Please raise a Bugzilla. I don't need a full repro, provided you paste PlanImpl.getDerivedMinSprintCount from PlanImpl.java and attach your *.ecore.

Regards

Ed Willink
Re: Class CastException in OCLinEcore generated code [message #1833542 is a reply to message #1833525] Fri, 16 October 2020 09:59 Go to previous messageGo to next message
Stefan John is currently offline Stefan JohnFriend
Messages: 17
Registered: March 2018
Junior Member
Thank you for the advice Ed. Both of your proposals worked for me:


  1. Changing the type of the collected "Effort" attribute to Integer really got rid of the exception. I am surprised this change doesn't seem to break anything depite EMF treating the value as BigInteger everywhere. I anticipated errors when loading old instances of the metamodel or when applying Henshin transformations. But the change seems to be gracefully accepted everywhere.

  2. To be on the safe side, however, I changed the summation to
    self.backlog.workitems->collect(Effort.oclAsType(Real))->sum()
    in order to force the generator to allow sum() to return a RealValue without trying to cast it to IntegerValue. The implementation of CollectionSumOperation seems to not recognize EInt as being conform oclstdlib::Integer and, therefore, sums up RealValues internally. So, I could not use round() or let but a type cast works.


I filed an issue on BugZilla. Actually, I included an MWE as I realized an exception also occurs when using delegates in the generated code. That should make it easier for a bug fixer to play around and switch between generator modes. Plus: BugZilla used by Eclipse is really not that supportive. At least markup support for bug reports would be nice. I feel like taken back to the nineties whenever I need to touch Eclipse's web infrastructure.

Best regards,
Stefan

Re: Class CastException in OCLinEcore generated code [message #1833544 is a reply to message #1833542] Fri, 16 October 2020 10:27 Go to previous message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7665
Registered: July 2009
Senior Member
Hi

Thanks,. The 'new' Pivot-based OCL uses IntegerValue / RealValue classes for all arithmetics within the OCL evaluator. IntegerValue is-a RealValue and may be polymorphically an {Int,Long,Big}IntegerValueImpl to support unbounded behaviour, within the limits of BigInteger, without imposing BigInteger overheads on the 99.9% small-integer use case. Conversion from/to storage types such as EInt normally occurs on read/write from/to the actual memory location with its EMF declared type. EInt is discouraged for intermediate variables, but not prohibited. I expect that the fix will be to add a getBehavioralType() call somewhere, and to search for similar bugs elsewhere.

Regards

Ed Willink

Previous Topic:Looking for OCL Rules for BPMN
Next Topic:Def expressions in OCLInEcore and the Interactive console.
Goto Forum:
  


Current Time: Tue Jul 23 04:05:45 GMT 2024

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

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

Back to the top