[jboss-jira] [JBoss JIRA] Commented: (JBRULES-740) IncompatibleClassChangeError working with ShadowProxy

Edson Tirelli (JIRA) jira-events at lists.jboss.org
Wed Apr 11 08:57:00 EDT 2007


    [ http://jira.jboss.com/jira/browse/JBRULES-740?page=comments#action_12358933 ] 
            
Edson Tirelli commented on JBRULES-740:
---------------------------------------

Dirk,

You are using the "collect" CE!!! :) This is the cause of your apparent "hang".
Problem is that accumulate/collect are very heavy CE's and you need to be carefull when using them.

Being brief, using the following rule:

rule "Find all PRs for user"
when
 $user : User( )
 $pr_list : RecordSet( size > 0 ) from
  collect( PRRecord( $resp : responsible -> ( $user.hasReport($resp) ) ) )
then
 $user.setRecords($pr_list, DataSource.GNATS);
end

if you already have "User" facts asserted into the working memory, it means that for every PRRecord that matches your <constraints>, it will recalculate the "collect". So, if you have a User fact, and assert a PRRecord, it will create a RecordSet and add your PRRecord to the set. When you assert a second PRRecord, it will create a new RecordSet and add the 2 PRRecord. As you see, it is a progression: 1+2+3+4...+N. 
Your case is even worst because your constraint is a predicate (not indexable right now), so, it means the progression above is executed in full.

It seems a simple thing to "optimize", but it is not. Although we need to do it soon, possibly before final.

Anyway, what you need to do:

1) If possible, adjust your business model in a way to replace the predicate for a regular "==" constraint, avoiding full iteration because of indexing.

2) Use a control fact to limit the partial matches. Example:

rule "Find all PRs for user"
when
 $control : ControlFact( phase == "findPR" )
 $user : User( )
 $pr_list : RecordSet( size > 0 ) from
  collect( PRRecord( $resp : responsible -> ( $user.hasReport($resp) ) ) )
then
 $user.setRecords($pr_list, DataSource.GNATS);
 $control.setPhase( "do everything else" )
 modify( $control )
end

    Doing the above, make sure you assert all PRRecords first and only then, set (or assert) your control fact to phase "findPR". The above will make the engine avoid wasting time calculating partial matches that will never be used.
     It seems ugly at first, but it is a technique that unfortunately needs to be used in some special cases.

     I will close this ticket for now. If you can, please open a ticket for collect/accumulate optimization and refer to this ticket in your comments. 

   Thank you,
   Edson


> IncompatibleClassChangeError working with ShadowProxy
> -----------------------------------------------------
>
>                 Key: JBRULES-740
>                 URL: http://jira.jboss.com/jira/browse/JBRULES-740
>             Project: JBoss Rules
>          Issue Type: Bug
>      Security Level: Public(Everyone can see) 
>    Affects Versions: 3.1-m2
>         Environment: Trunk (revision 10170)
>            Reporter: Dirk Bergstrom
>         Assigned To: Edson Tirelli
>             Fix For: 3.1-m2
>
>         Attachments: more-stacktraces.txt, Record.java, RLIRecord.java, stacktraces.txt
>
>
> I'm getting an exception while asserting objects into the working memory.  Depending on the timing, I get different stacktraces leading up the same exception on the same generated class.  I have 15 rules and three types of objects in the working memory.  2500 User objects, 37 Milestone objects, and 2000 RLI objects.  If I assert all the Users and Milestones first, I get the first exception below during assertion of the RLI objects, at the 257th object asserted.  If I arrange to skip that particular record, I can assert a few more before another record trips the bug.  If I put a try/catch block around the assertion and continue after hitting an exception, I can assert about 1600 of the records successfully, and the others reliably throw (ie. if I try to assert them later).  If I assert RLIs first, I get the second stacktrace during assertion of Milestones.  Looks like the problem happens during execution of one or more rules.  I'll attach the RLI class, and its parent class (which is also the parent of the other two classes).
> Exception in thread "RLIs Processor" java.lang.IncompatibleClassChangeError
> 	at net.juniper.dash.data.RLIRecordShadowProxy.hashCode(Unknown Source)
> 	at java.util.HashMap.put(HashMap.java:418)
> 	at java.util.HashSet.add(HashSet.java:194)
> 	at org.drools.reteoo.CollectNode.assertTuple(CollectNode.java:135)
> 	at org.drools.reteoo.CollectNode.assertObject(CollectNode.java:212)
> 	at
> org.drools.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:20)
> 	at org.drools.reteoo.AlphaNode.assertObject(AlphaNode.java:145)
> 	at
> org.drools.reteoo.CompositeObjectSinkAdapter.propagateAssertObject(CompositeObjectSinkAdapter.java:304)
> 	at org.drools.reteoo.ObjectTypeNode.assertObject(ObjectTypeNode.java:176)
> 	at org.drools.reteoo.Rete.assertObject(Rete.java:121)
> 	at org.drools.reteoo.ReteooRuleBase.assertObject(ReteooRuleBase.java:196)
> 	at
> org.drools.reteoo.ReteooWorkingMemory.doAssertObject(ReteooWorkingMemory.java:68)
> 	at
> org.drools.common.AbstractWorkingMemory.assertObject(AbstractWorkingMemory.java:729)
> 	at
> org.drools.common.AbstractWorkingMemory.assertObject(AbstractWorkingMemory.java:548)
> Exception in thread "Milestones and NPI Processor" java.lang.IncompatibleClassChangeError
> 	at net.juniper.dash.data.RLIRecordShadowProxy.hashCode(Unknown Source)
> 	at java.util.HashMap.put(HashMap.java:418)
> 	at java.util.HashSet.add(HashSet.java:194)
> 	at org.drools.reteoo.CollectNode.assertTuple(CollectNode.java:135)
> 	at org.drools.reteoo.CompositeTupleSinkAdapter.propagateAssertTuple(CompositeTupleSinkAdapter.java:30)
> 	at org.drools.reteoo.JoinNode.assertTuple(JoinNode.java:116)
> 	at org.drools.reteoo.SingleTupleSinkAdapter.createAndPropagateAssertTuple(SingleTupleSinkAdapter.java:55)
> 	at org.drools.reteoo.LeftInputAdapterNode.assertObject(LeftInputAdapterNode.java:147)
> 	at org.drools.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:20)
> 	at org.drools.reteoo.AlphaNode.assertObject(AlphaNode.java:145)
> 	at org.drools.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:20)
> 	at org.drools.reteoo.ObjectTypeNode.assertObject(ObjectTypeNode.java:176)
> 	at org.drools.reteoo.Rete.assertObject(Rete.java:121)
> 	at org.drools.reteoo.ReteooRuleBase.assertObject(ReteooRuleBase.java:196)
> 	at org.drools.reteoo.ReteooWorkingMemory.doAssertObject(ReteooWorkingMemory.java:68)
> 	at org.drools.common.AbstractWorkingMemory.assertObject(AbstractWorkingMemory.java:729)
> 	at org.drools.common.AbstractWorkingMemory.assertObject(AbstractWorkingMemory.java:548)
> 	at net.juniper.dash.data.DataSource.reconcileAssertedRecords(DataSource.java:190)
> 	at net.juniper.dash.data.DataSource.populateRecords(DataSource.java:150)
> 	at net.juniper.dash.Updater$DataSourceProcessor.work(Updater.java:181)
> 	at net.juniper.dash.Refresher.run(Refresher.java:70)

-- 
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