First, I would like to know how field bindings behave when used together
with or, like in the following drl:
HelloWorld.drl:
---------------
package HelloWorld
import java.lang.String;
import org.drools.integrationtests.helloworld.A;
rule "rule"
when
A(x : a, b=="b") || A(a=="a", x : b)
then
assert(x);
System.out.println("assert=" + x);
end
Of course it could be put in separate rules, but its allowed, and it
yields ArrayIndexOutOfBoundsException. (Drools 3, Rev. 3505 (or 3502))
If A(x : a, b=="b") is evaluated and b fails, is x then "unbound" and
free to be used in A(a=="a", x : b) again?
+ I assume "or" uses shortcut-evaluation, so if A(x : a, b=="b") holds,
then A(a=="a", x : b) is not evaluated at all and x is therefore not
bound to b (assuming A(a=="a", x : b) would hold too) but remains bound
to a.
what if the second or operand has another binding? like A(a=="a", x : b,
y : c) (assuming A has member c). y would be not bound if the second
operand is never evaluated. Does drools check at when loading rules only
when unbound variable is encountered during rule execution?
A.java:
-------
package org.drools.integrationtests.helloworld;
public class A{
String a;
String b;
public A(String a, String b) {this.a = a;this.b = b;}
public String getA() {return a;}
public void setA(String a) {this.a = a;}
public String getB() {return b;}
public void setB(String b) {this.b = b;}
}
HelloWorldTest.java:
---------------------
...
public void testSomething() {
try {
//load up the rulebase
RuleBase ruleBase = readRule();
WorkingMemory workingMemory = ruleBase.newWorkingMemory();
workingMemory.assertObject(new A("x", "y"));
workingMemory.fireAllRules();
workingMemory.assertObject(new A("a", "Y"));
workingMemory.fireAllRules();
workingMemory.assertObject(new A("X", "b"));
workingMemory.fireAllRules();
//assertTrue( message.isFired() );
} catch (Throwable t) {
t.printStackTrace();
fail(t.getMessage());
}
}
...
This dsl causes:
org.drools.spi.ConsequenceException:
java.lang.ArrayIndexOutOfBoundsException: 1
at org.drools.common.Agenda.fireActivation(Agenda.java:323)
at org.drools.common.Agenda.fireNextItem(Agenda.java:299)
at
org.drools.reteoo.WorkingMemoryImpl.fireAllRules(WorkingMemoryImpl.java:248)
at
org.drools.reteoo.WorkingMemoryImpl.fireAllRules(WorkingMemoryImpl.java:261)
at
org.drools.integrationtests.helloworld.HelloWorldTest.testSomething(HelloWorldTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:436)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:311)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
at org.drools.reteoo.FactHandleList.get(FactHandleList.java:107)
at org.drools.reteoo.TupleKey.get(TupleKey.java:90)
at org.drools.reteoo.ReteTuple.get(ReteTuple.java:153)
at org.drools.reteoo.ReteTuple.get(ReteTuple.java:160)
at
HelloWorld.Rule_0ConsequenceInvoker.evaluate(Rule_0ConsequenceInvoker.java:12)
at org.drools.common.Agenda.fireActivation(Agenda.java:321)
... 19 more
fyi, Juergen