<br>&nbsp;&nbsp; Ok, let me show one example. Imagine the class Person, with 2 attributes (name and age) and the corresponding getter/setters.<br>&nbsp;&nbsp; What are the data for that fact that must be shadowed? easy answer: just shadow all getXXX() methods (getName and getAge).<br>
&nbsp;<br>&nbsp;&nbsp; Now, take a Map. What is the data that must be shadowed?<br><br>&nbsp;&nbsp; So, we do our best to work with facts that don&#39;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.<br>
<br>&nbsp;&nbsp; []s<br>&nbsp;&nbsp; Edson<br><br><div><span class="gmail_quote">2008/2/20, Godmar Back &lt;<a href="mailto:godmar@gmail.com">godmar@gmail.com</a>&gt;:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
On Feb 20, 2008 9:23 AM, Edson Tirelli &lt;<a href="mailto:tirelli@post.com">tirelli@post.com</a>&gt; wrote:<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;Godmar,<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;Short answer: collection/maps objects are not javabeans.<br>&gt;<br>
<br>Explain why this is a problem.<br><br>What is it about JavaBeans that your algorithm relies upon?&nbsp;&nbsp;Is it the<br>fact that the set of properties remains fixed and can be determined at<br>(fact) insertion time via reflection?<br>
<br>Otherwise, I do not see any conceptual difference between a map and a bean.<br>If that is the difference, then please allow maps with an immutable key set.<br><br> - Godmar<br><br><br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;Long answer: collection/maps must be shadowed to ensure consistency<br>
&gt; during execution, but how can we shadow the data if it is not exposed in a<br>&gt; default, spec manner, as in javabeans? The algorithm we have in place right<br>&gt; now is bellow. As you can see, it is a weak algo, but was the best I could<br>
&gt; come up at that time. If you have any suggestions on how to improve that, I<br>&gt; appreciate.<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; public Object getShadow(final Object fact) throws RuntimeDroolsException<br>&gt; {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ShadowProxy proxy = null;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( isShadowEnabled() ) {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( Collection.class.isAssignableFrom( this.shadowClass )<br>&gt; || Map.class.isAssignableFrom( this.shadowClass ) ) {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// if it is a collection, try to instantiate using<br>
&gt; constructor<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy = (ShadowProxy)<br>&gt; this.shadowClass.getConstructor( new Class[]{cls} ).newInstance( new<br>&gt; Object[]{fact} );<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch ( Exception e ) {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // not possible to instantiate using constructor<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( proxy == null ) {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( this.instantiator == null ) {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.setInstantiator();<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy = (ShadowProxy) this.instantiator.newInstance();<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy.setShadowedObject( fact );<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch ( final Exception e ) {<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println( &quot;shadow: &quot; +proxy.getClass() + &quot;:&quot; +<br>&gt; fact.getClass() );<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new RuntimeDroolsException( &quot;Error creating shadow<br>
&gt; fact for object: &quot; + fact,<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e );<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return proxy;<br>&gt;<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[]s<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Edson<br>&gt;<br>&gt; 2008/2/19, Godmar Back &lt;<a href="mailto:godmar@gmail.com">godmar@gmail.com</a>&gt;:<br>&gt; &gt; As a general comment, the examples for which I find Drools failing are<br>&gt; &gt; not the actual examples for which my application is failing. It&#39;s just<br>
&gt; &gt; the smallest test case I was able to eliminate.<br>&gt; &gt;<br>&gt; &gt; I&#39;m now a bit concerned about your comment that Maps and Collections<br>&gt; &gt; aren&#39;t well-defined as Facts. I am planning to make extensive use of<br>
&gt; &gt; them (that&#39;s also why I&#39;d prefer to use the MVEL dialect, because in<br>&gt; &gt; Java I cannot do this without creating Bean wrappers.)<br>&gt; &gt;<br>&gt; &gt; Could you elaborate what makes the semantics not &quot;well-defined&quot;.<br>
&gt; &gt;<br>&gt; &gt; I&#39;m specifically concerned with immutable maps (such as the one that<br>&gt; &gt; would have been returned by Collections.singletonMap), and with<br>&gt; &gt; collections of maps (such as those obtained via a &quot;from&quot;...&quot; clause).<br>
&gt; &gt; I need to insert immutable maps as facts; I understand that the items<br>&gt; &gt; returned by &quot;from&quot; aren&#39;t inserted as facts.<br>&gt; &gt;<br>&gt; &gt; - Godmar<br>&gt; &gt;<br>&gt; &gt; On Feb 19, 2008 3:11 PM, Edson Tirelli &lt;<a href="mailto:tirelli@post.com">tirelli@post.com</a>&gt; wrote:<br>
&gt; &gt; &gt;<br>&gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;Drools tries to create the ShadowProxy. The reason is that it does<br>&gt; not<br>&gt; &gt; &gt; know about the implementation... it just knows it is a Map and as so, it<br>&gt; &gt; &gt; must be shadowed. Problem is that SingletonMap is either&nbsp;&nbsp;final or does<br>
&gt; not<br>&gt; &gt; &gt; have a default constructor.<br>&gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp; My recommendation, besides opening a JIRA for this, is avoid<br>&gt; inserting<br>&gt; &gt; &gt; collections/maps directly as facts. The semantic for such facts is not<br>
&gt; &gt; &gt; clearly defined and it may cause undesired behavior.<br>&gt; &gt; &gt;<br>&gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;[]s<br>&gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;Edson<br>&gt; &gt; &gt;<br>&gt; &gt; &gt; 2008/2/19, Godmar Back &lt;<a href="mailto:godmar@gmail.com">godmar@gmail.com</a>&gt;:<br>
&gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; Hi,<br>&gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; usings Drools 4.0.4 and MVEL 1.4, this simple rule:<br>&gt; &gt; &gt; &gt; ---<br>
&gt; &gt; &gt; &gt; package test;<br>&gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; import java.util.Collections;<br>&gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; dialect &quot;mvel&quot;<br>&gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; rule &quot;Rule #1&quot;<br>
&gt; &gt; &gt; &gt; when<br>&gt; &gt; &gt; &gt; then<br>&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp; insert(Collections.singletonMap(&quot;content&quot;, &quot;hello&quot;));<br>&gt; &gt; &gt; &gt; end<br>&gt; &gt; &gt; &gt; --<br>&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; produces:<br>&gt; &gt; &gt; &gt; java.lang.IllegalAccessError: class<br>&gt; &gt; &gt; &gt; org.drools.shadow.java.util.Collections$SingletonMapShadowProxy cannot<br>&gt; &gt; &gt; &gt; access its superclass java.util.Collections$SingletonMap<br>
&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at java.lang.ClassLoader.defineClass1(Native Method)<br>&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at java.lang.ClassLoader.defineClass(ClassLoader.java:620)<br>&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at<br>&gt; &gt; &gt;<br>
&gt; org.drools.rule.MapBackedClassLoader.fastFindClass(MapBackedClassLoader.java:60)<br>&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at<br>&gt; &gt; &gt;<br>&gt; org.drools.rule.MapBackedClassLoader.loadClass(MapBackedClassLoader.java:79)<br>
&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at java.lang.ClassLoader.loadClass(ClassLoader.java:251)<br>&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at<br>&gt; &gt; &gt;<br>&gt; org.drools.reteoo.Rete$ClassObjectTypeConf.loadOrGenerateProxy(Rete.java:547)<br>
&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at<br>&gt; &gt; &gt;<br>&gt; org.drools.reteoo.Rete$ClassObjectTypeConf.defineShadowProxyData(Rete.java:494)<br>&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at<br>&gt; &gt; &gt; org.drools.reteoo.Rete$ClassObjectTypeConf.&lt;init&gt;(Rete.java:461)<br>
&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at org.drools.reteoo.Rete.assertObject(Rete.java:152)<br>&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at<br>&gt; &gt; &gt; org.drools.reteoo.ReteooRuleBase.assertObject(ReteooRuleBase.java:192)<br>&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at<br>
&gt; &gt; &gt;<br>&gt; org.drools.reteoo.ReteooWorkingMemory.doInsert(ReteooWorkingMemory.java:71)<br>&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at<br>&gt; &gt; &gt;<br>&gt; org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:909)<br>
&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at<br>&gt; &gt; &gt;<br>&gt; org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:881)<br>&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at<br>&gt; &gt; &gt;<br>&gt; org.drools.base.DefaultKnowledgeHelper.insert(DefaultKnowledgeHelper.java:67)<br>
&gt; &gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at<br>&gt; &gt; &gt;<br>&gt; org.drools.base.DefaultKnowledgeHelper.insert(DefaultKnowledgeHelper.java:61)<br>&gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; It&#39;s not clear to me why Drools creates Proxies for such classes as<br>
&gt; &gt; &gt; &gt; java.util.Collections, or does MVEL do it?<br>&gt; &gt; &gt; &gt;<br>&gt; &gt; &gt; &gt; - Godmar<br>&gt; &gt; &gt; &gt; _______________________________________________<br>&gt; &gt; &gt; &gt; rules-users mailing list<br>
&gt; &gt; &gt; &gt; <a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>&gt; &gt; &gt; &gt; <a href="https://lists.jboss.org/mailman/listinfo/rules-users">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
&gt; &gt; &gt; &gt;<br>&gt; &gt; &gt;<br>&gt; &gt; &gt;<br>&gt; &gt; &gt;<br>&gt; &gt; &gt; --<br>&gt; &gt; &gt;&nbsp;&nbsp; Edson Tirelli<br>&gt; &gt; &gt;&nbsp;&nbsp; JBoss Drools Core Development<br>&gt; &gt; &gt;&nbsp;&nbsp;&nbsp;&nbsp;Office: +55 11 3529-6000<br>
&gt; &gt; &gt;&nbsp;&nbsp; Mobile: +55 11 9287-5646<br>&gt; &gt; &gt;&nbsp;&nbsp; JBoss, a division of Red Hat @ <a href="http://www.jboss.com">www.jboss.com</a><br>&gt; &gt; &gt; _______________________________________________<br>&gt; &gt; &gt; rules-users mailing list<br>
&gt; &gt; &gt; <a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>&gt; &gt; &gt; <a href="https://lists.jboss.org/mailman/listinfo/rules-users">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
&gt; &gt; &gt;<br>&gt; &gt; &gt;<br>&gt; &gt; _______________________________________________<br>&gt; &gt; rules-users mailing list<br>&gt; &gt; <a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>
&gt; &gt; <a href="https://lists.jboss.org/mailman/listinfo/rules-users">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>&gt; &gt;<br>&gt;<br>&gt;<br>&gt;<br>&gt; --<br>&gt;&nbsp;&nbsp; Edson Tirelli<br>&gt;&nbsp;&nbsp; JBoss Drools Core Development<br>
&gt;&nbsp;&nbsp; Office: +55 11 3529-6000<br>&gt;&nbsp;&nbsp; Mobile: +55 11 9287-5646<br>&gt;&nbsp;&nbsp; JBoss, a division of Red Hat @ <a href="http://www.jboss.com">www.jboss.com</a><br>&gt; _______________________________________________<br>&gt; rules-users mailing list<br>
&gt; <a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>&gt; <a href="https://lists.jboss.org/mailman/listinfo/rules-users">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>&gt;<br>
&gt;<br>_______________________________________________<br>rules-users mailing list<br><a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br><a href="https://lists.jboss.org/mailman/listinfo/rules-users">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
</blockquote></div><br><br clear="all"><br>-- <br>&nbsp;&nbsp;Edson Tirelli<br>&nbsp;&nbsp;JBoss Drools Core Development<br>&nbsp;&nbsp;Office: +55 11 3529-6000<br>&nbsp;&nbsp;Mobile: +55 11 9287-5646<br>&nbsp;&nbsp;JBoss, a division of Red Hat @ <a href="http://www.jboss.com">www.jboss.com</a>