在drools中removeKnowledgePackage时出现异常

时间:2014-06-21 11:39:07

标签: drools

我在drools论坛上问了这个问题,没有人回答。所以我在这里问。

我们的规则是从数据库创建动态。我们使用Drools 6.0.1。 删除规则时使用API​​ knowledgeBase.removeKnowledgePackage(), 抛出异常。

规则内容如下:

package test 

import java.util.Map 

rule "test" 

    salience 0 
    date-effective "2014-05-19" 
    date-expires "2014-12-30" 
    no-loop true   

   when 

       Map( this['_type'] == 'SaleItemInfo' && ( 
        this['filmTypeKey'] in ("1") 
        && 
        this['sumPrice'] > 4B 
       )) 

       Map( this['_type'] == 'Member' && ( 
            this['dynamicPeriod'] == "CurrentDay" 
              && 
                this['consumeWayCode'] == "01324T" 
                  && 
                this['dynamicConsumeCount'] > 10 
       )) 

       Map( this['_type'] == 'SaleItemInfo' && ( 
        this['filmTypeKey'] in ("1") 
       ))

   then 
       System.out.println("=============="); 

end 

当我删除规则时,抛出异常:

java.lang.IllegalArgumentException: Cannot remove a sink, when the list of sinks is null at org.drools.core.reteoo.ObjectSource.removeObjectSink(ObjectSource.java:203) at org.drools.core.reteoo.ObjectSource.doRemove(ObjectSource.java:242) at org.drools.core.common.BaseNode.remove(BaseNode.java:120) at org.drools.core.reteoo.ReteooBuilder.removeNode(ReteooBuilder.java:240) at org.drools.core.reteoo.ReteooBuilder.removeTerminalNode(ReteooBuilder.java:183) at org.drools.core.reteoo.ReteooBuilder.removeRule(ReteooBuilder.java:157) at org.drools.core.reteoo.ReteooRuleBase.removeRule(ReteooRuleBase.java:1409) at org.drools.core.reteoo.ReteooRuleBase.removeRule(ReteooRuleBase.java:1400) at org.drools.core.reteoo.ReteooRuleBase.removePackage(ReteooRuleBase.java:1318) at org.drools.core.impl.KnowledgeBaseImpl.removeKnowledgePackage(KnowledgeBaseImpl.java:205) at com.oristartech.rule.drools.DroolsTest.removePackage(DroolsTest.java:128) at com.oristartech.rule.drools.DroolsTest.testDrools(DroolsTest.java:67) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597). .....

我发现https://issues.jboss.org/browse/JBRULES-2465说这个问题已经解决了。

当我将drools版本更改为5.6时,没有抛出任何异常。

那么,这是一个问题,还是我在规则文件中犯了错误? 谢谢。

更新:

根据laune的建议,我在这里添加了演示代码:

public class DemoTest {
  public static void main(String[] args) {
    System.setProperty( "drools.dateformat", "yyyy-MM-dd" );

    KnowledgeBuilderConfiguration builderConf = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration();
    KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder(builderConf);
    builder.add(ResourceFactory.newClassPathResource("demo.drl"), ResourceType.DRL);

    if (builder.hasErrors()) {
        throw new RuntimeException(builder.getErrors().toString());
    }
    KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
    Collection<KnowledgePackage> packs = builder.getKnowledgePackages();
    kBase.addKnowledgePackages(packs);
    StatelessKnowledgeSession session = kBase.newStatelessKnowledgeSession();

    List<Object> facts = new ArrayList<Object>();
    Map<String, Object> f1 = new HashMap<String, Object>();
    f1.put("_type", "SaleItemInfo");
    f1.put("sumPrice", 100);
    f1.put("filmTypeKey", "1");
    facts.add(f1);

    Map<String, Object> f2 = new HashMap<String, Object>();
    f2.put("_type", "SaleItemInfo");
    f2.put("sumPrice", 300);
    f2.put("filmTypeKey", "1");
    facts.add(f2);

    Map<String, Object> f3 = new HashMap<String, Object>();
    f3.put("_type", "Member");
    f3.put("dynamicPeriod", "CurrentDay");
    f3.put("consumeWayCode", "01324T");
    f3.put("dynamicConsumeCount", 20);
    facts.add(f3);

    session.execute(facts);
    for(KnowledgePackage pk : packs) {
        kBase.removeKnowledgePackage(pk.getName());
    }
  }

}

为了便于测试,我将规则内容复制到demo.drl。在我们的系统中,我们没有drl文件, 所有规则都是从数据库加载和组成的,但逻辑是相同的。

1 个答案:

答案 0 :(得分:0)

总结一下:

1)规则编写得不好,因为第三个CE将与第一个CE(并且,取决于WM内容)相同的Map对象绑定到具有给定约束的任何其他Map。 =&GT; @michael的AP用于改进规则构建器。

2)演示的代码包含

session.execute(facts);
for(KnowledgePackage pk : packs) {
    kBase.removeKnowledgePackage(pk.getName());
}

从(无状态)会话中删除知识包是没有意义的。无论如何,会话已被执行处理,知识库可以“丢弃”而不会清空它。

3)至于从Drools 6.x中删除回归,我强烈要求@michael再次尝试此列表:rules-users@lists.jboss.org。 AFAIK,此列表接受所有电子邮件。 (如果还有其他失败,请在此处发表评论,我会看到它。)

我希望这有助于澄清和改善这个问题。