[rules-users] ClassCastException due to binding
We have a need to support binds for conditional or elements so that we can describe why a rule fired in the then clause of a rule. The following DRL is a simple example of what we are trying to do. There are two versions of our rule in the DRL: *rule WORKING: find with or*: works but only because the first variable we try to bind in the or expression is of type target which is a super class of the other elements in the or expression. *rule BROKEN: find with or*: causes a class cast exception when the bar pattern is matched because the then clause tries to store the bar object in handle x which it thinks is of type foo. Is there a way to define the object type for the bind variable? Is there any other way to make something like this work? package tests import org.apache.log4j.Logger; global Logger log declare target notreal : boolean end declare foo extends target foovalue : String end declare bar extends target barvalue : String end rule insertdata when then insert(new foo(false, a)); insert(new bar(false, b)); end rule WORKING: find with or when ( or x: target(notreal) x: foo(foovalue == a) x: bar(barvalue == b) ) then log.info(i found object: + x); end rule BROKEN: find with or when ( or x: foo(foovalue == a) x: bar(barvalue == b) ) then log.info(i found object: + x); end Exception executing consequence for rule find with or in tests: java.lang.ClassCastException: tests.bar cannot be cast to tests.foo at org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:39) at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1283) at org.drools.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:1209) at org.drools.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1442) at org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:710) at org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:674) at org.drools.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:230) at org.drools.impl.StatelessKnowledgeSessionImpl.execute(StatelessKnowledgeSessionImpl.java:278) at tests.DroolsTest.testStateless(DroolsTest.java:120) at tests.DroolsTest.runTest(DroolsTest.java:74) at tests.DroolsTest.main(DroolsTest.java:59) Caused by: java.lang.ClassCastException: tests.bar cannot be cast to tests.foo at tests.Rule_find_with_or_411ee1c99de54340945b2b707ad0a576DefaultConsequenceInvoker.evaluate(Unknown Source) at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1273) ... 9 more -- View this message in context: http://drools.46999.n3.nabble.com/ClassCastException-due-to-binding-tp4024115.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] Finding matching values in composite constraint
Is there a way to determine (in the rule consequence) which condition in a composite constraint caused a rule to succeed? I am working on a system that allows users to create rules via a custom UI and when one of their rules fires, I want to be able to create a message that describes why their rule fired. In a real example, they might have a list of a few hundred conditions in a composite constraint. An example rule with just two conditions in a composite constraint follows: rule test rule when MyObject( (myfield str[startsWith] a || myfield str[startsWith] b) ) then System.out.prinltn(kcontext.getRule().getName() + fired because myfield started with ???); end Is this exposed somewhere in the variables like kcontext that are available to each rule in their consequence? -- View this message in context: http://drools.46999.n3.nabble.com/Finding-matching-values-in-composite-constraint-tp4021343.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] Finding matching values in composite constraint
Suppose we have a Transaction object with a String field. Users want to create a rule through our application that says alert me whenever the value of that field contains a value in a list of values provided in the rule. It's easy enough to write this type of rule and send an alert; however, it would be helpful to include the value from the list that matched. The only way I can think to do this type of thing is to create a function somewhere that checks if the field contains any of the values in the user list and if so return that value. Then call that function in the rule condition and bind the result. Something like what follows: public class ExternalMatcher { public static String contains(String field, String...list) { // return the first string that satisfies the contains logic or null if no strings succeed } } rule test when Transaction( $matchedValue : ExternalMatcher.contains(field, value1, value2, value3) != null) then sendAlert(I found a transaction that matched your criteria because field foo equals: + $matchedValue); end -- View this message in context: http://drools.46999.n3.nabble.com/Finding-matching-values-in-composite-constraint-tp4021343p4021346.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] Drools Rule Evaluations are Inconsistent
Drools is not producing consistent results in the following example. If you run the DRL shown below, you will see that rules 2 and 3 activate and log a message. If you then comment out rule 3 in the DRL (you must put the entire rule inside /* */ characters rather than simply disabling it), and rerun it, you'll notice that rules 1 and 2 fire. How is it that the presence of rule 3 affects whether or not rule 1 activates? These two rules are not dependent in their DRL. It appears to be related to the fact that rule 1 uses single quotes instead of double quotes. If you change that, then Drools starts behaving consistently. This makes me believe that the problem is somehow related to how Drools is building the Rete tree with the single quotes. With all three rules active I get: [main]::INFO ::DroolsTest::test 3 hit on RecordA( id=100 ) - RecordB( id=100, role=2 ) [main]::INFO ::DroolsTest::test 2 hit on RecordA( id=100 ) - RecordB( id=100, role=1 ) With rule 3 commented out I get: [main]::INFO ::DroolsTest::test 2 hit on RecordA( id=100 ) - RecordB( id=100, role=1 ) [main]::INFO ::DroolsTest::test 1 hit on RecordA( id=100 ) - RecordB( id=100, role=1 ) Interestingly, if you comment out rule 2 so only rules 1 and 3 are active, rule 1 fires again: [main]::INFO ::DroolsTest::test 3 hit on RecordA( id=100 ) - RecordB( id=100, role=2 ) [main]::INFO ::DroolsTest::test 1 hit on RecordA( id=100 ) - RecordB( id=100, role=1 ) *Environment: Drools 5.4.0* package tests import org.apache.log4j.Logger; global Logger log declare RecordA id : long end declare RecordB id : long role : String end rule insert data 1 salience 9 when then insert (new RecordA(100)); insert (new RecordB(100, 1)); insert (new RecordB(100, 2)); end rule test 1 when a : RecordA( ) b : RecordB( id == b.id, role == '1' ) then log.info(String.format(%s hit on %s - %s, kcontext.getRule().getName(), a, b)); end rule test 2 when a : RecordA( ) b : RecordB( id == b.id, role == 1 ) then log.info(String.format(%s hit on %s - %s, kcontext.getRule().getName(), a, b)); end rule test 3 when a : RecordA( ) b : RecordB( id == b.id, role == 2 ) then log.info(String.format(%s hit on %s - %s, kcontext.getRule().getName(), a, b)); end -- View this message in context: http://drools.46999.n3.nabble.com/Drools-Rule-Evaluations-are-Inconsistent-tp4019900.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] Drools Rule Evaluations are Inconsistent
I was able to use the Drools Eclipse Plugin to view the Rete tree and I can confirm that it Drools does build the tree differently under the scenarios described above. With rule 3 commented out, there are 2 AlphaNodes -- one checks for [role==1] and the other checks for [role=='1']. With rule 3 uncommented, the AlphaNode for [role=='1'] disappears. It seems rather scary that Drools doesn't create the Rete tree the same way. I hope there aren't any other issues like this that may affect the validity of the rules??? Do you recommend skipping the upgrade to Drools 5.4.0 in favor of another version? -- View this message in context: http://drools.46999.n3.nabble.com/Drools-Rule-Evaluations-are-Inconsistent-tp4019900p4019902.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] Bug in enabled rule attribute???
The following DRL produces a Null Pointer Exception when the enabled attribute is set to false on test rule 2. Any ideas why? Changing this value to true or commenting out the rule causes things to succeed. Environment: Java 7 and Drools 5.4 package tests import org.apache.log4j.Logger; import java.util.List; global Logger log declare Data name : String end rule insert Data when then insert(new Data(test)); end rule test rule 2 enabled false when d : List() from collect (Data( name == test) ) then log.info(String.format(%s hit on %s, kcontext.getRule().getName(), d)); end Exception executing consequence for rule insert Data in tests: java.lang.NullPointerException at org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:39) at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1283) at org.drools.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:1209) at org.drools.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1442) at org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:710) at org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:674) at org.drools.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:230) at org.drools.impl.StatelessKnowledgeSessionImpl.execute(StatelessKnowledgeSessionImpl.java:278) at tests.DroolsTest.testStateless(DroolsTest.java:98) at tests.DroolsTest.runTest(DroolsTest.java:60) at tests.DroolsTest.main(DroolsTest.java:45) Caused by: java.lang.NullPointerException at org.drools.common.DefaultAgenda.createActivation(DefaultAgenda.java:569) at org.drools.reteoo.RuleTerminalNode.modifyLeftTuple(RuleTerminalNode.java:297) at org.drools.reteoo.SingleLeftTupleSinkAdapter.propagateModifyChildLeftTuple(SingleLeftTupleSinkAdapter.java:259) at org.drools.reteoo.AccumulateNode.evaluateResultConstraints(AccumulateNode.java:676) at org.drools.reteoo.ReteooWorkingMemory$EvaluateResultConstraints.execute(ReteooWorkingMemory.java:591) at org.drools.common.PropagationContextImpl.evaluateActionQueue(PropagationContextImpl.java:345) at org.drools.common.NamedEntryPoint.insert(NamedEntryPoint.java:342) at org.drools.common.NamedEntryPoint.insert(NamedEntryPoint.java:298) at org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:888) at org.drools.base.DefaultKnowledgeHelper.insert(DefaultKnowledgeHelper.java:187) at org.drools.base.DefaultKnowledgeHelper.insert(DefaultKnowledgeHelper.java:181) at tests.Rule_insert_Data_2eb7a40b15e640d6bc777e1075d1218b.defaultConsequence(Rule_insert_Data_2eb7a40b15e640d6bc777e1075d1218b.java:7) at tests.Rule_insert_Data_2eb7a40b15e640d6bc777e1075d1218bDefaultConsequenceInvokerGenerated.evaluate(Unknown Source) at tests.Rule_insert_Data_2eb7a40b15e640d6bc777e1075d1218bDefaultConsequenceInvoker.evaluate(Unknown Source) at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1273) -- View this message in context: http://drools.46999.n3.nabble.com/Bug-in-enabled-rule-attribute-tp4019049.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] Unification with logical or question
Thank you for your response. I am aware that the rule with the conditional or gets rewritten into two separate rules and that rule is actually doing what I would expect -- producing two matches. The main part of my question is why doesn't the second rule produce the same results -- I was expecting two matches but it only produces one. The only thing I can think of is that it's an order of operations issue but that doesn't seem to make sense given the parenthesis. The second pattern in that rule is basically: condition || (! condition unification) This should produce two matches with the given data but, it doesn't produce a match when the condition left of the || is satisfied (in that case the unification shouldn't be happening but, maybe it is?). If I change the rule to the following, it does produce two matches which makes me believe that the unification is affecting things. condition || ! condition Thoughts? -- View this message in context: http://drools.46999.n3.nabble.com/Unification-with-logical-or-question-tp4017826p4017833.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] Newbie problem: I can't get Eclipse and Examples working
Does your CLASSPATH for the runtime configuration include the target/classes directory? -- View this message in context: http://drools.46999.n3.nabble.com/Newbie-problem-I-can-t-get-Eclipse-and-Examples-working-tp4017824p4017834.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] Unification with logical or question
Can someone explain to me why these two rules behave differently? I expected that the second rule would produce the same output as the first but it seems to ignore the first half of the logical or expression. Is this because the unification happens before the null checks occur? declare Foo name : String item : Item end declare Item id : long end rule insert stuff when then Item item1 = new Item(1); Foo foo1 = new Foo(foo1, item1); insert(foo1); Foo foo3 = new Foo(foo3, null); insert(foo3); end rule Unification Test Rule when f : Foo ( item != null, $item := item ) f2 : ( Foo ( item == null ) or Foo ( $item := item ) ) then System.out.println(String.format(%s Fired:\n\tFoo: %s\n\t%s, kcontext.getRule().getName(), f, f2)); end rule Unification Test Rule 2 salience -10 when f : Foo ( item != null, $item := item ) f2 : Foo ( ( item == null ) || ( item != null $item := item ) ) then System.out.println(String.format(%s Fired:\n\tFoo: %s\n\t%s, kcontext.getRule().getName(), f, f2)); end Unification Test Rule Fired: Foo: Foo( name=foo1, item=Item( id=1 ) ) Foo( name=foo3, item=null ) Unification Test Rule Fired: Foo: Foo( name=foo1, item=Item( id=1 ) ) Foo( name=foo1, item=Item( id=1 ) ) Unification Test Rule 2 Fired: Foo: Foo( name=foo1, item=Item( id=1 ) ) Foo( name=foo1, item=Item( id=1 ) ) -- View this message in context: http://drools.46999.n3.nabble.com/Unification-with-logical-or-question-tp4017826.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] Integrating Drools with rules from a legacy BRMS
I am working on integrating Drools with a legacy BRMS that was developed in-house. The customers like the BRMS and are unwilling to migrate to another tool such as Guvnor. The BRMS creates the rules in a proprietary XML format. In order to integrate Drools with the BRMS, I need to convert these rules to a format that Drools understands and that leaves me with what seems like 3 options: 1) Write some XSLT to transform the proprietary XML to Drools XML format. This seems straightforward; however, I am concerned that the online documentation states that the Drools XML format should be considered deprecated. I'd hate to invest much time in this approach if the XML support is going to disappear in a future release. 2) Write my own parser that can convert the proprietary XML to classes in the org.lang.descr package. I'm not sure if the Drools developers intend for others to use these classes directly. For instance, if they change frequently, this approach may be difficult to maintain. 3) Write my own parser that can convert the proprietary XML to DRL. This approach seems unfortunate in that the rules would be parsed twice; first to convert them to DRL and then internally by the Drools DrlParser. Also, this doesn't seem to offer any benefit over approach 2 (except that I know DRL well and wouldn't have to learn how the org.lang.descr classes work [not much documentation in those classes]). Right now, I'm leaning towards approach 2. Any thoughts or suggestions would be appreciated. -- View this message in context: http://drools.46999.n3.nabble.com/Integrating-Drools-with-rules-from-a-legacy-BRMS-tp4017676.html Sent from the Drools: User forum mailing list archive at Nabble.com. ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users