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 <[EMAIL PROTECTED]>: > > On Feb 20, 2008 9:23 AM, Edson Tirelli <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]>: > > > 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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]>: > > > > > > > > > > > > > > > > > > > > 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$SingletonMapShadowProxycannot > > > > > 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@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@lists.jboss.org > > > > https://lists.jboss.org/mailman/listinfo/rules-users > > > > > > > > > > > _______________________________________________ > > > rules-users mailing list > > > rules-users@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@lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/rules-users > > > > > _______________________________________________ > rules-users mailing list > rules-users@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@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users