<div dir="ltr"><div><div><div>Hi all,<br><br></div>I am using Drools-Fusion v5.4.0.Final. My use case is to add rules dynamically at runtime which should get automatically updated in the KnowledgeSession. Rules in my application are defined as DTO. I have written a toDrl() method which returns a String which essentially is a rule in drl. I use following code to add it to the already running instance of rule engine.<br>
<br></div><div><b>Initialize Rule Engine<br></b>KnowledgeBuilder kBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();<br></div><div>KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();<br>if(kBase != null){    <br>
    kBase.addKnowledgePackages(kBuilder.getKnowledgePackages());<br>}<br><br></div><div>// Populate rules from DB<br>List&lt;AlertDefinitionDto&gt; alertDefs = getDbRules();<br></div><div>for(AlertDefinitionDto alertDef : alertDefs) {<br>
     addRule(alertDef);<br>}<br></div><div>StatefulKnowledgeSession kSession = kBase.newStatefulKnowledgeSession();<br><br></div><b>Add Rule<br></b>        try {<br>            rwl.lock();<br>            // Create new rule from AlertDefinitionDto<br>
            kBuilder.add(org.drools.io.ResourceFactory.newByteArrayResource(alertDef.toDrl().getBytes()),<br>                    org.drools.builder.ResourceType.DRL);<br>            if(kBuilder.hasErrors()) {<br>                kBuilder.undo();<br>
                KnowledgeBuilderErrors errs = kBuilder.getErrors();<br>                System.err.print(AlertGenerationServiceImpl.class, &quot;Error adding rule : &quot;+alertDef.getName());<br>                String errorStr = &quot;&quot;;<br>
                for (KnowledgeBuilderError error : errs) {<br>                    errorStr = errorStr + error.getMessage()+&quot;\\n&quot;;<br>                }<br>                System.err.print(&quot;Error adding new rule: &quot;+errorStr);<br>
            }<br>        } finally {<br>            rwl.unlock();<br>        }<br><b><br></b></div><b>       </b>// No errors. Update KnowledgeBase.<br><div>        try {<br>            Collection&lt;KnowledgePackage&gt; kPkgs = kBuilder.getKnowledgePackages();<br>
            kBase.addKnowledgePackages(kPkgs);<br>        } catch (RuntimeException e) {<br>            if(kBase.getRule(RULE_PACKAGE_NAME, alertDef.getName()) != null) {<br>                kBuilder.undo();<br>            }<br>
            e.printStackStrace();<br>        }<br><b><br></b></div><div><b>Fire Rules<br></b></div><div><b>            </b>LogMessage logMsg = getLog();<b><br></b></div><div>            kSession.insert(logMsg);<br>            kSession.fireAllRules();<br>
<br clear="all"></div><div><div><div><div><br></div><div>This code works fine under all conditions for initialization where rules are fetched from DB and rule engine is initialized. <br><br></div><div>The code fails to add new rule dynamically, when the rule engine is already initialized and fired few number of times with LogMessage as fact. The errors which I am getting are<br>
<p style="margin:0px 0px 1em;padding:0px;color:rgb(0,0,0);font-family:arial,FreeSans,Helvetica,sans-serif;font-size:14px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:20px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240)">
------------------------------------------------------------------<br></p><p style="margin:0px 0px 1em;padding:0px;color:rgb(0,0,0);font-family:arial,FreeSans,Helvetica,sans-serif;font-size:14px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:20px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240)">
1. For the first time when it fails to add new rule.<br></p><p style="margin:0px 0px 1em;padding:0px;color:rgb(0,0,0);font-family:arial,FreeSans,Helvetica,sans-serif;font-size:14px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:20px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240)">
------------------------------------------------------------------<br>java.lang.RuntimeException: Null accessor on node: null<br>at org.drools.rule.constraint.ConditionAnalyzer.analyzeNode(ConditionAnalyzer.java:229)<br>at org.drools.rule.constraint.ConditionAnalyzer.analyzeSingleCondition(ConditionAnalyzer.java:126)<br>
at org.drools.rule.constraint.ConditionAnalyzer.analyzeCondition(ConditionAnalyzer.java:102)<br>at org.drools.rule.constraint.ConditionAnalyzer.analyzeCombinedCondition(ConditionAnalyzer.java:134)<br>at org.drools.rule.constraint.ConditionAnalyzer.analyzeCondition(ConditionAnalyzer.java:94)<br>
at org.drools.rule.constraint.ConditionAnalyzer.analyzeCondition(ConditionAnalyzer.java:73)<br>at org.drools.rule.constraint.MvelConditionEvaluator.getAnalyzedCondition(MvelConditionEvaluator.java:78)<br>at org.drools.rule.constraint.MvelConstraint.getListenedPropertyMask(MvelConstraint.java:273)<br>
at org.drools.reteoo.AlphaNode.calculateDeclaredMask(AlphaNode.java:372)<br>at org.drools.reteoo.ObjectSource.initDeclaredMask(ObjectSource.java:151)<br>at org.drools.reteoo.AlphaNode.&lt;init&gt;(AlphaNode.java:86)<br>at org.drools.reteoo.builder.PatternBuilder.attachAlphaNodes(PatternBuilder.java:323)<br>
at org.drools.reteoo.builder.PatternBuilder.attachPattern(PatternBuilder.java:162)<br>at org.drools.reteoo.builder.PatternBuilder.build(PatternBuilder.java:80)<br>at org.drools.reteoo.builder.GroupElementBuilder$AndBuilder.build(GroupElementBuilder.java:113)<br>
at org.drools.reteoo.builder.GroupElementBuilder.build(GroupElementBuilder.java:71)<br>at org.drools.reteoo.builder.ReteooRuleBuilder.addSubRule(ReteooRuleBuilder.java:155)<br>at org.drools.reteoo.builder.ReteooRuleBuilder.addRule(ReteooRuleBuilder.java:128)<br>
at org.drools.reteoo.ReteooBuilder.addRule(ReteooBuilder.java:116)<br>at org.drools.reteoo.ReteooRuleBase.addRule(ReteooRuleBase.java:445)<br>at org.drools.common.AbstractRuleBase.addRule(AbstractRuleBase.java:956)<br>at org.drools.common.AbstractRuleBase.addPackages(AbstractRuleBase.java:627)<br>
at org.drools.reteoo.ReteooRuleBase.addPackages(ReteooRuleBase.java:472)<br>at org.drools.impl.KnowledgeBaseImpl.addKnowledgePackages(KnowledgeBaseImpl.java:150)<br>------------------------------------------------------------------<br>
</p><p style="margin:0px 0px 1em;padding:0px;color:rgb(0,0,0);font-family:arial,FreeSans,Helvetica,sans-serif;font-size:14px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:20px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240)">
2. Everytime after 1st failure.<br></p><p style="margin:0px 0px 1em;padding:0px;color:rgb(0,0,0);font-family:arial,FreeSans,Helvetica,sans-serif;font-size:14px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:20px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(240,240,240)">
------------------------------------------------------------------<br>java.lang.NullPointerException<br>at org.drools.reteoo.ReteooBuilder.removeRule(ReteooBuilder.java:259)<br>at org.drools.reteoo.ReteooRuleBase.removeRule(ReteooRuleBase.java:459)<br>
at org.drools.common.AbstractRuleBase.removeRule(AbstractRuleBase.java:1107)<br>at org.drools.common.AbstractRuleBase.mergePackage(AbstractRuleBase.java:851)<br>at org.drools.common.AbstractRuleBase.addPackages(AbstractRuleBase.java:610)<br>
at org.drools.reteoo.ReteooRuleBase.addPackages(ReteooRuleBase.java:472)<br>at org.drools.impl.KnowledgeBaseImpl.addKnowledgePackages(KnowledgeBaseImpl.java:150)</p><br class=""></div><div>I have checked numerous times the generated drl (from method toDrl()) is syntactically correct. The LogMessage has some null fields but they are checked appropriately in the rules. <br>
<br></div><div>I am not sure what is going wrong here. May be the stacktrace provided above give some pointers to the problem. <br><br></div><div>Also, please confirm if this is the right way to update rules dynamically. I have taken a look at KnowledgeAgent but that requires a changeset represented in XML which I do not have currently in my implementation.<br>
</div><div><br></div><div>Awaiting response.<br></div></div></div></div></div>