Uploaded image for project: 'Drools'
  1. Drools
  2. DROOLS-275

RuleEngine AfterEvaluator.evaluateCachedRight throws NPE on persisted Session reload (Phreak, Stream, PseudoClock)

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Major
    • 6.0.0.CR5
    • 6.0.0.CR3
    • None
    • None

    Description

      I persist a KieSession via the Marshaller (serializable) with one fact/event inserted. On reload of the session, I can see that fact is still there (when I check the FactHandles) and the PseudoClock is at the correct time (the time when I persisted it). If I then insert another fact/event into this reloaded session which matches the following rule:

      rule "SimpleFactTimeWindow"
      when
      $s1: SimpleFact() from entry-point LinkyStream
      $s2: SimpleFact(this != $s1, this after [0s, 10s] $s1) from entry-point LinkyStream
      then
      System.out.println("Rule fired, found 2 Facts within the time window.");
      end

      I get a NPE (in both Phreak and ReteOO mode). Exception in Phreak:
      java.lang.reflect.InvocationTargetException
      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.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
      at java.lang.Thread.run(Thread.java:724)
      Caused by: java.lang.NullPointerException
      at org.drools.core.base.evaluators.AfterEvaluatorDefinition$AfterEvaluator.evaluateCachedRight(AfterEvaluatorDefinition.java:304)
      at org.drools.core.rule.constraint.EvaluatorConstraint.isAllowedCachedRight(EvaluatorConstraint.java:80)
      at org.drools.core.common.DoubleBetaConstraints.isAllowedCachedRight(DoubleBetaConstraints.java:117)
      at org.drools.core.phreak.PhreakJoinNode.doRightInserts(PhreakJoinNode.java:150)
      at org.drools.core.phreak.PhreakJoinNode.doNode(PhreakJoinNode.java:56)
      at org.drools.core.phreak.RuleNetworkEvaluator.switchOnDoBetaNode(RuleNetworkEvaluator.java:547)
      at org.drools.core.phreak.RuleNetworkEvaluator.evalBetaNode(RuleNetworkEvaluator.java:533)
      at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:335)
      at org.drools.core.phreak.RuleNetworkEvaluator.outerEval(RuleNetworkEvaluator.java:162)
      at org.drools.core.phreak.RuleNetworkEvaluator.evaluateNetwork(RuleNetworkEvaluator.java:117)
      at org.drools.core.phreak.RuleExecutor.reEvaluateNetwork(RuleExecutor.java:194)
      at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:65)
      at org.drools.core.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:936)
      at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1183)
      at org.drools.core.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:936)
      at org.drools.core.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:910)
      at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:233)
      at org.jboss.ddoyle.brms.cep.ha.management.TestScenarioRunner.secondRun(TestScenarioRunner.java:142)
      at org.jboss.ddoyle.brms.cep.ha.management.MainSecondRun.main(MainSecondRun.java:7)
      ... 6 more

      Exception in ReteOO:
      java.lang.reflect.InvocationTargetException
      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.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
      at java.lang.Thread.run(Thread.java:724)
      Caused by: org.drools.core.RuntimeDroolsException: Unexpected exception executing action org.drools.core.reteoo.PropagationQueuingNode$PropagateAction@2e3aeda
      at org.drools.core.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:1225)
      at org.drools.core.common.NamedEntryPoint.insert(NamedEntryPoint.java:371)
      at org.drools.core.common.NamedEntryPoint.insert(NamedEntryPoint.java:278)
      at org.drools.core.common.NamedEntryPoint.insert(NamedEntryPoint.java:131)
      at org.drools.core.common.NamedEntryPoint.insert(NamedEntryPoint.java:56)
      at org.jboss.ddoyle.brms.cep.ha.management.TestScenarioRunner.secondRun(TestScenarioRunner.java:140)
      at org.jboss.ddoyle.brms.cep.ha.management.MainSecondRun.main(MainSecondRun.java:7)
      ... 6 more
      Caused by: java.lang.NullPointerException
      at org.drools.core.base.evaluators.AfterEvaluatorDefinition$AfterEvaluator.evaluateCachedLeft(AfterEvaluatorDefinition.java:324)
      at org.drools.core.rule.constraint.EvaluatorConstraint.isAllowedCachedLeft(EvaluatorConstraint.java:67)
      at org.drools.core.common.DoubleBetaConstraints.isAllowedCachedLeft(DoubleBetaConstraints.java:108)
      at org.drools.reteoo.nodes.ReteJoinNode.propagateFromLeft(ReteJoinNode.java:147)
      at org.drools.reteoo.nodes.ReteJoinNode.assertLeftTuple(ReteJoinNode.java:99)
      at org.drools.core.reteoo.SingleLeftTupleSinkAdapter.doPropagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:213)
      at org.drools.core.reteoo.SingleLeftTupleSinkAdapter.propagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:73)
      at org.drools.reteoo.nodes.ReteJoinNode.propagateFromRight(ReteJoinNode.java:135)
      at org.drools.reteoo.nodes.ReteJoinNode.assertRightTuple(ReteJoinNode.java:125)
      at org.drools.reteoo.nodes.ReteBetaNodeUtils.assertObject(ReteBetaNodeUtils.java:47)
      at org.drools.reteoo.nodes.ReteJoinNode.assertObject(ReteJoinNode.java:39)
      at org.drools.core.reteoo.CompositeObjectSinkAdapter.doPropagateAssertObject(CompositeObjectSinkAdapter.java:502)
      at org.drools.core.reteoo.CompositeObjectSinkAdapter.propagateAssertObject(CompositeObjectSinkAdapter.java:387)
      at org.drools.core.reteoo.PropagationQueuingNode$AssertAction.execute(PropagationQueuingNode.java:430)
      at org.drools.core.reteoo.PropagationQueuingNode.propagateActions(PropagationQueuingNode.java:266)
      at org.drools.core.reteoo.PropagationQueuingNode$PropagateAction.execute(PropagationQueuingNode.java:592)
      at org.drools.core.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:1223)
      ... 12 more

      What I discovered is that this only happens when I save the KieSession to a file in one JVM and reload it in another. When I load the KieSession in the same JVM as the one in which I persisted it, there is no exception and the rule get's fired (as expected).

      I created a reproducer project for it: https://github.com/DuncanDoyle/DroolsSessionPersistenceNPE/

      I've added some Maven profiles so you can easily observe the behaviour:

      • mvn -PallRuns exec:java : this runs both the persistence and the reload in the same JVM, no exception, everything works fine.
      • mvn -PfirstRun exec:java : this runs the first part of the test, and saves the KieSession to a file.
      • mvn -PsecondRun exec:java : this runs the second part of the test, which loads the previously saved KieSession from the file and inserts a new fact, resulting in the NPE.

      All three tests can also be run in ReteOO mode by adding "-Ddrools.ruleEngine=reteoo" at the end of the command.

      Attachments

        Activity

          People

            mfusco@redhat.com Mario Fusco
            rhn-gps-ddoyle Duncan Doyle (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: