I'm trying to write a simple rule. To perform a set of calculations. I understand that the calculations can be handled via functions. But, The business logic involves calculations.
package com.sample.rules
import com.sample.rules.Test
rule "Calculate"
when
Test(calculate == true)
then
finalValue = Test(InitialValue) + 10;
Test.setFinalValue(finalValue)
System.out.println("FinalValue=" + Test.getFinalValue();
end
The Class file with variable
public class Test {
private int finalValue;
private int initialValue;
private boolean calculate;
public int getFinalValue() {
return FinalValue;
}
public void setFinalValue(int FinalValue) {
this.FinalValue = FinalValue;
}
public int getInitialValue() {
return InitialValue;
}
public void setInitialValue(int InitialValue) {
this.InitialValue = InitialValue;
}
public boolean isCalculate() {
return calculate;
}
public void setCalculate(boolean calculate) {
this.calculate = calculate;
}
}
The App file is as shown below
public class CalculationApp {
public static void main(String[] args) {
System.out.println( "Bootstrapping the Rule Engine ..." );
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules");
Test test = new Test();
test.setInitialValue(20);
test.setCalculate(true);
kSession.insert(test);
int fired = kSession.fireAllRules();
System.out.println( "Number of Rules executed = " + fired );
}
}
The rule file throws an error :
Rule Compilation error finalValue cannot be resolved to a variable
Cannot make a static reference to the non-static method getInitialValue() from the type Test
finalValue cannot be resolved to a variable
Cannot make a static reference to the non-static method getFinalValue() from the type Test
While I found the answer by Trial and Error: I'm trying to understand the logic behind it. I mean, Assigning a variable
(I understand variable has a different meaning) /assignment
in the when
condition is understandable, but the same the how does the Then
part work. I mean, the item.setFinalValue(...)
part.
Your rule has several problems, as indicated by the error.
Rule Compilation error finalValue cannot be resolved to a variable
finalValue cannot be resolved to a variable
The first problem is that you never declare finalValue
, just attempt to assign to it on the right hand side. To fix this, simply declare finalValue. Assuming it's an integer:
int finalValue = ...
This is identical to how it works in Java.
However given what the original rule looks like, I think you're trying to pull the initial value from the Test object. To do that, you would do something like this:
rule "Calculate"
when
Test( calculate == true,
$initialValue: initialValue ) // assign the $initialValue variable
then
int finalValue = $initialValue + 10; // set finalValue by adding 10 to $initialValue
Cannot make a static reference to the non-static method getInitialValue() from the type Test
Cannot make a static reference to the non-static method getFinalValue() from the type Test
Both of these errors indicate that you're trying to call instance methods without an object instance. This is once again the same as in Java, where if you have an instance method you must call it against an instance.
Assuming these are methods on the Test
class, you would change your rule to be:
package com.sample.rules
import com.sample.rules.Test
rule "Calculate"
when
$test : Test( calculate == true,
$initialValue: initialValue )
then
int finalValue = $initialValue + 10;
$test.setFinalValue(finalValue); // call against $test instance
System.out.println("FinalValue=" + $test.getFinalValue()); // you were also missing a parenthesis
end