java drools

java - Excepción de captura en el LHS de Drools



(1)

Según mi entendimiento, antes de realizar el método de FireAllRules (), se deben seguir los pasos a continuación:

  1. Añadir reglas al paquete / generador de conocimiento
  2. Validar que no haya errores en las Reglas.
  3. Inyectar reglas en la memoria de trabajo.

Por supuesto, es posible disparar las Reglas sin el Paso 2, pero esta práctica puede resultar en problemas como se menciona en esta pregunta. Si yo fuera tú, seguiría la lógica a continuación para solucionar este problema:

Paso 1:

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

Paso 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; }

Paso 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)); }

Usando el método anterior, no ejecutará una regla que tenga errores, y la situación descrita anteriormente no surgirá. Sin embargo, sigo creyendo que debería centrarse más en el código que genera Reglas erróneas, y en el método descrito anteriormente solo para rastrear y persistir tales incidencias.

Tengo un problema donde la cláusula when de una regla de drools lanza una excepción MethodNotFoundException . Estoy buscando una manera de averiguar qué regla es durante el tiempo de ejecución para poder eliminarlo de la lista de reglas para usar.

Ejemplo de regla

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

Por lo tanto, el método getBadMethod en FooBar no existe. Me gustaría una forma de decir qué regla es, y eliminarlo de la lista de reglas para usar.

Soluciones probadas y fallidas:

He intentado extender DefaultAgendaEventListener y reemplazar el método beforeActivationFired para agregar la regla que se está activando a una lista. Esperaba que el último en la lista fuera el que cometiera el error, pero lamentablemente no funcionó de esa manera.

Ahora he intentado agregar reglas "siempre verdaderas" antes de todas mis reglas. Registran el nombre de la regla que viene después. El problema es que cuando hay una excepción en la cláusula "WHEN", no se registra nada. Es como si no se activaran reglas cuando se produce una excepción como la anterior.

El problema reside en el código de generación de drools dinámico. Me gustaría adoptar un enfoque doble para corregir el código de generación y detectar excepciones como la que se enumera en esta publicación.

Nota al margen: Verifico errores en el constructor. No recibo ningún error del código de abajo.

KnowledgeBuilderErrors errors = builder.getErrors(); if (!errors.isEmpty()) { for (KnowledgeBuilderError error : errors) { ... } }