[jboss-jira] [JBoss JIRA] (DROOLS-613) JBRULES-3723 NullPointerException in RuleNetworkEvaluator.innerEval(RuleNetworkEvaluator.java:271)

qibiao deng (JIRA) issues at jboss.org
Fri Sep 26 01:36:02 EDT 2014


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)



More information about the jboss-jira mailing list