Uploaded image for project: 'JBRULES'
  1. JBRULES
  2. JBRULES-3323

Using Set in accumulate causes NPE in some scenarios

This issue belongs to an archived project. You can view it, but you can't modify it. Learn more

XMLWordPrintable

      When using either "collectSet" or the full syntax (init, action, reverse, result) of "accumulate" an NPE is beeing thrown in org.drools.rule.Accumulate.reverse(final Object[] workingMemoryContext, final Object[] context, ...). Actual exception is comming from a generated accumulator within the reverse() method of Accumulate.

      IMPORTANT: When using Rule 2 (full syntax) I was able to replicate that the NPE is thrown during the execution of "reverse" block of "accumulate"!
      IMPORTANT: I checked trivial stuff such as fields/variables/collections used in rules not null and some other sanity checks.

      I am attaching

      • example rules causing NPE;
      • Stack trace;
      • test project as soon as I have set it up;
      • Rule 1 causing NPE
        rule "Sub optimal resource parallelism"
            when
                $project : Project($optimalResourceParallelism : optimalResourceParallelism)
                $assignment : Assignment(project == $project, $leftId : id, resource != null, $leftResource : resource)
                exists Assignment(project == $project, id != $leftId, resource != null && != $leftResource)
                $resourceParallelism : Set ((size + 1) != $optimalResourceParallelism)
                	from accumulate ( $otherAssignment : Assignment(project == $project, id != $leftId, resource != null && != $leftResource, $resource : resource),
                	collectSet($resource) )
            then
            	insertLogical(new IntConstraintOccurrence("sub-optimal resource parallelism", ConstraintType.NEGATIVE_SOFT
            	, Math.abs($optimalResourceParallelism - ($resourceParallelism.size() + 1)), $assignment));
                System.out.println("Sub optimal resource parallelism detected. Assignment: " + $assignment.getId()
                + " optimalParallelism is: " + $optimalResourceParallelism + " and actual: " + ($resourceParallelism.size() + 1));
        end
      • Rule 2 causing NPE
        rule "Sub optimal resource parallelism"
            when
                $project : Project($optimalResourceParallelism : optimalResourceParallelism)
                $assignment : Assignment(project == $project, $leftId : id, resource != null, $leftResource : resource)
                exists Assignment(project == $project, id != $leftId, resource != null && != $leftResource)
                $resourceParallelism : Set ((size + 1) != $optimalResourceParallelism)
                	from accumulate ( $otherAssignment : Assignment(project == $project, id != $leftId, resource != null && != $leftResource, $resource : resource),
                	init( Set<Resource> resources = new HashSet<Resource>(); ),
                	action( resources.add($resource); ),
                	reverse( resources.remove($resource); ),
                	result( resources.size(); ) )
            then
            	insertLogical(new IntConstraintOccurrence("sub-optimal resource parallelism", ConstraintType.NEGATIVE_SOFT
            	, Math.abs($optimalResourceParallelism - ($resourceParallelism.size() + 1)), $assignment));
                System.out.println("Sub optimal resource parallelism detected. Assignment: " + $assignment.getId()
                + " optimalParallelism is: " + $optimalResourceParallelism + " and actual: " + ($resourceParallelism.size() + 1));
        end
      • Stack trace
        org.drools.RuntimeDroolsException: java.lang.NullPointerException
        	at org.drools.rule.Accumulate.reverse(Accumulate.java:217)
        	at org.drools.reteoo.AccumulateNode.removeMatch(AccumulateNode.java:888)
        	at org.drools.reteoo.AccumulateNode.modifyRightTuple(AccumulateNode.java:554)
        	at org.drools.reteoo.BetaNode.modifyObject(BetaNode.java:431)
        	at org.drools.reteoo.CompositeObjectSinkAdapter.doPropagateModifyObject(CompositeObjectSinkAdapter.java:468)
        	at org.drools.reteoo.CompositeObjectSinkAdapter.propagateModifyObject(CompositeObjectSinkAdapter.java:436)
        	at org.drools.reteoo.AlphaNode.modifyObject(AlphaNode.java:149)
        	at org.drools.reteoo.CompositeObjectSinkAdapter.doPropagateModifyObject(CompositeObjectSinkAdapter.java:468)
        	at org.drools.reteoo.CompositeObjectSinkAdapter.propagateModifyObject(CompositeObjectSinkAdapter.java:436)
        	at org.drools.reteoo.ObjectTypeNode.modifyObject(ObjectTypeNode.java:284)
        	at org.drools.reteoo.EntryPointNode.modifyObject(EntryPointNode.java:271)
        	at org.drools.common.NamedEntryPoint.update(NamedEntryPoint.java:465)
        	at org.drools.common.AbstractWorkingMemory.update(AbstractWorkingMemory.java:959)
        	at org.drools.common.AbstractWorkingMemory.update(AbstractWorkingMemory.java:932)
        	at org.drools.planner.core.heuristic.selector.variable.PlanningValueWalker.changeWorkingValue(PlanningValueWalker.java:125)
        	at org.drools.planner.core.heuristic.selector.variable.PlanningValueWalker.walk(PlanningValueWalker.java:112)
        	at org.drools.planner.core.heuristic.selector.variable.PlanningVariableWalker.walk(PlanningVariableWalker.java:130)
        	at org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.decideNextStep(DefaultGreedyDecider.java:62)
        	at org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:62)
        	at org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:166)
        	at org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:138)
        	at de.orbitx.retena.domain.ScheduleTest.schedule(ScheduleTest.java:227)
        	at de.orbitx.retena.domain.ScheduleTest.testGetScoreTrivialScenario(ScheduleTest.java:78)
        	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        	at java.lang.reflect.Method.invoke(Method.java:597)
        	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
        	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
        	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
        	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
        	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
        	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:300)
        	at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
        	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115)
        	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
        	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        	at java.lang.reflect.Method.invoke(Method.java:597)
        	at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
        	at $Proxy0.invoke(Unknown Source)
        	at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
        	at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
        	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
        Caused by: java.lang.NullPointerException
        	at org.drools.base.accumulators.CollectSetAccumulateFunction.reverse(CollectSetAccumulateFunction.java:123)
        	at org.drools.base.accumulators.JavaAccumulatorFunctionExecutor.reverse(JavaAccumulatorFunctionExecutor.java:130)
        	at org.drools.rule.Accumulate.reverse(Accumulate.java:208)
        	... 51 more

              etirelli@redhat.com Edson Tirelli
              reinis_jira Reinis Vicups (Inactive)
              Archiver:
              rhn-support-ceverson Clark Everson

                Created:
                Updated:
                Resolved:
                Archived: