qibiao deng created DROOLS-613:
----------------------------------
Summary: JBRULES-3723 NullPointerException in
RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:271)
Key: DROOLS-613
URL:
https://issues.jboss.org/browse/DROOLS-613
Project: Drools
Issue Type: Bug
Affects Versions: 6.1.0.Final, 6.0.1.Final
Environment: drools-core: 6.1.0.Final
drools-compiler: 6.1.0.Final
JDK: 1.7.0_45
IDE:eclipse kepler
OS: windows 7
Test: Junit4
Reporter: qibiao deng
Assignee: Mark Proctor
when there is one rule in KBase, dynamically add second rule and fire it. drools report
this error:
{code:title=Exception stack |borderStyle=solid}
java.lang.NullPointerException
at org.drools.core.phreak.RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:271)
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:216)
at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:91)
at org.drools.core.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:964)
at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1234)
at
org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1239)
at
org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1222)
at
mock.com.camel.drools.expert.sample.service.DynamicAddRuleBugTest.testReproduceBugWithSDO(DynamicAddRuleBugTest.java:134)
{code}
That tow drl rules are almost same expect package name:
{code:title=drl 1|borderStyle=solid}
package com.camel.drools.expert.sample.testbug1
import mock.com.camel.drools.expert.sample.service.domain.Order;
import mock.com.camel.drools.expert.sample.service.domain.RuleConditionSdo;
rule "order flow"
when
$rcs:RuleConditionSdo($rc:ruleCondition)
$order:Order(price>$rc.getDouble("minPrice"),
source==$rc.getString("source"), dest==$rc.getString("dest"))
then
System.out.println("finished rule for bug test 1" +
$rc.getString("source"));
end
{code}
{code:title=drl 2|borderStyle=solid}
package com.camel.drools.expert.sample.testbug2
import mock.com.camel.drools.expert.sample.service.domain.Order;
import mock.com.camel.drools.expert.sample.service.domain.RuleConditionSdo;
rule "order flow"
when
$rcs:RuleConditionSdo($rc:ruleCondition)
$order:Order(price>$rc.getDouble("minPrice"),
source==$rc.getString("source"), dest==$rc.getString("dest"))
then
System.out.println("finished rule for bug test 2" +
$rc.getString("source"));
end
{code}
1. The RuleConditionSdo object was dynamically created at runtime, it using a SDO
technic.
2. If changed RuleCondtionSdo with a pre-write pojo, It works fine.
3. If use Cglib util net.sf.cglib.beans.BeanGenerator creat RuleConditionSdo object
dynamically. It works still fine.
so, It's like a bug.
Test code below:
{code:title=DynamicAddRuleBugTest.java |borderStyle=solid}
package mock.com.camel.drools.expert.sample.service;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import mock.com.camel.drools.expert.sample.service.domain.Order;
import mock.com.camel.drools.expert.sample.service.domain.RuleCondition;
import mock.com.camel.drools.expert.sample.service.domain.RuleConditionSdo;
import org.drools.compiler.builder.impl.KnowledgeBuilderImpl;
import org.drools.compiler.compiler.DroolsParserException;
import org.drools.core.impl.InternalKnowledgeBase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.AgendaFilter;
import org.kie.api.runtime.rule.Match;
import org.kie.internal.KnowledgeBaseFactory;
import com.camel.drools.expert.sample.utils.CglibDynamicBeanGenerator;
import com.camel.drools.expert.sample.utils.RegisterSDOXsd;
/**
* reproduce dynamic add rule bug
* @author dengqb
* @date 2014年9月19日
*/
public class DynamicAddRuleBugTest {
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
}
/**
* using pre-write RuleCondition Object
* result: fine
*/
@Test
public void testReproduceBug() {
InternalKnowledgeBase kBase = (InternalKnowledgeBase)
KnowledgeBaseFactory.newKnowledgeBase();
String drlFile = "/drools/drl/bug_test1.drl";
loadPackageFromDrl(kBase, drlFile);
Order order = new Order(50,"ebay","china");
RuleCondition ruleCondition = new
RuleCondition(30,"ebay","china");
KieSession kieSession = kBase.newStatefulKnowledgeSession();
kieSession.insert(ruleCondition);
kieSession.insert(order);
kieSession.fireAllRules(new AgendaFilter(){
@Override
public boolean accept(Match match) {
return match.getRule().getPackageName().endsWith("testbug1");
}
});
//statfull session使用后必需调用dispose
kieSession.dispose();
System.out.println("========add new rule=================");
String drlFile2 = "/drools/drl/bug_test2.drl";
loadPackageFromDrl(kBase, drlFile2);
kieSession = kBase.newStatefulKnowledgeSession();
Order order2 = new Order(32.0,"ebay","brazil");
RuleCondition ruleCondition2 = new
RuleCondition(30,"ebay","brazil");
kieSession.insert(ruleCondition2);
kieSession.insert(order2);
kieSession.fireAllRules(new AgendaFilter(){
@Override
public boolean accept(Match match) {
return match.getRule().getPackageName().endsWith("testbug2");
}
});
kieSession.dispose();
}
/**
* using a RuleConditonSdo object, it is dynamically created by SDO technic
* result: false
*/
@Test
public void testReproduceBugWithSDO() {
InternalKnowledgeBase kBase = (InternalKnowledgeBase)
KnowledgeBaseFactory.newKnowledgeBase();
String drlFile = "/drools/drl/bug_sdo_test1.drl";
loadPackageFromDrl(kBase, drlFile);
Order order = new Order(50,"ebay","china");
//注册sdo对象
RegisterSDOXsd register = new RegisterSDOXsd();
register.setXsdFilePath("/drools/xsd/xsdList.txt");
register.register();
RuleConditionSdo rcsdo = new RuleConditionSdo();
rcsdo.getRuleCondition().setDouble("minPrice",30);
rcsdo.getRuleCondition().setString("source","ebay");
rcsdo.getRuleCondition().setString("dest","china");
KieSession kieSession = kBase.newStatefulKnowledgeSession();
kieSession.insert(rcsdo);
kieSession.insert(order);
kieSession.fireAllRules(new AgendaFilter(){
@Override
public boolean accept(Match match) {
return match.getRule().getPackageName().endsWith("testbug1");
}
});
//statfull session使用后必需调用dispose
kieSession.dispose();
System.out.println("========add new rule=================");
String drlFile2 = "/drools/drl/bug_sdo_test2.drl";
loadPackageFromDrl(kBase, drlFile2);
kieSession = kBase.newStatefulKnowledgeSession();
Order order2 = new Order(32.0,"ebay","brazil");
//RuleCondition ruleCondition2 = new
RuleCondition(30,"ebay","brazil");
RuleConditionSdo rcsdo2 = new RuleConditionSdo();
rcsdo.getRuleCondition().setDouble("minPrice",30);
rcsdo.getRuleCondition().setString("source","ebay");
rcsdo.getRuleCondition().setString("dest","breazil");
kieSession.insert(rcsdo2);
kieSession.insert(order2);
kieSession.fireAllRules(new AgendaFilter(){
@Override
public boolean accept(Match match) {
return match.getRule().getPackageName().endsWith("testbug2");
}
});
kieSession.dispose();
}
/**
* using a dynamicl RuleCondition object, it created by cglib BeanGenerator
* result: fine
* @throws ClassNotFoundException
*/
@Test
public void testReproduceBugWithDynamicBean() throws ClassNotFoundException{
InternalKnowledgeBase kBase = (InternalKnowledgeBase)
KnowledgeBaseFactory.newKnowledgeBase();
String drlFile = "/drools/drl/bug_dyb_test1.drl";
loadPackageFromDrl(kBase, drlFile);
Order order = new Order(50,"ebay","china");
Map<String,Class<?>> properties = new
HashMap<String,Class<?>>();
properties.put("minPrice", Class.forName("java.lang.Double"));
properties.put("source", Class.forName("java.lang.String"));
properties.put("dest", Class.forName("java.lang.String"));
// 生成动态 Bean
CglibDynamicBeanGenerator ruleCondition = new
CglibDynamicBeanGenerator(properties);
ruleCondition.setValue("minPrice", 40d);
ruleCondition.setValue("source", "ebay");
ruleCondition.setValue("dest", "china");
KieSession kieSession = kBase.newStatefulKnowledgeSession();
kieSession.insert(ruleCondition);
kieSession.insert(order);
kieSession.fireAllRules(new AgendaFilter(){
@Override
public boolean accept(Match match) {
return match.getRule().getPackageName().endsWith("testbug1");
}
});
//statfull session使用后必需调用dispose
kieSession.dispose();
System.out.println("========add new rule=================");
String drlFile2 = "/drools/drl/bug_dyb_test2.drl";
loadPackageFromDrl(kBase, drlFile2);
kieSession = kBase.newStatefulKnowledgeSession();
Order order2 = new Order(32.0,"ebay","brazil");
ruleCondition = new CglibDynamicBeanGenerator(properties);
ruleCondition.setValue("minPrice", 30d);
ruleCondition.setValue("source", "ebay");
ruleCondition.setValue("dest", "brazil");
kieSession.insert(ruleCondition);
kieSession.insert(order2);
kieSession.fireAllRules(new AgendaFilter(){
@Override
public boolean accept(Match match) {
return match.getRule().getPackageName().endsWith("testbug2");
}
});
kieSession.dispose();
}
private void loadPackageFromDrl(InternalKnowledgeBase kBase, String drlFile) {
final Reader drlReader = new
InputStreamReader(this.getClass().getResourceAsStream(drlFile));
final KnowledgeBuilderImpl builder = new KnowledgeBuilderImpl();
try {
builder.addPackageFromDrl(drlReader);
if (builder.hasErrors()){
System.out.println(builder.getErrors());
}
kBase.addPackage(builder.getPackage());
} catch (DroolsParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
{code}
--
This message was sent by Atlassian JIRA
(v6.3.1#6329)