【问题标题】:Drools rule error "Unexpected global"Drools 规则错误“意外的全局”
【发布时间】:2014-03-11 07:10:02
【问题描述】:

我在 Drools 中实现了业务规则,在执行时我得到了 java RuntimeException

Unexpected global [myService]
org.drools.common.AbstractWorkingMemory.setGlobal(AbstractWorkingMemory.java:588)

可能是什么原因?

规则:

rule "Tax Rule"
  when
    calculateTax : calculateTax(
        objOne : objOne,
        objTwo : objTwo,
        objThree : objThree
    );

    objFour : objFour();
    System.out.println("debug");

  then
    ...
end

【问题讨论】:

  • 你能分享你的规则吗?以及启动规则引擎的部分代码。
  • 谢谢安迪,我刚刚发现了问题,发布了答案。

标签: jboss7.x drools business-rules


【解决方案1】:

在许多情况下,此错误意味着您的 DRL 编译时出现错误,因此 Drools 会告诉您“意外全局”,因为它在空 DRL 中找不到任何全局声明。

DRL 编译器不会抛出任何错误异常,您应该使用以下方法自行检查:

kieBuilder.getErrors()

【讨论】:

    【解决方案2】:

    就是这样,对于 5.x; 6.x 有点不同:

    KnowledgeBuilderConfiguration kbConfig =
        KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration();
    //    kbConfig.setOption( sizeAccFunOption );
    
    KnowledgeBuilder kBuilder =
        KnowledgeBuilderFactory.newKnowledgeBuilder( kbConfig );
    
    Resource drl = ResourceFactory.newFileResource( drlPath );
    
    kBuilder.add( drl, ResourceType.DRL );
    
    if( kBuilder.hasErrors() ){
        System.err.println( "### compilation errors ###" );
        KnowledgeBuilderErrors errors = kBuilder.getErrors();
        for( KnowledgeBuilderError err: errors ){
        System.err.println( err.toString() );
        }
        throw new IllegalStateException( "compile errors" );
    }
    

    【讨论】:

    • 使用 KnowledgeBuilder,我偶尔也会发现这个问题。如果存在规则编译问题,我添加了条件(如@laune 指定)以导致严重失败。我并没有立即明白全局设置失败的原因是知识库中的编译问题。
    【解决方案3】:

    我发现了问题。我的 System.out.println() 很少,其中一个位于下图所示的位置。删除它解决了问题。

    rule "Tax Rule"
      when
        calculateTax : calculateTax(
            objOne : objOne,
            objTwo : objTwo,
            objThree : objThree
        );
    
        objFour : objFour();
        System.out.println("debug");
    
      then
        ...
    end
    

    【讨论】:

    • 您一定忽略了 DRL 编译的基本警告:检查错误。显然:没有编译的 DRL,因此:没有全局:因此:设置失败。
    • @laune 能否请您进一步说明如何捕获此类规则编译问题,因为我无法确切看到它失败的地方,对我来说它看起来像一个黑匣子。
    【解决方案4】:

    要在 DRL 中声明和设置全局变量,您需要声明并初始化它:

    // DRL file
    global Service myService
    
    // Java application
    StatefulKnowledgeSession session = ...
    session.setGlobal("myService", new Service() );
    

    未能在 DRL 文件中声明全局,或者全局名称与 setGlobal 调用中的第一个参数不匹配,会导致发布的错误消息。

    【讨论】:

    • 我检查了,我已经正确声明了它并且没有不匹配的地方。
    • 如果您要共享您的代码(创建全局的 API 代码和引用它的规则)而不是仅仅告诉我们您的代码是正确的,这可能会有所帮助?如果你说的都是正确的,我怀疑你不会有这个问题。 ;)
    • @Steve,如果你仔细阅读你会发现我从来没有说过我的代码是正确的,我说的是Laune所指的代码块是正确的。还要记住,由于机密性方面的原因,始终无法共享代码。
    猜你喜欢
    • 2017-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 2012-10-13
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    相关资源
    最近更新 更多