0
votes

Using drools 6.4-FINAL

We have two rules;

rule "Rule1"
when
    // conditions
    $aclass: AClass(type == AType.DOG);
    $bclass: BClass(type == BType.SHIP);
    $cclass: CClass();
    $xclass: XClass();
then
    //actions       
    System.out.println("Actioning Rule1");
end

rule "Rule2"
when
    // conditions
    $aclass: AClass(type == AType.DOG);
    $bclass: BClass(type == BType.SHIP);
    $cclass: CClass();
    $yclass: YClass();
then
    //actions
    System.out.println("Actioning Rule2");
end

Notice that the first 3 conditions of both rules are the same (matching over the classtype and an inner type in some cases of classes AClass, BClass and CClass. The rules differ on with XClass or YClass is present in the facts.

We are finding the following behaviour;

  • If classes A,B,C and Y are provided Rule2 fires.
  • If classes A,B,C and X are provided no rules fire, even though Rule1 should have.
  • Deleteing Rule2 allows Rule1 to fire when A,B,C and X are provided.
  • Swapping the rules around in their order in the file reverses the above behaviour (X = Rule1 fires, Y = no fire even though Rule2 should do).
  • Again in this reverse order, deleteing the second rule allows the first to fire.

Can anyone explain what is going on here. While I suspect the ordering is a red herring, it does look like the first rule to attempt to match somehow consumes the facts, or there is some conflict in assigning facts to variables.

UPDATE

After further investigation I oversimplified the code above. Rather than enum comparison in BClass there is actually a getter such that;

    public Class<?> getConfigClass() {
        return BConfig.class;
    }

And the rules BClass line actually reads;

$bclass: BClass(configClass == BConfig.class);

We have refined the issue down to the BClass line. The class comparison somehow consumes or conflicts. Adding further rules (say Rule3, Rule4) of the same format only exacerbates the issue. Further reducing the rules to remove their only differentiating Class (X or Y);

rule "Rule1"
when
    // conditions
    $aclass: AClass(type == AType.DOG);
    $bclass: BClass(configClass == BConfig.class);
    $cclass: CClass();
then
    //actions       
    System.out.println("Actioning Rule1");
end

rule "Rule2"
when
    // conditions
    $aclass: AClass(type == AType.DOG);
    $bclass: BClass(configClass == BConfig.class);
    $cclass: CClass();
then
    //actions
    System.out.println("Actioning Rule2");
end

rule "Rule3"
when
    // conditions
    $aclass: AClass(type == AType.DOG);
    $bclass: BClass(configClass == BConfig.class);
    $cclass: CClass();
then
    //actions
    System.out.println("Actioning Rule3");
end

Passing in facts that satisfy those 3 conditions (ie AClass with getType == AType.DOG, BClass with getConfigClass == BConfig.class and a CClass) always runs the last rule, no matter how many rules there are.

Removing the BClass class comparison condition and re-running the test fires all rules as expected.

It seems very strange behaviour that given that one rule fires, the class comparison is valid, but only for one rule?

1
This can't be reproduced unless you provide the exact code for classes A and B and the AType and BType enums.laune
I disagree, given the first three conditions in both rules are the same their actual implementation is irrelevant. Perhaps I should have simplified further and only left CClass in there, the point of the question is that the two rules, given nearly matching conditions seem to block on another.Nick Foote
I disagree as well, since the situation (as described here) cannot be reproduced, i.e., both rules fire.laune
Ok sorry about this, I appear to have oversimplified the code from our actual code. See update regarding class comparison.Nick Foote

1 Answers

0
votes

This is a bug, at least in 6.3.0 and 6.4.0.

It's quite interesting: as long as there are just two identical LHSs, both fire; if there isn't a constraint using a field of type java.lang.Class it's OK; only if there is such a constraint and if there are three rules, two activations are dropped.

Conclusion

The bug was reported as DROOLS-1144 and the fix is available via the pull request https://github.com/droolsjbpm/drools/pull/763