有没有办法在 drools 中调用 void 函数?

Is there a way to invoke a void function in drools?

有没有办法调用 void 函数作为 when 条件的一部分? 我正在尝试拥有自己的功能,其中包含一些必须作为每个规则的一部分调用的业务逻辑。

例如:自定义日志函数,这个函数是静态的。

rule "some rule"
    when
        $instance : Customer(type == "Regular");
        eval(Utils.log());
    then
        ......
end

当我执行上面的函数时,函数被调用但执行失败

java.lang.RuntimeException: Utils.log() : java.lang.NullPointerException

    at org.drools.core.rule.EvalCondition.isAllowed(EvalCondition.java:129)
    at org.drools.core.phreak.PhreakEvalNode.doLeftInserts(PhreakEvalNode.java:72)
    at org.drools.core.phreak.PhreakEvalNode.doNode(PhreakEvalNode.java:56)
    at org.drools.core.phreak.RuleNetworkEvaluator.evalNode(RuleNetworkEvaluator.java:389)

有人可以帮助阐明我如何在何时调用函数吗?

您可以从右侧调用 void 函数。你不能从左边,因为它没有任何意义。左侧应该是条件——空白不是条件。

rule "some rule"
when
  Customer(type == "Regular")
then
  Utils.log()
end

读作:“当有类型为 'Regular' 的客户时,则调用 log() 函数。”

从逻辑上讲,您不能从“何时”开始。这甚至意味着什么? “当有类型为 'Regular' 的客户并且......无效时?”


如果您坚持这样做,请将您的日志记录函数的 return 类型更改为 return true,以便它始终具有匹配条件。 不要依赖此记录调用的结果来尝试跟踪执行时间或规则执行——它只会告诉您 Drools 引擎在确定规则时评估该行的时间火柴。如果后续条件导致匹配项被丢弃,则日志记录将已经触发。条件子句中的方法应该是纯粹的并且没有副作用。

public static boolean log() {
  // logic
  return true;
}

rule "an awful rule don't do this"
when
  Customer(type == "Regular")
  Boolean (this == true) from Utils.log()
then
  // logic
end

rule "another awful rule, still don't do this"
when
  Customer( type == "Regular" )
  eval( Utils.log() )
then
  // logic
end

我绝对推荐曾经这样做。


如果您只是想记录规则匹配或匹配,您应该使用 listener 来实现您的日志记录逻辑,而不是污染您的规则。