我在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文件, 所有规则都是从数据库加载和组成的,但逻辑是相同的。
答案 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,此列表接受所有电子邮件。 (如果还有其他失败,请在此处发表评论,我会看到它。)
我希望这有助于澄清和改善这个问题。