[rules-users] Adding @PropertyReactive causes the other rules removed from the stack

Mark Proctor mproctor at codehaus.org
Fri Dec 20 10:22:13 EST 2013


small correction to the unit test, which I paste in full below:

@Test
public void testModifyAfterInsertWithPropertyReactive() {
    String rule1 =
            "\n" +
            "package com.sample;\n" +
            "import " + MyClass.class.getCanonicalName() + ";\n" +
            "global java.util.List list;\n" +
            "rule r0\n" +
            "then insert( new MyClass() );\n" +
            "end\n" +
            "rule r1 salience 1\n" +
            "when " +
            "  MyClass(value == null)\n" +
            "then " +
            "  list.add( 1 );\n" +
            "end\n" +
            "\n" +
            "rule r2 salience 2\n" +
            "when " +
            "  m : MyClass(value == null)\n" +
            "then " +
            "  modify(m) { setData(\"test\") }\n" +
            "  list.add( 2 );\n" +
            "end\n" +
            "\n" +
            "rule r3 salience 3\n" +
            "when " +
            "  MyClass(value == null)\n" +
            "then " +
            "  list.add( 3 );\n" +
            "end";

    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add( ResourceFactory.newByteArrayResource(rule1.getBytes()), ResourceType.DRL );

    if ( kbuilder.hasErrors() ) {
        fail( kbuilder.getErrors().toString() );
    }

    KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
    kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );

    StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
    List list = new ArrayList();
    ksession.setGlobal("list", list);

    assertEquals(4, ksession.fireAllRules());

    assertEquals(3, list.size());

    assertEquals(3, list.get(0));
    assertEquals(2, list.get(1));
    assertEquals(1, list.get(2));
}


On 20 Dec 2013, at 15:14, Mark Proctor <mproctor at codehaus.org> wrote:

> I turned your code into a unit test and added it to the 6.0 codebase. see the method “testModifyAfterInsertWithPropertyReactive” in the commit:
> https://github.com/droolsjbpm/drools/commit/53ca46d3b
> 
> It works for PHREAK and RETE mode. Everything works for 6.0, we’ll try it against 5.6.CR1 soon
> 
> Mark
> 
> On 20 Dec 2013, at 09:14, Sonata <plz.write.to at gmail.com> wrote:
> 
>> Davide Sottara wrote
>>> The goal of @propertyReactive is exactly to prevent rules from refiring
>>> on a modify, based on what properties are constrained or @watched.
>>> This is irrelevant with respect to the order of the rules.
>>> This may or may not be a bug, we'd need to see the rules.
>>> Davide
>> 
>> Example attached
>> 
>> ReactiveTest.java
>> package com.sample;
>> import org.drools.KnowledgeBase;
>> import org.drools.KnowledgeBaseFactory;
>> import org.drools.builder.KnowledgeBuilder;
>> import org.drools.builder.KnowledgeBuilderFactory;
>> import org.drools.builder.ResourceType;
>> import org.drools.io.ResourceFactory;
>> import org.drools.logger.KnowledgeRuntimeLogger;
>> import org.drools.logger.KnowledgeRuntimeLoggerFactory;
>> import org.drools.runtime.StatefulKnowledgeSession;
>> public class ReactiveTest {
>> 	public static final void main(String[] args) {
>> 		KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
>> 		kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"),
>> ResourceType.DRL);
>> 		KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
>> 		kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
>> 		StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
>> 		ksession.insert(new MyClass());
>> 		ksession.fireAllRules();
>> 	}
>> }
>> 
>> MyClass.java
>> package com.sample;
>> import org.drools.definition.type.PropertyReactive;
>> @PropertyReactive
>> public class MyClass {
>> 	private String value;
>> 	public String getValue() { return value; }
>> 	public void setValue(String value) { this.value = value; }
>> }
>> 
>> Sample.drl
>> package com.sample;
>> rule "1"
>> when MyClass(value == null)
>> then System.out.println("Rule 1 fired");
>> end
>> 
>> rule "2"
>> when m : MyClass(value == null)
>> then modify(m) { setData("test") }
>> end
>> 
>> rule "3"
>> when MyClass(value == null)
>> then System.out.println("Rule 3 fired");
>> end
>> 
>> So you can see from the example, rule "1", rule "2" and rule "3" are all
>> added to the stack ready to be fired.
>> Rules are then fired starting from the bottom, where rule "3" fired and then
>> rule "2" fired. But rule "1" is being removed from the stack after rule "2"
>> has fired, which is a mystery to me.
>> 
>> Try to remove modify(m) to just m.setData("test") in rule "2", all three
>> rules fired.
>> 
>> So I agree to your "prevent rules from refiring", but this case is not even
>> fired yet.
>> 
>> 
>> 
>> --
>> View this message in context: http://drools.46999.n3.nabble.com/Adding-PropertyReactive-causes-the-other-rules-removed-from-the-stack-tp4027374p4027382.html
>> Sent from the Drools: User forum mailing list archive at Nabble.com.
>> _______________________________________________
>> rules-users mailing list
>> rules-users at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/rules-users
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20131220/6ec35c74/attachment-0001.html 


More information about the rules-users mailing list