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@gmail.com>:
On Feb 20, 2008 9:23 AM, Edson Tirelli <tirelli@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@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
_______________________________________________
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