[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:47:02 EDT 2014


     [ https://issues.jboss.org/browse/DROOLS-613?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

qibiao deng updated DROOLS-613:
-------------------------------
    Description: 
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 two 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. This works failed
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 with SDO object.

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}

SDO RuleCondition class
{code::title=RuleConditionSdo.java |borderStyle=solid}
package mock.com.camel.drools.expert.sample.service.domain;

import commonj.sdo.DataObject;
import commonj.sdo.helper.DataFactory;

/**
 * 
 * @author dengqb
 * @date 2014年9月19日
 */
public class RuleConditionSdo {
    private DataObject ruleCondition;
    
    public RuleConditionSdo(){
        ruleCondition = DataFactory.INSTANCE.create("http://drools.research.com/xsd/RuleCondition", "RuleCondition");
    }

    public DataObject getRuleCondition() {
        return ruleCondition;
    }

    public void setRuleCondition(DataObject ruleCondition) {
        this.ruleCondition = ruleCondition;
    }
}

{code}

  was:
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 two 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. This works failed
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 with SDO object.

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}




> 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.0.1.Final, 6.1.0.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
>              Labels: DRL, Drools, SDO
>
> 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 two 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. This works failed
> 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 with SDO object.
> 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}
> SDO RuleCondition class
> {code::title=RuleConditionSdo.java |borderStyle=solid}
> package mock.com.camel.drools.expert.sample.service.domain;
> import commonj.sdo.DataObject;
> import commonj.sdo.helper.DataFactory;
> /**
>  * 
>  * @author dengqb
>  * @date 2014年9月19日
>  */
> public class RuleConditionSdo {
>     private DataObject ruleCondition;
>     
>     public RuleConditionSdo(){
>         ruleCondition = DataFactory.INSTANCE.create("http://drools.research.com/xsd/RuleCondition", "RuleCondition");
>     }
>     public DataObject getRuleCondition() {
>         return ruleCondition;
>     }
>     public void setRuleCondition(DataObject ruleCondition) {
>         this.ruleCondition = ruleCondition;
>     }
> }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.1#6329)



More information about the jboss-jira mailing list