Search code examples
javadroolsrule-engine

Why does the Drools Rules Engine only run a rule with an empty conditional once?


I have a very basic drools rules engine set up with only rule inserted:

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

I am running the application in a Java Thread run loop. Every iteration of the loop I fire all the rules (using a stateful Kie Session). The first iteration of the loop results in the "Hello World!" statement successfully printing. However, after that the rule does not fire again.

Here is the run function:

@Override
public void run() {   
   // Fire the rules
   System.out.println("Firing rules");
   kSession.fireAllRules();           
}

And here is how I initialize my Kie Session:

KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieBase kBase1 = kContainer.getKieBase("KBase1");         
kSession = kBase1.newKieSession();

Why is this? I am guessing it has something to do with the inferring done by the application, but I don't conceptually understand the engine enough to know.

I am using Maven and have the following dependencies:

  • drools-engine (Version 9.44.0-Final)
  • drools-xml-support (Version 9.44.0-Final)
  • drools-mvel (Version 9.44.0-Final)

I am also using the following plugin:

  • kie-maven-plugin (Version 9.44.0-Final)

Thanks in advance!


Solution

  • Works as designed. Rule is activated by InitalFactImpl.

    The InitalFactImpl fact is a special fact that is always present (but not always used) in PHREAK network. Every time a new KIE Session is created, an InitalFactImpl is automatically inserted into it. This will allow patterns such as the NOT conditional element to be evaluated...

    Let's consider a situation where we want a rule to be executed when we don't have any SuspiciousOperation in our session regardless of the Customer. This rule would be written as follows:

    rule "Sample Rule 1"
    when
        not (SuspiciousOperation())
    then
        channels["audit-channel"].send("OK");
    end
    

    For this example InitalFactImpl is used as we don't have any fact that could trigger the rule.

    Source: Mastering JBoss Drools 6 (Mauricio Salatino, Mariano De Maio, Esteban Aliverti)