[
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