Edson,
Thanks for the quick response!
I'm using Drools 4.0.7 and mvel 1.3.1
Thanks for the tip about packages and rulebases. I'll make sure to change
that in our code.
As far as changing the accumulate to collect, I can easily work around
that selector returning a list of PotentialMatches instead of Integers. I
made that change and have been unable to create the ClassCastException
since. I'm still not certain that the problem is resolved due to its
random nature, but I'm hoping that it is patched enough for now until we
can make the rulebase change you mentioned.
Thanks for the info about Drools 5. I'm currently in the process of
converting to Drools 5.
You're right the eval does look odd, but it is working for the time being.
This rule is in one of the first features I implemented using Drools, so
it is probably not done in the best way possible. I'll keep an eye on it
if I do not get this issue resolved some other way.
Thanks again!
Steve Ronderos
rules-users-bounces(a)lists.jboss.org wrote on 06/23/2009 11:09:48 AM:
[image removed]
Re: [rules-users] Class Cast Exception in Drools 4 Generated
Accumulate Method
Edson Tirelli
to:
Rules Users List
06/23/2009 11:29 AM
Sent by:
rules-users-bounces(a)lists.jboss.org
Please respond to Rules Users List
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(a)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(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
--
Edson Tirelli
JBoss Drools Core Development
JBoss by Red Hat @
www.jboss.com
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users