[jboss-jira] [JBoss JIRA] Commented: (JBRULES-904) ArrayIndexOutOfBoundsException in org.drools.util.TupleIndexHashTable.toArray

Brian Stiles (JIRA) jira-events at lists.jboss.org
Tue Jun 26 23:47:57 EDT 2007


    [ http://jira.jboss.com/jira/browse/JBRULES-904?page=comments#action_12366952 ] 
            
Brian Stiles commented on JBRULES-904:
--------------------------------------

As far as I can tell, your fix solves the problem.  I'm a bit concerned that there might be other problems lurking, though, since I believe that there are some broken assumptions in the code.

Perhaps the code as is will operate sufficiently, and if so, fine, but I think there are some issues worth looking at.

Looks to me like TupleIndexHashTable must have been cut-n-paste-modified from TupleHashTable.  TupleHashTable uses ReteTuples as its entries but TupleIndexHashTable uses FieldIndexEntry as entries that hold Tuples.  If my overall assessment is correct, there has been an incomplete shift from using ReteTuples (Entry/Tuple chimeras) as entries to FieldIndexEntrys (that hold references to Tuples) as entries.  (On a more general note, I think that the interface defined by org.drools.reteoo.TupleMemory adds to the problem here since it limits implementation choices by using ReteTuple instead of Tuple, thereby requiring the tuple also to implement org.drools.util.Entry.)

Look at the inner while loop in toArray in your code.  I don't believe that "entry.getNext()" can ever return non-null because entry is the ReteTuple (should just be Tuple) held by fieldIndexEntry and the tuple's "next" is never set with a non-null value (and shouldn't be because the FieldIndexEntry is being used as the table entry, not the tuple).  This has held true in my testing.

Similarly, look at getOrCreate.  If "entry.matches(tuple, hashCode)" in the while loop ever was true, there would be a mismatch between tuples and FieldIndexEntrys (more tuples than entries).  I'm not certain this would be a problem, but it looks to me like that breaks FieldIndexHashTableIterator.next.

And, it looks like FieldIndexHashTableFullIterator.next can't work properly since the following line

  this.entry = (this.table[this.row] != null) ? ((FieldIndexEntry) this.table[this.row]).first : null;

sets "this.entry" to a ReteTuple which will never have "next" that is a FieldIndexEntry.

I never saw either "next" called in my testing, so I can't confirm whether or not the work as is.

I'm going to add an attachment with a patch for org.drools.util.TupleIndexHashTable that cleans things up according to my assumptions.  If you think it's worth looking at, you can check out what I've done and see if it makes sense.

I am not sure if the iterator classes are supposed to iterate over FieldIndexEntrys or ReteTuples, but my code assumes FieldIndexEntrys.

> ArrayIndexOutOfBoundsException in org.drools.util.TupleIndexHashTable.toArray
> -----------------------------------------------------------------------------
>
>                 Key: JBRULES-904
>                 URL: http://jira.jboss.com/jira/browse/JBRULES-904
>             Project: JBoss Rules
>          Issue Type: Bug
>      Security Level: Public(Everyone can see) 
>    Affects Versions:  4.0.0.MR3
>         Environment: Java 1.5
>            Reporter: Dirk Bergstrom
>         Assigned To: Mark Proctor
>             Fix For:  4.0.0.MR4
>
>         Attachments: real-testcase.tgz, testcase.tar.gz
>
>
> When asserting a particular object type, I get the following stacktrace:
> java.lang.ArrayIndexOutOfBoundsException: 26
>         at org.drools.util.TupleIndexHashTable.toArray(TupleIndexHashTable.java:178)
>         at org.drools.reteoo.CollectNode.assertObject(CollectNode.java:212)
>         at org.drools.reteoo.CompositeObjectSinkAdapter.propagateAssertObject(CompositeObjectSinkAdapter.java:317)
>         at org.drools.reteoo.ObjectTypeNode.assertObject(ObjectTypeNode.java:183)
>         at org.drools.reteoo.Rete.assertObject(Rete.java:121)
>         at org.drools.reteoo.ReteooRuleBase.assertObject(ReteooRuleBase.java:201)
>         at org.drools.reteoo.ReteooWorkingMemory.doAssertObject(ReteooWorkingMemory.java:70)
>         at org.drools.common.AbstractWorkingMemory.assertObject(AbstractWorkingMemory.java:766)
>         at org.drools.common.AbstractWorkingMemory.assertObject(AbstractWorkingMemory.java:578)
>         at net.juniper.dash.data.DataSource.reconcileAssertedRecords(DataSource.java:250)
>         at net.juniper.dash.data.DataSource.populateRecords(DataSource.java:193)
>         at net.juniper.dash.Updater$DataSourceProcessor.work(Updater.java:177)
>         at net.juniper.dash.Refresher.run(Refresher.java:69)
> I added some println() statements, and it's not an off-by-one error, it's something more serious.  I changed the allocated size of the array to (this.size * 10), and it *still* tried to overfill the array.  The hashtable had 26 entries, but it tried to add 261, and counting.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the jboss-jira mailing list