[jboss-jira] [JBoss JIRA] (DROOLS-839) Accumulate Function ClassCastException

Mario Fusco (JIRA) issues at jboss.org
Mon Jul 13 09:57:05 EDT 2015


    [ https://issues.jboss.org/browse/DROOLS-839?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13088880#comment-13088880 ] 

Mario Fusco commented on DROOLS-839:
------------------------------------

Yes, the error is definitively related with the 'or' condition. I reproduced it with the simpler test case I'm pasting below and I'm debugging it just now. 

{code}
    @Test
    public void testAccumulateWithOr() {
        // DROOLS-839
        String drl1 =
                "import " + Converter.class.getCanonicalName() + ";\n" +
                "global java.util.List list;\n" +
                "rule R when\n" +
                "  (or\n" +
                "    Integer (this == 1)\n" +
                "    Integer (this == 2)\n" +
                "  )\n" +
                "String( $length : length )\n" +
                "accumulate ( $c : Converter(), $result : sum( $c.convert($length) ) )\n" +
                "then\n" +
                "end";

        KieSession ksession = new KieHelper().addContent( drl1, ResourceType.DRL )
                                             .build()
                                             .newKieSession();

        List<Integer> list = new ArrayList<Integer>();
        ksession.setGlobal( "list", list );

        ksession.insert( 1 );
        ksession.insert( "hello" );
        ksession.insert( new Converter() );
        ksession.fireAllRules();

        assertEquals( 1, list.size() );
        assertEquals( "hello".length(), (int)list.get(0) );
    }

    public static class Converter {
        public static int convert(int i) {
            return i;
        }
    }
{code}

As a side note (totally unrelated with this bug) I believe that the 'or' condition you wrote is quite ugly and doesn't make much sense. Why are you testing the scope that belongs to the Contract inside the Employee pattern? Wouldn't be clearer (and more correct) to do something like this?

{code}
		Employee ($employeeId : employeeId)
		(or
			Contract (scope == ContractScope.EmployeeContract && contractRefId == $employeeId)
			Contract (scope == ContractScope.TeamContract)
		)
{code}


> Accumulate Function ClassCastException
> --------------------------------------
>
>                 Key: DROOLS-839
>                 URL: https://issues.jboss.org/browse/DROOLS-839
>             Project: Drools
>          Issue Type: Bug
>          Components: core engine
>    Affects Versions: 6.2.0.CR4, 6.3.0.Beta1
>         Environment: Mac OS X 10.10.3
>            Reporter: Eugene Shvartsman
>            Assignee: Mario Fusco
>         Attachments: Drools-839-Reproducer.zip
>
>
> I am getting a ClassCastException with the following LHS side of the rule. The sample I am posting is the simplest version of the rule that I could create while still retaining the error. 
> {code:title=Rule.drl|borderStyle=solid}
> rule "reproducer"
>         dialect "mvel" 
> 	enabled true
> 	when
> 		$contract : Contract( $contractRefId : contractRefId, $scope : scope )
> 		(or 
> 			$employee : Employee ($scope == ContractScope.EmployeeContract && employeeId == $contractRefId) 
> 			$employee : Employee ($scope == ContractScope.TeamContract) 
> 		)
> 		$contractLine : MinMaxContractLine( contractLineType == ContractLineType.HOURS_PER_DAY, $maxMinutesValue : maximumValue, $weight : maximumWeight, 
> 											maximumEnabled == true, $contract == contract)
> 		$info : EmployeeRosterInfo( $type : profileDayType, $firstDayOfWeek : firstDayOfWeek )
> 		$shiftDate : ShiftDate(isInPlanningWindow($info))
> 		accumulate ( $shift : ShiftAssignment( employee != null, employee == $employee
> 								,getDateByProfileDayType($type).equals($shiftDate)
> 								,$minutes : shiftDurationMinutes)
>            			,$minutesInDay  : sum( $shift.getShiftDurationMinutesByProfileType($type, $shiftDate) )
>            			,$shiftsInvolved : collectList($shift)
> 		)
> 	then
> end
> {code}
> During the execution of the rules I get the following stack trace:
> {code:title=StackTrace.java|borderStyle=solid}
> java.lang.RuntimeException: java.lang.ClassCastException: com.reproducer.engine.domain.contract.Contract cannot be cast to com.reproducer.engine.domain.EmployeeRosterInfo
> 	at org.drools.core.rule.MultiAccumulate.accumulate(MultiAccumulate.java:99)
> 	at org.drools.core.phreak.PhreakAccumulateNode.addMatch(PhreakAccumulateNode.java:751)
> 	at org.drools.core.phreak.PhreakAccumulateNode.doLeftInserts(PhreakAccumulateNode.java:163)
> 	at org.drools.core.phreak.PhreakAccumulateNode.doNode(PhreakAccumulateNode.java:80)
> 	at org.drools.core.phreak.RuleNetworkEvaluator.switchOnDoBetaNode(RuleNetworkEvaluator.java:562)
> 	at org.drools.core.phreak.RuleNetworkEvaluator.evalBetaNode(RuleNetworkEvaluator.java:533)
> 	at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:334)
> 	at org.drools.core.phreak.RuleNetworkEvaluator.outerEval(RuleNetworkEvaluator.java:161)
> 	at org.drools.core.phreak.RuleNetworkEvaluator.evaluateNetwork(RuleNetworkEvaluator.java:116)
> 	at org.drools.core.phreak.RuleExecutor.reEvaluateNetwork(RuleExecutor.java:231)
> 	at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:106)
> 	at org.drools.core.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:1008)
> 	at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1294)
> 	at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1289)
> 	at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1262)
> 	at com.engine.drools.hardconstraints.MaxHoursPerDayTester.testMaxHoursTwoShiftsViolatedSplitByMidnightType(MaxHoursPerDayTester.java:67)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 	at java.lang.reflect.Method.invoke(Method.java:606)
> 	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
> 	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
> 	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
> 	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
> 	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
> 	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
> 	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
> 	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69)
> 	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
> 	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
> 	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
> 	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
> 	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
> 	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
> 	at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
> 	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
> 	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> 	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
> 	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
> 	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
> 	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
> Caused by: java.lang.ClassCastException: com.reproducer.engine.domain.contract.Contract cannot be cast to com.reproducer.engine.domain.EmployeeRosterInfo
> 	at org.drools.base.com.reproducer.engine.domain.EmployeeRosterInfo1136687844$getProfileDayType.getValue(Unknown Source)
> 	at org.drools.core.base.ClassFieldReader.getValue(ClassFieldReader.java:91)
> 	at org.drools.core.rule.Declaration.getValue(Declaration.java:228)
> 	at org.drools.core.base.mvel.MVELCompilationUnit.updateFactory(MVELCompilationUnit.java:359)
> 	at org.drools.core.base.mvel.MVELCompilationUnit.getFactory(MVELCompilationUnit.java:291)
> 	at org.drools.core.base.accumulators.MVELAccumulatorFunctionExecutor.accumulate(MVELAccumulatorFunctionExecutor.java:116)
> 	at org.drools.core.rule.MultiAccumulate.accumulate(MultiAccumulate.java:90)
> 	... 40 more
> {code}
> If I remove the 'or' clause from the rule by commenting out the lines as below, the error goes away.
> {code:title=Error.java|borderStyle=solid}
> 		$contract : Contract( $contractRefId : contractRefId, $scope : scope )
> 		// (or
> 			$employee : Employee ($scope == ContractScope.EmployeeContract && employeeId == $contractRefId) 
> 			// $employee : Employee ($scope == ContractScope.TeamContract) 
> 		// )
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)


More information about the jboss-jira mailing list