[rules-users] The effect of not using shadow facts
Chris West
crayzfishr at gmail.com
Fri Jul 20 09:40:42 EDT 2007
Edson,
It appears that revision #13637 of drools breaks the ability for me to use
one of my existing classes. The attached eclipse project illustrates the
problem. This test works on 4.0.0MR3, but not revision #13637. The
exception is:
org.drools.spi.ConsequenceException: org.drools.RuntimeDroolsException:
Error creating shadow fact for object: NamedList(Hello List): [1, 2, 3]
at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java
:549)
at org.drools.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:509)
at org.drools.common.AbstractWorkingMemory.fireAllRules(
AbstractWorkingMemory.java:430)
at org.drools.common.AbstractWorkingMemory.fireAllRules(
AbstractWorkingMemory.java:392)
at com.sample.DroolsTest.main(DroolsTest.java:29)
Caused by: org.drools.RuntimeDroolsException: Error creating shadow fact for
object: NamedList(Hello List): [1, 2, 3]
at org.drools.reteoo.Rete$ObjectTypeConf.getShadow(Rete.java:458)
at org.drools.reteoo.Rete.assertObject(Rete.java:157)
at org.drools.reteoo.ReteooRuleBase.assertObject(ReteooRuleBase.java
:190)
at org.drools.reteoo.ReteooWorkingMemory.doInsert(
ReteooWorkingMemory.java:70)
at org.drools.common.AbstractWorkingMemory.insert(
AbstractWorkingMemory.java:848)
at org.drools.common.AbstractWorkingMemory.insert(
AbstractWorkingMemory.java:822)
at org.drools.base.DefaultKnowledgeHelper.insert(
DefaultKnowledgeHelper.java:60)
at org.drools.base.DefaultKnowledgeHelper.insert(
DefaultKnowledgeHelper.java:54)
at com.sample.Rule_Insert_named_list_0.consequence
(Rule_Insert_named_list_0.java:7)
at com.sample.Rule_Insert_named_list_0ConsequenceInvoker.evaluate
(Rule_Insert_named_list_0ConsequenceInvoker.java:19)
at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java
:545)
... 4 more
Caused by: java.lang.NullPointerException
at java.util.ArrayList.ensureCapacity(ArrayList.java:163)
at java.util.ArrayList.addAll(ArrayList.java:475)
at com.sample.NamedListShadowProxy.updateProxy(Unknown Source)
at com.sample.NamedListShadowProxy.setShadowedObject(Unknown Source)
at org.drools.reteoo.Rete$ObjectTypeConf.getShadow(Rete.java:456)
... 14 more
The insert works if you modify my NamedList class to have a no arg
constructor, but the class misbehaves in my rule set (as if shadow is not
working properly).
Please take a look.
Thanks,
-Chris West
On 7/19/07, Edson Tirelli <tirelli at post.com> wrote:
>
>
> Ouch!
> Is all that trouble a result of using JDK proxies in drools? If it is,
> I think it is the case of us developing a whole set of unit and integration
> tests for this specific scenario, since none of our tests are triggering
> errors...
>
> Thanks and please keep me posted of your progress or any problems you
> find.
>
> []s
> Edson
>
> 2007/7/19, Chris West <crayzfishr at gmail.com >:
> >
> > Edson,
> >
> > Thanks for incorporating this fix. The good news is that it fixes that
> > problem.
> >
> > The bad news for me is that I'm now experiencing a different problem
> > (where my rules are not firing). I'll look into my new problem a little
> > deeper.
> >
> > Thanks again.
> > -Chris West
> >
> > On 7/19/07, Edson Tirelli < tirelli at post.com> wrote:
> > >
> > >
> > > Chris,
> > >
> > > Right on the spot. I changed other references, but this one passed
> > > unnoticed. The correct is:
> > >
> > > Class cls = null;
> > > if ( object instanceof ShadowProxy ) {
> > > cls =
> > > ((ShadowProxy)object).getShadowedObject().getClass();
> > > } else {
> > > cls = object.getClass();
> > > }
> > >
> > > I made a text search this time and found no other occurence of this
> > > problem.
> > > I commited the fix in revision #13637. Take a look and let me know
> > > if you still has problems.
> > >
> > > Thank you a lot,
> > > Edson
> > >
> > > 2007/7/19, Chris West < crayzfishr at gmail.com>:
> > > >
> > > > Edson,
> > > >
> > > > I think I've discovered the problem. In the file Rete.java, in the
> > > > method "assertObject", there is a check for shadow proxy like below:
> > > >
> > > > Class cls = object.getClass();
> > > > if ( object instanceof ShadowProxy ) {
> > > > cls = cls.getSuperclass();
> > > > }
> > > >
> > > > If the class being proxied was final, and your new logic chose an
> > > > interface of that class to build a proxy from, then the superclass is
> > > > Object.class.
> > > >
> > > > This leads to an incorrect selection of cachedNodes further down in
> > > > the method.
> > > >
> > > > I've traced this through the debugger with my object types, and it
> > > > does show that a node for a SortieStatus is being given an object of type
> > > > LaunchRecoveryStatusShadowProxy, which is not compatible.
> > > >
> > > > Perhaps theres a different way to determine the type of object such
> > > > that type LaunchRecoveryStatusShadowProxy will return LaunchRecoveryStatus
> > > > rather than Object.
> > > >
> > > > Please take a look and let me know if I need to provide more info.
> > > >
> > > > Thanks,
> > > > -Chris West
> > > >
> > > > On 7/18/07, Edson Tirelli < tirelli at post.com> wrote:
> > > > >
> > > > >
> > > > > Chris,
> > > > >
> > > > > What seems to be happening us that your SortieStatus interface
> > > > > has a state attribute. Drools is trying to read this attribute value and
> > > > > cast it to LaunchRecoveryStatusShadowProxy what is causing the
> > > > > problems...
> > > > > Best way to solve would be to have the code so I can debug. Is
> > > > > it possible to isolate it and send me?
> > > > >
> > > > > []s
> > > > > Edson
> > > > >
> > > > >
> > > > >
> > > > > 2007/7/18, Chris West < crayzfishr at gmail.com>:
> > > > > >
> > > > > > Edson,
> > > > > >
> > > > > > It is certainly possible to create a JDK proxy with only some of
> > > > > > the interfaces that are present on the delegate object that you are
> > > > > > proxying, but in my case, my proxies have all the interfaces of the
> > > > > > underlying object.
> > > > > >
> > > > > > The top two lines of the call stack I sent shows the following:
> > > > > >
> > > > > > Exception in thread "main" java.lang.ClassCastException:
> > > > > > ascc.status.FlightOpsStatusBoard$LaunchRecoveryStatusShadowProxy
> > > > > > at
> > > > > > org.drools.base.ascc.status.AirPlanStatusBoard$SortieStatus$getState.getValue(Unknown
> > > > > > Source)
> > > > > >
> > > > > > What's strange here is that the ClassCastException seems to be
> > > > > > caused by casting an object of type SortieStatus to type
> > > > > > LaunchRecoveryStatusShadowProxy, if I'm reading that right. The types
> > > > > > SortieStatus and LaunchRecoveryStatus are both interfaces in my code, and
> > > > > > they never appear on the same fact object (so no SortieStatus will ever be a
> > > > > > LaunchRecoveryStatus and vice-versa). So I'm wondering why the cast is
> > > > > > occuring, since it is not possible to work.
> > > > > >
> > > > > > The unfortunate part is I cannot see into the class where the
> > > > > > cast is occurring, as it is a generated class created by drools.
> > > > > >
> > > > > > -Chris West
> > > > > >
> > > > > > On 7/18/07, Edson Tirelli <tirelli at post.com> wrote:
> > > > > > >
> > > > > > >
> > > > > > > Chris,
> > > > > > >
> > > > > > > For the solution to work, it is important that a
> > > > > > > superclass or interface matches all the ObjectTypes in your rulebase that
> > > > > > > your final class (proxy) matches... I guess that is the case with JDK
> > > > > > > proxies, isn't it?
> > > > > > >
> > > > > > > []s
> > > > > > > Edson
> > > > > > >
> > > > > > > 2007/7/18, Chris West <crayzfishr at gmail.com >:
> > > > > > > >
> > > > > > > > Edson,
> > > > > > > >
> > > > > > > > I downloaded and built the latest from the trunk of the
> > > > > > > > repository. I applied this new build toward my test case, and it seemed to
> > > > > > > > fix the problem. However, when I applied it to my real project, it still
> > > > > > > > exhibits the problem. If I discover more information about the problem I'll
> > > > > > > > let you know.
> > > > > > > >
> > > > > > > > Thanks,
> > > > > > > > Chris West
> > > > > > > >
> > > > > > > > On 7/17/07, Edson Tirelli < tirelli at post.com> wrote:
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > Chris,
> > > > > > > > >
> > > > > > > > > I found and developed an intermediate solution that
> > > > > > > > > shall work for your proxies.
> > > > > > > > > If it is not possible to create a shadow fact for a
> > > > > > > > > class that is asserted (because the class is final or whatever), the engine
> > > > > > > > > goes up in the class hierarchy, looking for a class or interface for which
> > > > > > > > > is possible to create the proxy, but that still matches all ObjectTypes
> > > > > > > > > available in the rule base matched by the original class. The analysis is a
> > > > > > > > > bit complex, specially because new rules with new object types can be
> > > > > > > > > dynamically added to the rule base, but I believe the solution will work for
> > > > > > > > > JDK proxies and the most common proxy frameworks out there, that usually
> > > > > > > > > don't proxy multiple unrelated interfaces at once.
> > > > > > > > >
> > > > > > > > > So, I ask you please to get latest snapshot from the
> > > > > > > > > repository and try it out for your use case and report back to the list the
> > > > > > > > > results, since seems there are a few other people using similar things.
> > > > > > > > >
> > > > > > > > > Thanks,
> > > > > > > > > Edson
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > 2007/7/17, Chris West < crayzfishr at gmail.com>:
> > > > > > > > > >
> > > > > > > > > > Is that still true if the equals() and hashcode()
> > > > > > > > > > methods are only based on the identity fields of the object (which cannot
> > > > > > > > > > change)?
> > > > > > > > > >
> > > > > > > > > > -Chris West
> > > > > > > > > >
> > > > > > > > > > On 7/17/07, Mark Proctor <mproctor at codehaus.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > > you only need to use modifyRetract if the object is
> > > > > > > > > > > inserted. The reason for this is if you change field values on your facts we
> > > > > > > > > > > will not be able to remove them from our various internal hashmaps; thus the
> > > > > > > > > > > need to remove first prior to any changes, then make the changes and then
> > > > > > > > > > > insert it again. We can't allow users to just call update() as we have no
> > > > > > > > > > > idea what the old values where, thus we cannot find the objects in our
> > > > > > > > > > > hashmaps.
> > > > > > > > > > >
> > > > > > > > > > > Mark
> > > > > > > > > > > Chris West wrote:
> > > > > > > > > > >
> > > > > > > > > > > Mark,
> > > > > > > > > > >
> > > > > > > > > > > Using modifyRetract and modifyInsert seems to fix the
> > > > > > > > > > > problem (at least in my test case I finally created). I'll try this on my
> > > > > > > > > > > real code.
> > > > > > > > > > >
> > > > > > > > > > > My only concern here is that it puts the burden on the
> > > > > > > > > > > rule author to know whether things are being shadowed or not. For shadowing
> > > > > > > > > > > that is explicitly turned off this is ok. But for implicit non-shadowing
> > > > > > > > > > > based on a class being final, this is not at all obvious to the rule auther.
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > Is there any way to have this hidden such that I can
> > > > > > > > > > > still call "update" but have it use "modifyRetract" and "modifyInsert"
> > > > > > > > > > > instead?
> > > > > > > > > > >
> > > > > > > > > > > Also, I'm curious why I have to call modifyRetract
> > > > > > > > > > > before I start modifing the object, since the engine does not know about my
> > > > > > > > > > > modifications anyway until I call update or modifyInsert? By the way, I was
> > > > > > > > > > > unable to use the block setter approach in the rule consequence due to not
> > > > > > > > > > > having set methods for modifying my objects.
> > > > > > > > > > >
> > > > > > > > > > > Thanks,
> > > > > > > > > > > -Chris West
> > > > > > > > > > >
> > > > > > > > > > > On 7/17/07, Mark Proctor <mproctor at codehaus.org >
> > > > > > > > > > > wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > If you do not have shadow facts you cannot use the
> > > > > > > > > > > > update() method, it will leave the working memory corrupted. Instead you
> > > > > > > > > > > > must manage this yourself, before you change any values on the object you
> > > > > > > > > > > > must call modifyRetract() and after you hvae finished your changes ot hte
> > > > > > > > > > > > object call modifyInsert() - luckily if you are doing this in the
> > > > > > > > > > > > consequence you can use the MVEL modify keyword combined with the block
> > > > > > > > > > > > setter and it does this for you:
> > > > > > > > > > > > modify ( person ) { age += 1, location = "london" }
> > > > > > > > > > > >
> > > > > > > > > > > > Mark
> > > > > > > > > > > > Chris West wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > Hello,
> > > > > > > > > > > >
> > > > > > > > > > > > With prior versions of JBoss Rules (3.0.5) I have
> > > > > > > > > > > > been using JDK generated dynamic proxies as facts, and they have been
> > > > > > > > > > > > working fine. However, after upgrading to JBoss Rules
> > > > > > > > > > > > 4.0.0MR3, I cannot seem to get the dynamic proxies
> > > > > > > > > > > > to work as facts. It seems that even though a rule fires that changes a
> > > > > > > > > > > > field on the proxy, a second rule that should not be activated after the
> > > > > > > > > > > > update still fires.
> > > > > > > > > > > >
> > > > > > > > > > > > According to the JDK javadoc documentation, dynamic
> > > > > > > > > > > > proxies are created as final. My assumption is that JBoss Rules is not
> > > > > > > > > > > > creating Shadow facts for these since they are final. After reading the
> > > > > > > > > > > > JIRA at
> > > > > > > > > > > > http://jira.jboss.com/jira/browse/JBRULES-960, I now
> > > > > > > > > > > > am questioning what the effect of not using shadow facts is on the engine.
> > > > > > > > > > > > The relevant part of that is:
> > > > > > > > > > > >
> > > > > > > > > > > > "The problem is that SpringAOP is generating a proxy
> > > > > > > > > > > > whose methods equals() and hashCode() are "final". As drools must either
> > > > > > > > > > > > override these methods in the shadow proxy or not shadow the fact at all,
> > > > > > > > > > > > I'm disabling shadow proxy generation for this use case.
> > > > > > > > > > > > It is really important to note that if you are
> > > > > > > > > > > > asserting SpringAOP proxies as facts into the working memory, you will not
> > > > > > > > > > > > be able to change any field value whose field is constrained in rules or you
> > > > > > > > > > > > may incur in a memory leak and non-deterministic behavior by the rules
> > > > > > > > > > > > engine. Unfortunately there is nothing we can do about, since when SpringAOP
> > > > > > > > > > > > makes the methods equals and hashcode final, we can't override them anymore
> > > > > > > > > > > > and as so, we can't shadow them."
> > > > > > > > > > > > [ Show »<http://jira.jboss.com/jira/browse/JBRULES-960>]
> > > > > > > > > > > > Edson Tirelli<http://jira.jboss.com/jira/secure/ViewProfile.jspa?name=tirelli>
> > > > > > > > > > > > [02/Jul/07 03:29 PM] The problem is that SpringAOP
> > > > > > > > > > > > is generating a proxy whose methods equals() and hashCode() are "final". As
> > > > > > > > > > > > drools must either override these methods in the shadow proxy or not shadow
> > > > > > > > > > > > the fact at all, I'm disabling shadow proxy generation for this use case. It
> > > > > > > > > > > > is really important to note that if you are asserting SpringAOP proxies as
> > > > > > > > > > > > facts into the working memory, you will not be able to change any field
> > > > > > > > > > > > value whose field is constrained in rules or you may incur in a memory leak
> > > > > > > > > > > > and non-deterministic behavior by the rules engine. Unfortunately there is
> > > > > > > > > > > > nothing we can do about, since when SpringAOP makes the methods equals and
> > > > > > > > > > > > hashcode final, we can't override them anymore and as so, we can't shadow
> > > > > > > > > > > > them.
> > > > > > > > > > > >
> > > > > > > > > > > > Although I'm not using SpringAOP, I believe my facts
> > > > > > > > > > > > are not being shadowed.
> > > > > > > > > > > >
> > > > > > > > > > > > Is it true that not using shadow facts may lead to
> > > > > > > > > > > > non-deterministic behavior? Prior to shadow facts, the engine seemed to
> > > > > > > > > > > > handle it. Any chance of reverting back to the old style of truth
> > > > > > > > > > > > maintenance in the case of not using shadow facts.
> > > > > > > > > > > >
> > > > > > > > > > > > I apologize if I'm not on the right track here. My
> > > > > > > > > > > > only test case for my problem is the entire application right now, so I
> > > > > > > > > > > > cannot offer it for discussion. Any advice would be greatly appreciated.
> > > > > > > > > > > >
> > > > > > > > > > > > Thanks,
> > > > > > > > > > > > -Chris West
> > > > > > > > > > > >
> > > > > > > > > > > > ------------------------------
> > > > > > > > > > > >
> > > > > > > > > > > > _______________________________________________
> > > > > > > > > > > > rules-users mailing list
> > > > > > > > > > > > rules-users at lists.jboss.org
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > https://lists.jboss.org/mailman/listinfo/rules-users
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > _______________________________________________
> > > > > > > > > > > > rules-users mailing list
> > > > > > > > > > > > rules-users at lists.jboss.org
> > > > > > > > > > > > https://lists.jboss.org/mailman/listinfo/rules-users
> > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > ------------------------------
> > > > > > > > > > >
> > > > > > > > > > > _______________________________________________
> > > > > > > > > > > rules-users mailing list
> > > > > > > > > > > rules-users at lists.jboss.org
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > https://lists.jboss.org/mailman/listinfo/rules-users
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > _______________________________________________
> > > > > > > > > > > rules-users mailing list
> > > > > > > > > > > rules-users at lists.jboss.org
> > > > > > > > > > > https://lists.jboss.org/mailman/listinfo/rules-users
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > _______________________________________________
> > > > > > > > > > rules-users mailing list
> > > > > > > > > > rules-users at lists.jboss.org
> > > > > > > > > > https://lists.jboss.org/mailman/listinfo/rules-users
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > --
> > > > > > > > > Edson Tirelli
> > > > > > > > > Software Engineer - JBoss Rules Core Developer
> > > > > > > > > Office: +55 11 3529-6000
> > > > > > > > > Mobile: +55 11 9287-5646
> > > > > > > > > JBoss, a division of Red Hat @ www.jboss.com
> > > > > > > > >
> > > > > > > > > _______________________________________________
> > > > > > > > > rules-users mailing list
> > > > > > > > > rules-users at lists.jboss.org
> > > > > > > > > https://lists.jboss.org/mailman/listinfo/rules-users
> > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > > > _______________________________________________
> > > > > > > > rules-users mailing list
> > > > > > > > rules-users at lists.jboss.org
> > > > > > > > https://lists.jboss.org/mailman/listinfo/rules-users
> > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > --
> > > > > > > Edson Tirelli
> > > > > > > Software Engineer - JBoss Rules Core Developer
> > > > > > > Office: +55 11 3529-6000
> > > > > > > Mobile: +55 11 9287-5646
> > > > > > > JBoss, a division of Red Hat @ www.jboss.com
> > > > > > >
> > > > > > > _______________________________________________
> > > > > > > rules-users mailing list
> > > > > > > rules-users at lists.jboss.org
> > > > > > > https://lists.jboss.org/mailman/listinfo/rules-users
> > > > > > >
> > > > > > >
> > > > > >
> > > > > > _______________________________________________
> > > > > > rules-users mailing list
> > > > > > rules-users at lists.jboss.org
> > > > > > https://lists.jboss.org/mailman/listinfo/rules-users
> > > > > >
> > > > > >
> > > > >
> > > > >
> > > > > --
> > > > > Edson Tirelli
> > > > > Software Engineer - JBoss Rules Core Developer
> > > > > Office: +55 11 3529-6000
> > > > > Mobile: +55 11 9287-5646
> > > > > JBoss, a division of Red Hat @ www.jboss.com
> > > > >
> > > > > _______________________________________________
> > > > > rules-users mailing list
> > > > > rules-users at lists.jboss.org
> > > > > https://lists.jboss.org/mailman/listinfo/rules-users
> > > > >
> > > > >
> > > >
> > > > _______________________________________________
> > > > rules-users mailing list
> > > > rules-users at lists.jboss.org
> > > > https://lists.jboss.org/mailman/listinfo/rules-users
> > > >
> > > >
> > >
> > >
> > > --
> > > Edson Tirelli
> > > Software Engineer - JBoss Rules Core Developer
> > > Office: +55 11 3529-6000
> > > Mobile: +55 11 9287-5646
> > > JBoss, a division of Red Hat @ www.jboss.com
> > >
> > > _______________________________________________
> > > rules-users mailing list
> > > rules-users at lists.jboss.org
> > > https://lists.jboss.org/mailman/listinfo/rules-users
> > >
> > >
> >
> > _______________________________________________
> > rules-users mailing list
> > rules-users at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/rules-users
> >
> >
>
>
> --
> Edson Tirelli
> Software Engineer - JBoss Rules Core Developer
> Office: +55 11 3529-6000
> Mobile: +55 11 9287-5646
> JBoss, a division of Red Hat @ www.jboss.com
>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20070720/e1ba302c/attachment.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.zip
Type: application/zip
Size: 9658 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/rules-users/attachments/20070720/e1ba302c/attachment.zip
More information about the rules-users
mailing list