[rules-users] IllegalAccessError in shadow classes

Godmar Back godmar at gmail.com
Wed Feb 20 12:53:38 EST 2008


On Feb 20, 2008 12:30 PM, Edson Tirelli <tirelli at post.com> wrote:
>
>    Godmar,
>
>    Shadow Facts are a necessary evil in current version. Basically what they
> do is keep the working memory consistent in face of attribute changes on the
> facts, that may happen both internally and externally to the working memory.
>     Our implementation to shadow facts is a lazy proxy that caches the
> values until a safe point to synchronize the actual attribute value with the
> one seen by the engine.
>
>    So, the question is: given an object:
>
> (Map) fact
>
>    How can we create an identical copy of it (shadow), if there is no
> "clone" operation?

Can you explain why you require the use of "clone()"?

Cloning a map is otherwise easy - it's also referred to as a "shallow
copy" -- HashMap's HashMap(Map) constructor will do it.
http://java.sun.com/j2se/1.4.2/docs/api/java/util/HashMap.html#HashMap(java.util.Map)
I know you know that, so explain what necessitates the use of clone().

> More than that, the shadow must be a subclass of it.

java.util.HashMap is a subclass of Map.

>
>    Most Collection and Map implementations have a single parameter
> constructor that allows us to do:
>
>
> proxy = (ShadowProxy) this.shadowClass.getConstructor( new Class[]{cls}
> ).newInstance( new Object[]{fact} );
>
>     But the SingletonMap you were using does not accept that constructor.
> So, one way is to explicit check if the fact is a SingletonMap and handle it
> accordingly, but that is a specific class hack... is there any general
> solution we can use?
>

Forget about the SingletonMap.  That was just one of the many things I
tried and failed.

Fundamentally, I would like Drools to process facts that were obtained
from real-world sources, and these facts have properties I do not know
in advance. Therefore, I cannot use beans (or using beans would be
highly inconvenient since it will require changes to Java code
whenever I'm referring to a new property, something I'd rather avoid.)

 - Godmar

>
>     []s
>     Edson
>
> 2008/2/20, Godmar Back <godmar at gmail.com>:
> > I don't really understand what you mean by "shadow".  What is the
> > purpose of such shadowing. Mark's email implies that it has to do with
> > concurrency protection; it's not clear what that means.
> >
> > In my view, whatever purpose you pursue with "shadowing", it does not
> > justify treating beans and maps differently.
> >
> > Your example of class Person shows that. If a person has two
> > attributes, name and age, then this is equivalent to a map with two
> > keys 'name' and 'age'.
> >
> > Here's the mapping:
> >
> > p.getName()    corresponds to m["name"]
> > p.getAge() corresponds to m["age"]
> >
> > and setName/setAge accordingly.
> >
> > Mathematically, a bean is an associative array with a fixed set of
> > keys (called "properties") that map to values. For all practical
> > purposes, that is the same as a map. There's no reason to treat them
> > differently. Wherever you'd do "getXXX()" with a bean you'd do
> > .get("XXX") with a map.
> >
> > - Godmar
> >
> > On Feb 20, 2008 11:25 AM, Edson Tirelli <tirelli at post.com> wrote:
> > >
> > >    Ok, let me show one example. Imagine the class Person, with 2
> attributes
> > > (name and age) and the corresponding getter/setters.
> > >    What are the data for that fact that must be shadowed? easy answer:
> just
> > > shadow all getXXX() methods (getName and getAge).
> > >
> > >    Now, take a Map. What is the data that must be shadowed?
> > >
> > >    So, we do our best to work with facts that don't follow the javabean
> > > spec, but collections and maps are a complicated beast. Again, if you
> have
> > > suggestions on how to improve the current support we provide for them,
> > > please share with us.
> > >
> > >    []s
> > >    Edson
> > >
> > > 2008/2/20, Godmar Back <godmar at gmail.com>:
> > >
> > > > On Feb 20, 2008 9:23 AM, Edson Tirelli <tirelli at post.com> wrote:
> > > > >
> > > > >    Godmar,
> > > > >
> > > > >    Short answer: collection/maps objects are not javabeans.
> > > > >
> > > >
> > > > Explain why this is a problem.
> > > >
> > > > What is it about JavaBeans that your algorithm relies upon?  Is it the
> > > > fact that the set of properties remains fixed and can be determined at
> > > > (fact) insertion time via reflection?
> > > >
> > > > Otherwise, I do not see any conceptual difference between a map and a
> > > bean.
> > > > If that is the difference, then please allow maps with an immutable
> key
> > > set.
> > > >
> > > > - Godmar
> > > >
> > > >
> > > > >    Long answer: collection/maps must be shadowed to ensure
> consistency
> > > > > during execution, but how can we shadow the data if it is not
> exposed in
> > > a
> > > > > default, spec manner, as in javabeans? The algorithm we have in
> place
> > > right
> > > > > now is bellow. As you can see, it is a weak algo, but was the best I
> > > could
> > > > > come up at that time. If you have any suggestions on how to improve
> > > that, I
> > > > > appreciate.
> > > > >
> > > > >     public Object getShadow(final Object fact) throws
> > > RuntimeDroolsException
> > > > > {
> > > > >         ShadowProxy proxy = null;
> > > > >         if ( isShadowEnabled() ) {
> > > > >             try {
> > > > >                 if ( Collection.class.isAssignableFrom(
> this.shadowClass
> > > )
> > > > > || Map.class.isAssignableFrom( this.shadowClass ) ) {
> > > > >                      // if it is a collection, try to instantiate
> using
> > > > > constructor
> > > > >                     try {
> > > > >                         proxy = (ShadowProxy)
> > > > > this.shadowClass.getConstructor( new Class[]{cls} ).newInstance( new
> > > > > Object[]{fact} );
> > > > >                      } catch ( Exception e ) {
> > > > >                         // not possible to instantiate using
> constructor
> > > > >                     }
> > > > >                 }
> > > > >                 if ( proxy == null ) {
> > > > >                     if ( this.instantiator == null ) {
> > > > >                          this.setInstantiator();
> > > > >                     }
> > > > >                     proxy = (ShadowProxy)
> > > this.instantiator.newInstance();
> > > > >                 }
> > > > >
> > > > >                 proxy.setShadowedObject( fact );
> > > > >              } catch ( final Exception e ) {
> > > > >                 System.out.println( "shadow: " +proxy.getClass() +
> ":" +
> > > > > fact.getClass() );
> > > > >                 throw new RuntimeDroolsException( "Error creating
> shadow
> > > > > fact for object: " + fact,
> > > > >                                                    e );
> > > > >             }
> > > > >         }
> > > > >         return proxy;
> > > > >
> > > > >
> > > > >     }
> > > > >
> > > > >      []s
> > > > >      Edson
> > > > >
> > > > > 2008/2/19, Godmar Back <godmar at gmail.com>:
> > > > > > As a general comment, the examples for which I find Drools failing
> are
> > > > > > not the actual examples for which my application is failing. It's
> just
> > > > > > the smallest test case I was able to eliminate.
> > > > > >
> > > > > > I'm now a bit concerned about your comment that Maps and
> Collections
> > > > > > aren't well-defined as Facts. I am planning to make extensive use
> of
> > > > > > them (that's also why I'd prefer to use the MVEL dialect, because
> in
> > > > > > Java I cannot do this without creating Bean wrappers.)
> > > > > >
> > > > > > Could you elaborate what makes the semantics not "well-defined".
> > > > > >
> > > > > > I'm specifically concerned with immutable maps (such as the one
> that
> > > > > > would have been returned by Collections.singletonMap), and with
> > > > > > collections of maps (such as those obtained via a "from"..."
> clause).
> > > > > > I need to insert immutable maps as facts; I understand that the
> items
> > > > > > returned by "from" aren't inserted as facts.
> > > > > >
> > > > > > - Godmar
> > > > > >
> > > > > > On Feb 19, 2008 3:11 PM, Edson Tirelli <tirelli at post.com> wrote:
> > > > > > >
> > > > > > >    Drools tries to create the ShadowProxy. The reason is that it
> > > does
> > > > > not
> > > > > > > know about the implementation... it just knows it is a Map and
> as
> > > so, it
> > > > > > > must be shadowed. Problem is that SingletonMap is either  final
> or
> > > does
> > > > > not
> > > > > > > have a default constructor.
> > > > > > >     My recommendation, besides opening a JIRA for this, is avoid
> > > > > inserting
> > > > > > > collections/maps directly as facts. The semantic for such facts
> is
> > > not
> > > > > > > clearly defined and it may cause undesired behavior.
> > > > > > >
> > > > > > >    []s
> > > > > > >    Edson
> > > > > > >
> > > > > > > 2008/2/19, Godmar Back <godmar at gmail.com>:
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > usings Drools 4.0.4 and MVEL 1.4, this simple rule:
> > > > > > > > ---
> > > > > > > > package test;
> > > > > > > >
> > > > > > > > import java.util.Collections;
> > > > > > > >
> > > > > > > > dialect "mvel"
> > > > > > > >
> > > > > > > > rule "Rule #1"
> > > > > > > > when
> > > > > > > > then
> > > > > > > >     insert(Collections.singletonMap("content", "hello"));
> > > > > > > > end
> > > > > > > > --
> > > > > > > >
> > > > > > > > produces:
> > > > > > > > java.lang.IllegalAccessError: class
> > > > > > > >
> org.drools.shadow.java.util.Collections$SingletonMapShadowProxy
> > > cannot
> > > > > > > > access its superclass java.util.Collections$SingletonMap
> > > > > > > >         at java.lang.ClassLoader.defineClass1(Native Method)
> > > > > > > >         at
> java.lang.ClassLoader.defineClass(ClassLoader.java:620)
> > > > > > > >         at
> > > > > > >
> > > > >
> > >
> org.drools.rule.MapBackedClassLoader.fastFindClass(MapBackedClassLoader.java:60)
> > > > > > > >         at
> > > > > > >
> > > > >
> > >
> org.drools.rule.MapBackedClassLoader.loadClass(MapBackedClassLoader.java:79)
> > > > > > > >         at
> java.lang.ClassLoader.loadClass(ClassLoader.java:251)
> > > > > > > >         at
> > > > > > >
> > > > >
> > >
> org.drools.reteoo.Rete$ClassObjectTypeConf.loadOrGenerateProxy(Rete.java:547)
> > > > > > > >         at
> > > > > > >
> > > > >
> > >
> org.drools.reteoo.Rete$ClassObjectTypeConf.defineShadowProxyData(Rete.java:494)
> > > > > > > >         at
> > > > > > > org.drools.reteoo.Rete$ClassObjectTypeConf.<init>(Rete.java:461)
> > > > > > > >         at org.drools.reteoo.Rete.assertObject(Rete.java:152)
> > > > > > > >         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:909)
> > > > > > > >         at
> > > > > > >
> > > > >
> > >
> org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:881)
> > > > > > > >         at
> > > > > > >
> > > > >
> > >
> org.drools.base.DefaultKnowledgeHelper.insert(DefaultKnowledgeHelper.java:67)
> > > > > > > >         at
> > > > > > >
> > > > >
> > >
> org.drools.base.DefaultKnowledgeHelper.insert(DefaultKnowledgeHelper.java:61)
> > > > > > > >
> > > > > > > >
> > > > > > > > It's not clear to me why Drools creates Proxies for such
> classes
> > > as
> > > > > > > > java.util.Collections, or does MVEL do it?
> > > > > > > >
> > > > > > > > - Godmar
> > > > > > > > _______________________________________________
> > > > > > > > rules-users mailing list
> > > > > > > > rules-users at lists.jboss.org
> > > > > > > > https://lists.jboss.org/mailman/listinfo/rules-users
> > > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > --
> > > > > > >   Edson Tirelli
> > > > > > >   JBoss Drools Core Development
> > > > > > >    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
> > > > >   JBoss Drools Core Development
> > > > >   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
> > >   JBoss Drools Core Development
> > >   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
>   JBoss Drools Core Development
>   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
>
>



More information about the rules-users mailing list