[jboss-jira] [JBoss JIRA] (JBRULES-3466) sum with no matching values results in NPE on reverse

Chris Dolan (JIRA) jira-events at lists.jboss.org
Tue Apr 17 09:40:24 EDT 2012


    [ https://issues.jboss.org/browse/JBRULES-3466?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12684921#comment-12684921 ] 

Chris Dolan commented on JBRULES-3466:
--------------------------------------

Hmm, I've failed to reproduce the problem in a unit test. Below is my failed attempt. If there are any useful diagnostics I can do on my real model, please let me know.

New file: src/test/resources/org/drools/integrationtests/test_AccumulateReverseModifyInsertLogical.drl

{noformat}
package org.drools.test;

import org.drools.Cheese;
import org.drools.Cheesery;
import org.drools.Person;

global java.util.List results;

declare Total
    person : Person
    value : Number
end

rule "Total" salience 2
    when
        $person      : Person( $likes : likes )
        $total       : Number() from accumulate( $c : Cheese( type == $likes ),
                                                sum($c.getPrice()) )
    then
    	insertLogical(new Total($person, $total));
end  

rule "Minimum Total" salience 1
    when
        $min       : Number() from accumulate( $p : Person(name != "Doug") and $t : Total(person == $p),
        										min($t.getValue()) )
    then
        results.add( $min );
end
{noformat}

Modified file: 

{noformat}
diff --git a/drools-compiler/src/test/java/org/drools/integrationtests/AccumulateTest.java b/drools-compiler/src/test/java/org/drools/integrationtests/AccumulateTest.java
index 0c4db51..c37fe67 100644
--- a/drools-compiler/src/test/java/org/drools/integrationtests/AccumulateTest.java
+++ b/drools-compiler/src/test/java/org/drools/integrationtests/AccumulateTest.java
@@ -475,6 +475,93 @@ public class AccumulateTest extends CommonTestMethodBase {
     }
 
     @Test
+    public void testAccumulateReverseModifyInsertLogical() throws Exception {
+        // read in the source
+        final Reader reader = new InputStreamReader( getClass().getResourceAsStream( "test_AccumulateReverseModifyInsertLogical.drl" ) );
+        final RuleBase ruleBase = loadRuleBase( reader );
+
+        final WorkingMemory wm = ruleBase.newStatefulSession();
+        final List results = new ArrayList();
+
+        wm.setGlobal( "results",
+                      results );
+
+        final Cheese[] cheese = new Cheese[]{
+                       new Cheese( "stilton", 10 ),
+                       new Cheese( "stilton", 2 ),
+                       new Cheese( "stilton", 5 ),
+                       new Cheese( "brie", 15 ),
+                       new Cheese( "brie", 16 ),
+                       new Cheese( "provolone", 8 )
+        };
+        final Person alice = new Person( "Alice", "brie" );
+        final Person bob = new Person( "Bob", "stilton" );
+        final Person carol = new Person( "Carol", "cheddar" );
+        final Person doug = new Person( "Doug", "stilton" );
+
+        final FactHandle[] cheeseHandles = new FactHandle[cheese.length];
+        for ( int i = 0; i < cheese.length; i++ ) {
+            cheeseHandles[i] = wm.insert( cheese[i] );
+        }
+        final FactHandle aliceHandle = wm.insert( alice );
+        final FactHandle bobHandle = wm.insert( bob );
+        // add Carol later
+        final FactHandle dougHandle = wm.insert( doug ); // should be ignored
+
+        wm.fireAllRules();
+        System.out.println("results: " + results);
+        assertEquals( 17, ((Number) results.get( results.size() - 1 )).intValue() );
+
+        wm.retract(cheeseHandles[1]);
+        wm.fireAllRules();
+        System.out.println("results: " + results);
+        assertEquals( 15, ((Number) results.get( results.size() - 1 )).intValue() );
+
+        bob.setLikes( "provolone" );
+        wm.update( bobHandle, bob );
+        wm.fireAllRules();
+        System.out.println("results: " + results);
+        assertEquals( 8, ((Number) results.get( results.size() - 1 )).intValue() );
+
+        wm.retract(cheeseHandles[5]);
+        wm.fireAllRules();
+        System.out.println("results: " + results);
+        assertEquals( 0, ((Number) results.get( results.size() - 1 )).intValue() );
+
+        wm.retract(bobHandle);
+        wm.fireAllRules();
+        System.out.println("results: " + results);
+        assertEquals( 31, ((Number) results.get( results.size() - 1 )).intValue() );
+
+        final FactHandle carolHandle = wm.insert( carol );
+        wm.fireAllRules();
+        System.out.println("results: " + results);
+        assertEquals( 0, ((Number) results.get( results.size() - 1 )).intValue() );
+
+        FactHandle cheddarHandle = wm.insert(new Cheese("cheddar", 6));
+        wm.fireAllRules();
+        System.out.println("results: " + results);
+        assertEquals( 6, ((Number) results.get( results.size() - 1 )).intValue() );
+
+        wm.retract(cheddarHandle);
+        wm.fireAllRules();
+        System.out.println("results: " + results);
+        assertEquals( 0, ((Number) results.get( results.size() - 1 )).intValue() );
+
+        wm.retract(aliceHandle);
+        wm.retract(carolHandle);
+        wm.retract(dougHandle);
+        wm.fireAllRules();
+        System.out.println("results: " + results);
+        assertEquals( Integer.MAX_VALUE, ((Number) results.get( results.size() - 1 )).intValue() );
+
+        wm.insert(alice);
+        wm.fireAllRules();
+        System.out.println("results: " + results);
+        assertEquals( 31, ((Number) results.get( results.size() - 1 )).intValue() );
+    }
+
+    @Test
     public void testAccumulateReverseModifyMVEL() throws Exception {
         // read in the source
         final Reader reader = new InputStreamReader( getClass().getResourceAsStream( "test_AccumulateReverseModifyMVEL.drl" ) );
{noformat}

                
> sum with no matching values results in NPE on reverse
> -----------------------------------------------------
>
>                 Key: JBRULES-3466
>                 URL: https://issues.jboss.org/browse/JBRULES-3466
>             Project: Drools
>          Issue Type: Bug
>      Security Level: Public(Everyone can see) 
>          Components: drools-core  (expert)
>    Affects Versions: 5.4.0.CR1
>         Environment: drools-planner 5.4.0-SNAPSHOT, snapshot downloaded on Apr 9, 2012
>            Reporter: Chris Dolan
>            Assignee: Edson Tirelli
>
> I have a rule with this element in the when clause:
> {noformat}
>         $beforePrediction : Number() from accumulate(
>              JobSlot(job != NULL_JOB, $j : job, $service == service, $ordinal > ordinal) and $p : Prediction(job == $j, service == $service),
>              sum($p.getMillisMid())
>         )
> {noformat}
> When I execute this I have cases where there are no matching Prediction instances, so the sum is zero. Later on retract, I get this:
> {noformat}
> Caused by: java.lang.NullPointerException: null
> 	at org.drools.base.accumulators.SumAccumulateFunction.reverse(SumAccumulateFunction.java:83)
> 	at org.drools.base.accumulators.JavaAccumulatorFunctionExecutor.reverse(JavaAccumulatorFunctionExecutor.java:130)
> 	at org.drools.rule.Accumulate.reverse(Accumulate.java:208)
> {noformat}
> The relevant code is this:
> {noformat}
>     public void accumulate(Serializable context,
>                            Object value) {
>         SumData data = (SumData) context;
>         data.total += ((Number) value).doubleValue();
>     }
> {noformat}
> and this:
> {noformat}
>     public void reverse(Object workingMemoryContext,
>                         Object context,
>                         Tuple leftTuple,
>                         InternalFactHandle handle,
>                         Declaration[] declarations,
>                         Declaration[] innerDeclarations,
>                         WorkingMemory workingMemory) throws Exception {
>         final Object value = ((JavaAccumulatorFunctionContext) context).reverseSupport.remove( Integer.valueOf( handle.getId() ) );
>         this.function.reverse( ((JavaAccumulatorFunctionContext) context).context,
>                                value );
>     }
> {noformat}
> A breakpoint reveals that handle is a Prediction instance. Somehow that handle was not added to reverseSupport, apparently.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.jboss.org/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the jboss-jira mailing list