Search code examples
javadrools

Drools Rules : Can a static method be called in the when section of a drool file


I am trying to write a drools rule that would check if a student has an average of more than 5 at a discipline and i get this error whenever i try to run a static method in the when clause. Moreover, i couldn't find in the drools documentation if it's possible to call a static method in the when section.

This is the rule :

rule "student with at least two grades and average less than 5" salience 8
    when
    $student : Student(grades.size() >= 2)
         $list : ArrayList() from eval(computeAverageGrade($student))
         $value : Double() from $list
         Boolean(booleanValue() == true) from $value < 5.0
    then
     System.out.println(2);
    student.setValid(false)
end

This is the method's header:

 public static List<Double> computeAverageGrade(Student student)

and this is the error i am getting :

Caused by: org.mvel2.PropertyAccessException: [Error: null pointer or function not found: eval]
[Near : {... eval(computeAverageGrade($stud ....}]
             ^
[Line: 1, Column: 1]

Solution

  • The error explains what's wrong: that's not how you use eval.

    Unlike other languages like Javascript, eval doesn't execute arbitary code and return a value: it executes arbitrary code and evaluates a boolean.

    You should have declared $list like this:

    $list: ArrayList() from computeAverageGrade($student)
    $value : Double(this < 5.0) from $list
    

    An example for how you'd use eval, would be to evaluate some sort of truthiness from arbitrary code ... for example like this:

    eval( $someValue < someExampleFunctionCall() )
    

    Of course you should always avoid the use of eval because Drools is very good at simplifying conditions for efficient processing, and eval forces it to evaluate your code as-written, thus losing all efficiencies/performance improvements the engine could otherwise give you.

    Almost any place you can use eval can be rewritten in a better way -- the example above can, for instance, be rewritten as Double(this > $someValue) from someExampleFunctionCall().