I am trying to execute a very basic example demonstrating the use of the accumulate()
function of Drools, but am getting a java.lang.NullPointerException
exception.
Here is the code:
Metric.java:
package com.sample;
public class Metric
{
public String id;
public double value;
public Metric(String id, double value)
{
this.id = id;
this.value = value;
}
}
ruleFile1.drl:
package com.sample
declare Metric
@role( event )
end
rule "rule1"
when
Metric()
metricAverage: Number() from accumulate(
Metric( $value : value ),
average( $value ) )
then
System.out.println("metric value average " + metricAverage);
end
KSessionGenerator.java:
package com.sample;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import org.kie.api.KieBase;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Message;
import org.kie.api.builder.Results;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
public class KSessionGenerator {
public KieSession buildKSession(String ruleFilePath){
KieServices kieServices = KieServices.Factory.get();
FileInputStream fis = null;
try {
fis = new FileInputStream(ruleFilePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
String virtualRuleFilePath = "src/main/resources/ruleFile1.drl";
KieFileSystem kfs = kieServices.newKieFileSystem();
kfs.write(virtualRuleFilePath, kieServices.getResources().newInputStreamResource(fis));
KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
Results results = kieBuilder.getResults();
if (results.hasMessages(Message.Level.ERROR)) {
System.out.println(results.getMessages());
throw new IllegalStateException("### errors ###");
}
KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
// Change the engine mode to 'stream'
KieBaseConfiguration config = kieServices.newKieBaseConfiguration();
config.setOption( EventProcessingOption.STREAM );
KieBase kieBase = kieContainer.newKieBase( config );
KieSession kSession = kieBase.newKieSession();
return kSession;
}
}
DroolsTest1.java:
package com.sample;
import org.kie.api.runtime.KieSession;
public class DroolsTest1 {
public static final void main(String[] args) {
try {
String ruleFilePath = "src/main/resources/rules/ruleFile1.drl";
KieSession kSession = (new KSessionGenerator()).buildKSession(ruleFilePath);
// go !
Metric metric1 = new Metric("m1", 50);
Metric metric2 = new Metric("m2", 60);
kSession.insert(metric1);
kSession.insert(metric2);
System.out.println("Firing all rules ...");
kSession.fireAllRules();
System.out.println("Rules fired!");
System.out.println("Bye");
} catch (Throwable t) {
t.printStackTrace();
}
}
}
kmodule.xml:
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
<kbase name="rules" packages="rules">
<ksession name="ksession-rules"/>
</kbase>
</kmodule>
The full stack trace of the exception:
Firing all rules ...
java.lang.RuntimeException: java.lang.NullPointerException
at org.drools.core.rule.SingleAccumulate.accumulate(SingleAccumulate.java:90)
at org.drools.core.phreak.PhreakAccumulateNode.addMatch(PhreakAccumulateNode.java:759)
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:235)
at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:106)
at org.drools.core.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:1016)
at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1302)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1289)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1262)
at com.sample.DroolsTest1.main(DroolsTest1.java:20)
Caused by: java.lang.NullPointerException
at org.drools.core.rule.Declaration.getValue(Declaration.java:228)
at com.sample.Rule_rule11017979978AccumulateExpression0Invoker.evaluate(Rule_rule11017979978AccumulateExpression0Invoker.java:19)
at org.drools.core.base.accumulators.JavaAccumulatorFunctionExecutor.accumulate(JavaAccumulatorFunctionExecutor.java:109)
at org.drools.core.rule.SingleAccumulate.accumulate(SingleAccumulate.java:82)
... 15 more
I am using Drools version 6.2.0 Final via plugin on Eclipse Mars 4.5.2
Can anyone tell me the cause of the error along with its solution ?
Tried the code, the NPE is caused by
"$value" -> "Method threw 'java.lang.NullPointerException' exception.
Cannot evaluate org.drools.core.rule.Declaration.toString()"
This is due to the Metric class not having any getter methods for its fields. Add the getters and the code will execute without problems