We have a cluster of jboss instances running drools. We generate the KnowledgeBase on one instance, then store it in a database; the other instances can then load it from the database instead of generating it themselves.
This has worked well for some time using drools 4, but we recently upgraded to drools 5.3.0 BRMS and the pattern no longer works. The KnowledgeBase works fine within the app instance in which it was generated, but it fails everywhere else with the following exception. Note that this exception happens upon inserting a fact into working memory.
All instances of the app are identical, they run in the same jvm, etc. The 'other' instance does not need to be on a different physical machine -- it can be on the same hardware, and the failure still occurs.
What is it about a KnowledgeBase that makes it fail in a different jvm instance from the one in which it was generated? Is there some way to avoid this problem? Thanks.
This is the drl in which the failure seems to happen. I've done some debugging through the mvel code, but I'm not familiar with it and I haven't figured out what's going on. I think the expression on which the failure occurs is the 'this.fact.requirementId'.
rule "Find OutOfOrder PredicateSolutions for new LeafPredicateSolution in rule [Become Application Expired : 147]"
ruleflow-group "RuleGroup[Become Application Expired:147]"
agenda-group "leaf"
no-loop
salience -1001
when
EngineDates($rewindToDate: engineEffectiveDate);
lps:LeafPredicateSolution(
ruleId==147,
parent==null,
$candidateId:candidateId,
defunct==false,
fact:fact,
effectiveDate == $rewindToDate,
$programId:programId,
eval(!fact.getReused())); // only solutions created for the fact we're running on can trigger OoO
oops : ArrayList() from accumulate(
PredicateSolution(
$sol:this,
candidateId==$candidateId,
effectiveDate > $rewindToDate,
defunct==false,
programId==$programId,
parent!=null,
solutionType!=SolutionType.RETIRED,
eval(($sol instanceof LeafPredicateSolution) || ($sol instanceof NonCalcProgramSolutionChild))
),
init(ArrayList items = new ArrayList();),
action(items.add($sol);),
reverse(items.remove($sol);),
result(items));
// Find ProgramPredicateSolutions in other programs that refer to this program.
// These need to be rewound.
oopps:ArrayList() from collect(
ProgramPredicateSolution(
this.fact.requirementId == $programId,
candidateId==$candidateId,
effectiveDate > $rewindToDate,
defunct==false,
parent!=null,
solutionType!=SolutionType.RETIRED));
eval((oops.size() > 0) || (oopps.size() > 0));
eval(predicateSolutionFactory.oopEnabled());//Don't run oop if it is disabled (TimeMachine, Whatif)
then
predicateSolutionFactory.addToOutOfOrder(lps, oops, oopps, new Long(65));
end
Stack trace:
java.lang.NullPointerException
at org.mvel2.MVEL.executeExpression(MVEL.java:954)
at org.drools.base.extractors.MVELClassFieldReader.getValue(MVELClassFieldReader.java:100)
at org.drools.base.extractors.BaseObjectClassFieldReader.getHashCode(BaseObjectClassFieldReader.java:196)
at org.drools.core.util.AbstractHashTable$DoubleCompositeIndex.hashCodeOf(AbstractHashTable.java:616)
at org.drools.core.util.RightTupleIndexHashTable.getOrCreate(RightTupleIndexHashTable.java:451)
at org.drools.core.util.RightTupleIndexHashTable.add(RightTupleIndexHashTable.java:332)
at org.drools.reteoo.AccumulateNode.assertObject(AccumulateNode.java:263)
at org.drools.reteoo.CompositeObjectSinkAdapter.doPropagateAssertObject(CompositeObjectSinkAdapter.java:458)
at org.drools.reteoo.CompositeObjectSinkAdapter.propagateAssertObject(CompositeObjectSinkAdapter.java:386)
at org.drools.reteoo.AlphaNode.assertObject(AlphaNode.java:135)
at org.drools.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:59)
at org.drools.reteoo.AlphaNode.assertObject(AlphaNode.java:135)
at org.drools.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:59)
at org.drools.reteoo.AlphaNode.assertObject(AlphaNode.java:135)
at org.drools.reteoo.CompositeObjectSinkAdapter.doPropagateAssertObject(CompositeObjectSinkAdapter.java:458)
at org.drools.reteoo.CompositeObjectSinkAdapter.propagateAssertObject(CompositeObjectSinkAdapter.java:376)
at org.drools.reteoo.ObjectTypeNode.assertObject(ObjectTypeNode.java:214)
at org.drools.reteoo.EntryPointNode.assertObject(EntryPointNode.java:244)
at org.drools.common.NamedEntryPoint.insert(NamedEntryPoint.java:337)
at org.drools.common.NamedEntryPoint.insert(NamedEntryPoint.java:298)
at org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:887)
at org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:846)
at org.drools.impl.StatefulKnowledgeSessionImpl.insert(StatefulKnowledgeSessionImpl.java:267)