[rules-users] Class Cast Exception in Drools 4 Generated Accumulate Method

Edson Tirelli tirelli at post.com
Tue Jun 23 12:09:48 EDT 2009


   Steve,

   What versions of MVEL and Drools are you using?
   Comments:

* You can not share packages between rulebases. You can share rulebases
among sessions. So, I strongly advise you to change your application to
build the rulebase once, and have the web sessions only create the rule
session every time... not the whole rulebase. Since packages have their own
classloaders and everytime you create a rulebase you merge such
classloaders, the problem might happen (CCE) exactly at the time you are
creating the rulebase concurrently. Drools 5 allows you to share packages,
although I still prefer to not do it and share only the rulebase.

* You can not use collect in this case, because you are creating a list of
$slot, not a list of PotentialMatch. Although, it is extremely easy to
create an accumulate function for that. Drools 5 includes 2 accumulate
functions: collectSet and collectList for that. If you want, just get the
class from Drools 5, fix the imports to use the classes from Drools 4 and
use it. Except for the "imports" you should not have any problem. Your rule
would look like:


*rule* "My Rule"
    *salience* 50
    *dialect* "java"
    *no-loop* *true*
    *when*
        $module : Module( selected == *false*, required > 1, $size :
required )
        $list : List( )
                *from* *accumulate*( PotentialMatch( module == $module,
$slot : slot ),
                    collectList( $slot ) )
        *eval*( countThem($list, $size) != $module.setMatchCount() )
    *then*
        *modify*( $module ) { setMatchCount(countThem($list, $size)) };
*end*

* Finally, your eval looks odd to me, but anyway, don't have enough details
to advise you on that.


    []s
    Edson


2009/6/23 Steve Ronderos <steve.ronderos at ni.com>

>
> Hi Rules Users,
>
> I'm experiencing an issue with a Drools 4.0.7 rule.
>
> Here is a clip of the exception that is thrown:
>
> Caused by: org.mvel.CompileException: cannot invoke method
>         at
> org.mvel.optimizers.impl.refl.MethodAccessor.getValue(MethodAccessor.java:54)
>         at
> org.mvel.optimizers.impl.refl.VariableAccessor.getValue(VariableAccessor.java:39)
>         at
> org.mvel.ast.VariableDeepPropertyNode.getReducedValueAccelerated(VariableDeepPropertyNode.java:22)
>         at
> org.mvel.ast.PropertyASTNode.getReducedValueAccelerated(PropertyASTNode.java:21)
>         at org.mvel.MVELRuntime.execute(MVELRuntime.java:90)
>         at
> org.mvel.CompiledExpression.getValue(CompiledExpression.java:111)
>         at org.mvel.MVEL.executeExpression(MVEL.java:235)
>         at
> org.drools.base.mvel.MVELConsequence.evaluate(MVELConsequence.java:48)
>         at
> org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:554)
>         ... 80 more
> Caused by: java.lang.reflect.InvocationTargetException
>         at sun.reflect.GeneratedMethodAccessor412.invoke(Unknown Source)
>         at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>         at java.lang.reflect.Method.invoke(Method.java:585)
>         at
> org.mvel.optimizers.impl.refl.MethodAccessor.getValue(MethodAccessor.java:46)
>         ... 88 more
> Caused by: org.drools.RuntimeDroolsException: java.lang.ClassCastException:
> com.demo.Rule_My_Rule_0$Accumulate0
>         at org.drools.rule.Accumulate.accumulate(Accumulate.java:131)
>         at
> org.drools.reteoo.AccumulateNode.modifyTuple(AccumulateNode.java:352)
>         at
> org.drools.reteoo.AccumulateNode.assertObject(AccumulateNode.java:248)
>         at
> org.drools.reteoo.CompositeObjectSinkAdapter.propagateAssertObject(CompositeObjectSinkAdapter.java:318)
>         at
> org.drools.reteoo.ObjectTypeNode.assertObject(ObjectTypeNode.java:162)
>         at org.drools.reteoo.Rete.assertObject(Rete.java:175)
>         at
> org.drools.reteoo.ReteooRuleBase.assertObject(ReteooRuleBase.java:192)
>         at
> org.drools.reteoo.ReteooWorkingMemory.doInsert(ReteooWorkingMemory.java:71)
>         at
> org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:911)
>         at
> org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:883)
>         at
> org.drools.base.DefaultKnowledgeHelper.insert(DefaultKnowledgeHelper.java:67)
>         at
> org.drools.base.DefaultKnowledgeHelper.insert(DefaultKnowledgeHelper.java:61)
>         ... 92 more
> Caused by: java.lang.ClassCastException:
> com.demo.Rule_My_Rule_0$Accumulate0
>         at
> com.demo.Rule_My_Rule_0Accumulate0Invoker.accumulate(Rule_My_Rule_0Accumulate0Invoker.java:43)
>         at org.drools.rule.Accumulate.accumulate(Accumulate.java:123)
>         ... 103 more
>
> The actually rule name and package are a lot longer, I changed them here
> for brevity and because I don't believe the names themselves are relevant.
>
> This exception is being thrown intermittently when this rule, which
> contains an accumulate function is called.  I say intermittently because it
> does not happen every time the rule is run.  As far as I can tell the
> ClassCastExceptions only happens when the computer that the rules are
> running on is under load.
>
> A few more details before I post the rule itself.  The rule base that I am
> building consists of 2 drl files.  Both of the files have the same package
> declaration at the top.  The 2 packages are built separately using
> PackageBuilder then combined using RuleBase.addPackage() on both packages.
>  Also, I'm not sure if this is relevant, but this scenario takes place in a
> web application where the two package objects are only built once (for
> performance) but each user session creates a new RuleBase and adds the
> packages.  The individual sessions then create stateful sessions from the
> rule base.
>
> This is the rule that I believe is causing the issue.
>
> *rule* "My Rule"
>     *salience* 50
>     *dialect* "java"
>     *no-loop* *true*
>     *when*
>         $module : Module( selected == *false*, required > 1, $size :
> required )
>         $list : ArrayList( )
>                 *from* *accumulate*( PotentialMatch( module == $module,
> $slot : slot ),
>                     init( List result = *new* ArrayList(); ),
>                     action( result.add($slot); ),
>                     reverse( result.remove((Integer)$slot ); ),
>                     result( result ) )
>         *eval*( countThem($list, $size) != $module.setMatchCount() )
>     *then*
>         *modify*( $module ) { setMatchCount(countThem($list, $size)) };
> *end*
>
> As I'm typing this I realize that there is another way to write this rule
> using collect.  I'm not sure why it was written this way, but since I have
> already come this far, has anyone had any experience with the Drools 4
> generated code throwing ClassCastExceptions?
>
> Thanks,
>
> Steve Ronderos
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
>


-- 
 Edson Tirelli
 JBoss Drools Core Development
 JBoss by Red Hat @ www.jboss.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20090623/59f6eabf/attachment.html 


More information about the rules-users mailing list