2016-03-15 221 views
0
java.lang.RuntimeException: Unexpected global [log] 
at org.drools.core.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:1163) 
  1. 日间行车灯是从数据库字符串列表检索。
  2. 我们不使用kmodule.xml 继评论: 的DRL(最小化的设置,试图找到问题)加载顺利,但不知何故在其定义的全局,是不是。

KieSession创建代码从Drools的6.0.1迁移到Drools的6.3.0,最终得到了意外的全球[日志]错误

KieServices ks = KieServices.Factory.get(); 
     KieRepository kr = ks.getRepository(); 
     KieFileSystem kFileSystem = ks.newKieFileSystem(); 

     int i=0; 
     for (String ruleId : drls.keySet()){ 
      Resource resource = ks.getResources().newByteArrayResource(drls.get(ruleId).getBytes()); 
      resource.setTargetPath("./out/"+ ruleId +".drl"); 
      resource.setResourceType(ResourceType.DRL); 
      kFileSystem.write(resource); 
     } 
     KieBuilder kieBuilder = ks.newKieBuilder(kFileSystem); 
     kieBuilder.buildAll(); 
    KieBuilder kieBuilder = ks.newKieBuilder(kFileSystem); 
    kieBuilder.buildAll(); 
    if (kieBuilder.getResults().hasMessages(Message.Level.ERROR)) { 
     log.error(PolicyUtils.createMsg("DRL Errors:\n" + kieBuilder.getResults().toString()), context, null, null); 
     throw new RuntimeException("DRL Errors:\n" +   kieBuilder.getResults().toString()); 
    } 
    kContainer = ks.newKieContainer(kr.getDefaultReleaseId()); 
    kContainer.newKieSession(); 
+0

你确认你正在创建的KieBase不包含任何错误?为了完整起见,您可以发布以下内容:您的DRL文件的结构,您的kmodule.xml以及您用于构建KieBase的代码。 –

+1

@EstebanAliverti由于会议是从一个空的规则库(无论是什么原因)创建的,人们在圈子中运行,在其他地方追逐错误,浪费了很多时间,我和其他人。为什么没有例外? – laune

回答

1

在Java代码中你有一些调用,比如

kieSession.setGlobal("log", ...); 

里面应该有一个对应你的.drl文件如

global ... log; 

但它没有。 (圆点分别标记为对象引用和相应类型的地方。)

看到你的代码...

kFileSystem.write(resource); 

我强烈建议你使用表单与此相对的路径:

kFileSystem.write("src/main/resources/" + ruleId + ".drl, 
        resource); 

或修改资源目标路径:

resource.setTargetPath("src/main/resources/hello.drl"); 

(您的代码不会工作:

resource.setTargetPath("./out/hello.drl"); 

后来,在编译过程中,这将导致警告 “未找到KieBase defaultKieBase文件”。 Drools手册包含这句话“这些工件必须添加到相应的常用Maven项目的相同位置。”但不会简单地解释这意味着什么,这会更有帮助。)

在您的DRL代码中没有“全局”当然相当于未编译知识库,即您的会话在空的知识库上运行。

+0

这似乎并不是这种情况,因为所有DRL实际上都有全局日志变量行+相同的DRL在Java 7 + Drools 6.0.1中编译和完美工作(我们只是在Maven中更改了Drools的版本,并且使用了编译Java 8,DRL或代码没有变化) – akapulko2020

+1

然后你没有加载你的DRL代码。检查DRL编译器消息。 – laune

+0

kieBuilder.getResults()。hasMessages的输出?或者是其他东西?谢谢 ! – akapulko2020

2

在阅读与@laune在另一个答案中的交谈之后,我猜问题现在已经确定:您的KieBase不包含您认为它的工件(规则,全局变量等)。

不知道你的代码有什么可能是错误的,但我认为一个简单的解决方法可以让你免受你在那里的所有样板代码(和容易出错)的代码。

这里的想法是使用KieHelper类而不是使用KieRepository,KieFileSystemKieBuilder。实际上,创建KieHelper类是为了避免涉及创建KieBase的这些复杂步骤(与Drools 5.x相比)。

使用KieHelper类,可以重构代码以类似于此:

KieHelper kieHelper = new KieHelper(); 
for (String ruleId : drls.keySet()) { 
    kieHelper.addContent(drls.get(ruleId), ResourceType.DRL); 
} 
Results results = kieHelper.verify(); 
for (Message message : results.getMessages()) { 
    log.error(">> Message ({}): {}", message.getLevel(), message.getText()); 
} 

if (results.hasMessages(Message.Level.ERROR)) { 
    throw new IllegalStateException("There are errors in the KB."); 
} 

KieSession ksession = kieHelper.build().newKieSession(); 

希望它能帮助,