Java 在Drools的LHS中捕获异常

Java 在Drools的LHS中捕获异常,java,drools,Java,Drools,我有一个问题,drools规则的when子句抛出了一个MethodNotFoundException。我正在寻找一种方法来确定在运行时它是哪个规则,以便能够从要使用的规则列表中删除它 规则示例 Rule "FooBar" when $V1 : Foo ( ) AND $V2 : FooBar( ) from $V1.getGoodMethod() AND $V3 : FooBarBar( status == "FooBar" ) from $V2.getBadMethod(

我有一个问题,drools规则的when子句抛出了一个MethodNotFoundException。我正在寻找一种方法来确定在运行时它是哪个规则,以便能够从要使用的规则列表中删除它

规则示例

Rule "FooBar"
when
 $V1 : Foo (    )  AND
 $V2 : FooBar(    ) from $V1.getGoodMethod()  AND
 $V3 : FooBarBar( status == "FooBar" ) from $V2.getBadMethod()  
reply : FooFooBar()
then
reply.getList().add("FooBar");
end
因此,FooBar上的getBadMethod不存在。我想知道它是什么规则,并将其从要使用的规则列表中删除

尝试和失败的解决方案:

我已尝试扩展DefaultAgendaEventListener并重写BeforeActivationConfiged方法,以将正在激发的规则添加到列表中。我希望列表中的最后一个会是抛出错误的那个,但遗憾的是,结果不是这样

我现在尝试在所有规则之前添加“始终正确”规则。他们记录它后面的规则的名称。问题是当“when”子句中出现异常时,不会记录任何内容。这就好像在发生上述异常时没有触发任何规则一样

问题在于动态drools生成代码。我想采取双管齐下的方法来修复生成代码,并捕获本文中列出的异常

旁注:我会检查生成器中的错误。我没有收到来自以下代码的错误

KnowledgeBuilderErrors errors = builder.getErrors();

if (!errors.isEmpty()) {
    for (KnowledgeBuilderError error : errors) {
        ...
    }
}

根据我的理解,在执行fireAllRules()方法之前,应遵循以下步骤:

  • 向包/知识生成器添加规则
  • 验证规则中是否没有错误
  • 在工作内存中注入规则
  • 当然,在没有第2步的情况下也可以使用fireRules,但这种做法可能会导致本问题中提到的问题。 如果我是你,我会按照以下逻辑解决你的问题:

    步骤1:

    private RuleBase initialiseDrools() throws IOException, DroolsParserException {
        PackageBuilder packageBuilder = readRules();
        return addRulesToWorkingMemory(packageBuilder);
    }
    
    步骤2:

    private PackageBuilder readRules() throws DroolsParserException, IOException {
        PackageBuilder packageBuilder = new PackageBuilder();
        PackageBuilder intermPackageBuilder = null;
    
        listOfReader = dynamicRuleReader(); // Here goes your application code
    
        for(Reader reader : listOfReader){ 
            try{
                intermPackageBuilder = new PackageBuilder();
                intermPackageBuilder.addPackage(reader);
                assertNoRuleErrors(intermPackageBuilder); // This is the core step. 
                // Above line throws an exception, every time a rules fails. You can persist this exception for production debugging
                packageBuilder.addPackage(reader);
            }catch(DroolsParserException | IOException e){
                logger.error("Rules contain error, so skip adding them to the Package Builder");
            }
        }
    
        return packageBuilder;
    }
    
    步骤3:

    public void shouldFireAllRules() throws IOException, DroolsParserException {
        RuleBase ruleBase = initialiseDrools();
        WorkingMemory workingMemory = ruleBase.newStatefulSession();
        int expectedNumberOfRulesFired = 2; // Idealy this number should be equal to the number of total rules injected in the Working memory
    
        int actualNumberOfRulesFired = workingMemory.fireAllRules();
    
        assertThat(actualNumberOfRulesFired, is(expectedNumberOfRulesFired));
    }
    
    使用上述方法,您将不会执行有错误的规则,并且不会出现上述情况。
    但是,我仍然认为您应该更多地关注生成错误规则的代码段,以及上面描述的仅用于跟踪和持久化此类事件的方法。

    Hi,afaik,mvel不支持异常捕获,因此您可以将规则更改为使用java方言,或者在尝试启动规则时使用try-and-catch语句。@kucing\u terbang我可以在drools规则的LHS中使用java方言吗?此外,当我启动规则时,我确实捕捉到了异常,问题是有时很难从stacktrace诊断问题。嗯,我认为你做不到这一点。我能想到的最接近的事情是你创建了自己的函数来处理你将在LHS中调用的错误。我真的不能这样做,drools代码是动态生成的。这意味着我不仅要动态生成drools规则,还要动态生成java方法上一条注释上的注释,该行没有错误。你是唯一能回答的人,虽然这并没有解决我的问题。我给你100分。