2015-04-07 6 views
16

У меня проблема, когда предложение when of the drools rule выбрасывает MethodNotFoundException. Я ищу способ выяснить, какое правило это во время выполнения, чтобы удалить его из списка правил для использования.Исключение Захват в LHS Drools

Правило Пример

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 

Итак, getBadMethod на FooBar не существует. Я хотел бы указать, что это такое, и удалить его из списка правил для использования.

Пробовал и Неудачные решения:

я пытался расширить DefaultAgendaEventListener и переопределение метода beforeActivationFired, чтобы добавить правило увольняют в список. Я надеялся, что последним в списке будет ошибка, но, к сожалению, это не получилось.

Я уже пытался добавить правила «всегда истинные» перед всеми моими правилами. Они записывают имя правила, которое появляется после него. Проблема заключается в том, что в предложении WHEN отсутствует исключение, и ничего не регистрируется. Как будто никакие правила не срабатывают, когда возникает Исключение, такое как вышеописанное.

Проблема связана с динамическим кодом генерации слюни. Я хотел бы использовать два подхода к исправлению кода генерации и перехватывать исключения, подобные тем, которые перечислены в этом сообщении.

Замечание: Я проверяю ошибки в строителе. Я не получаю ошибок из приведенного ниже кода.

KnowledgeBuilderErrors errors = builder.getErrors(); 

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

Привет, afaik, mvel не поддерживает захват исключений, поэтому вы можете либо изменить свое правило на использование диалекта _java_, либо использовать инструкцию try и catch при попытке запустить ваше правило. –

+0

@kucing_terbang Я могу использовать диалект java в LHS правила слюни? Кроме того, я поймаю исключение, когда я запускаю правило, проблема в том, что иногда бывает трудно диагностировать проблему из stacktrace. –

+0

ну, я не думаю, что вы можете это сделать. Самое близкое, о чем я могу думать, это то, что вы создаете свою собственную функцию, которая обрабатывает ошибку, которую вы вызываете в LHS. –

ответ

5

Согласно моему пониманию, прежде чем делать fireAllRules() метод ниже шаги должны следовать:

  1. Добавление правил в пакет/Knowledge Builder
  2. Validate, что нет ошибок в правилах
  3. INJECT Правила в рабочей памяти

Конечно, можно fireRules withou Шаг 2, но эта практика может привести к проблемам, упомянутым в этом вопросе. Если бы я тебя, я бы следовать ниже логику, чтобы исправить эту проблему:

Шаг 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)); 
} 

Используя вышеописанный метод, вы не будете выполнять правило с ошибками, и описанная выше ситуация не будет t возникает. Тем не менее, я по-прежнему считаю, что вам следует больше сосредоточиться на части кода, порождающей ошибочные правила, и описанном выше методе только для отслеживания и сохранения таких случаев.

+0

Я проверяю ошибку с помощью этой строки 'KnowledgeBuilderErrors errors = builder.getErrors();' –

+0

Примечание к предыдущему комментарию, ошибки не поступают из этой строки. Drools позволяет скользить. –

+0

Ты единственный человек, который мог бы ответить, хотя это не решило мою проблему. Я награждаю тебя 100 очками. –

Смежные вопросы