【问题标题】:Drools 6 loading and executing rule from StringDrools 6 从字符串加载和执行规则
【发布时间】:2015-12-22 15:09:40
【问题描述】:

我正在尝试从 Drools 6 中的字符串加载规则,如下所示:

// the rule
def drl = '''
dialect "mvel"

rule "Person is over 18"
    when
        $person : Person(age > 18)
    then
        System.out.println("Person is "+$person.name);
end
'''
// setup for rule
KieServices kieServices = KieServices.Factory.get()
KieFileSystem kfs = kieServices.newKieFileSystem()
kfs.write( "src/main/resources/simple.drl",
    kieServices.getResources().newReaderResource( new StringReader(drl) ) )
KieBuilder kieBuilder = kieServices.newKieBuilder( kfs ).buildAll()

// check there have been no errors for rule setup
Results results = kieBuilder.getResults();
if( results.hasMessages( Message.Level.ERROR ) ){
    println( results.getMessages() )
    throw new IllegalStateException( "### errors ###" )
}
KieContainer kieContainer =
    kieServices.newKieContainer( kieBuilder.getKieModule().getReleaseId() )
KieSession kieSession = kieContainer.newKieSession()

// insert facts and fire rules
kieSession.insert(new Person("Jon Doe", 21))
kieSession.insert(new Person("Jon Darcy", 1))
kieSession.fireAllRules()

kieSession.dispose()

@Immutable
class Person {
    String name
    int age
}

我想要发生的事情是将人名打印出来。通过附加 eventlistener 和 logger,我可以看到添加和断言了事实。通过在 drl 中出现错误,我可以确保看到并编译了规则。但规则永远不会触发。

我很确定代码中的某个地方存在一个愚蠢的小错误。有人可以帮帮我吗?

【问题讨论】:

    标签: drools


    【解决方案1】:

    从 KieContainer 获取 KieBase 并从中创建 KieSession 对我有用:

    KieContainer kieContainer =
       kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId() );
    KieBase kieBase = kieContainer.getKieBase();
    KieSession kieSession = kieBase.newKieSession();
    

    但您的代码也可以工作 - 至少在使用 Java 完成所有操作并确保 Person 和 DRL 文件位于同一个包中之后。

    String drl = "package drlstring;\n" +
        "dialect 'mvel'\n" +
        "rule Person_is_over_18\n" +
        "when\n" +
        "$person : Person(age > 18)\n" +
        "then\n" +
        "System.out.println(\"Person is \"+$person.getName());\n" +
        "end";
    // setup for rule
    KieServices kieServices = KieServices.Factory.get();
    KieFileSystem kfs = kieServices.newKieFileSystem();
    kfs.write( "src/main/resources/simple.drl",
           kieServices.getResources().newReaderResource( new StringReader(drl) ) );
    KieBuilder kieBuilder = kieServices.newKieBuilder( kfs ).buildAll();
    
    // check there have been no errors for rule setup
    Results results = kieBuilder.getResults();
    if( results.hasMessages( Message.Level.ERROR ) ){
        System.out.println( results.getMessages() );
        throw new IllegalStateException( "### errors ###" );
    }
    KieContainer kieContainer =
        kieServices.newKieContainer( kieBuilder.getKieModule().getReleaseId() );
    KieSession kieSession = kieContainer.newKieSession();
    
    // insert facts and fire rules
    kieSession.insert(new Person("Jon Doe", 21));
    kieSession.insert(new Person("Jon Darcy", 1));
    kieSession.fireAllRules();
    kieSession.dispose();
    

    如果您想继续您的 Scala 设置,请通过添加一个带有空条件的规则来缩小触发失败的可能原因:

    rule hello
    when then 
      System.out.println( "Hello!" );
    end
    

    认为 Drools 引擎无法识别类 Person 的 Scala 定义。

    【讨论】:

    • 您的意思是我的代码适用于您的更改?因为这里好像不是这样的
    • 规则没有触发似乎还有其他原因。请参阅我的扩展答案。
    • 看来问题不在于编写控制代码的语言(顺便说一句,是 Groovy 而不是 Scala)。我能够使用您的空条件规则来确认它是否正常工作。问题似乎是 Drools 引擎无法识别 Person 。你知道为什么吗?毕竟它是一个几乎正常的java类。而且它在 Drools 5.5 中工作。有我不知道的限制吗?是否有文档可以解释我为什么?
    • 正如您从我的回答中看到的那样,我对这些新语言没有经验。 @Immutable 可能会将扳手投入工作。 - Drools 团队 AFAIK 尚未保证将 Drools 与除 Java 之外的其他任何东西一起使用。
    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 2015-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 2013-05-07
    • 1970-01-01
    相关资源
    最近更新 更多