Godmar,
Short answer: collection/maps objects are not javabeans.
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@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@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@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@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