Failure to parse a 'from' expression

31 views
Skip to first unread message

Wolfgang Laun

unread,
Jan 4, 2017, 4:18:15 PM1/4/17
to drools...@googlegroups.com
In the following rule

rule comms when $conv: Convention() $comm: Comm() from (ArrayList)($conv.getComms()).get(Type.AAA) then

getComms returns a Map<Type,List<Comm>> but 6.4. and 6.5 fail to
 compile unless the cast to ArrayList is there.

Unable to Analyse Expression $conv.getComms().get( Type.AAA ):
sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot
 be cast to java.lang.Class : [Rule name='comms']

It has been reported that the code without the cast worked in 5.3.0. 
For testing, you can use String instead of Comm:

public class Convention {
private Map<Type,ArrayList<String>> comms = new HashMap<>();
public Map<Type,ArrayList<String>> getComms(){
return comms;
}
}

See also http://stackoverflow.com/questions/41461468

Happy New Year
Wolfgang




Mario Fusco

unread,
Jan 5, 2017, 2:45:07 AM1/5/17
to Drools Usage
Hi Wolfgang,

and happy new year.

Afaik we never inferred generics in those expressions and I believe that drools 5.x worked only because it was more forgiving and less strict in type analysis. Anyway I even don't know if the problem is in drools or in mvel at the moment. So let me try to quickly reproduce the problem locally and check what's going on. I'll keep you updated.

Thanks for having reported this,
Mario

--
You received this message because you are subscribed to the Google Groups "Drools Usage" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drools-usage+unsubscribe@googlegroups.com.
To post to this group, send email to drools...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/drools-usage/CANaj1LcLS2k8bUoKHOXQASTQx45x3nbsh4Y2CU55MRCUWi7zRA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Mario Fusco

unread,
Jan 5, 2017, 3:21:10 AM1/5/17
to Drools Usage
Hi again Wolfgang,

I properly reproduced the problem with the following test case and indeed it fails as you anticipated

public class Convention {
private final Map<String, List<String>> comms;

public Convention( Map<String, List<String>> comms ) {
this.comms = comms;
}

public Map<String, List<String>> getComms(){
return comms;
}
}

@Test
public void testGenericInference() {
// DROOLS-
String drl = "package com.sample\n" +
"import " + Convention.class.getCanonicalName() + ";\n" +
"global java.util.List list;\n" +
"rule R when\n" +
" $conv : Convention()\n" +
" $s : String() from $conv.getComms().get(\"test\")\n" +
"then\n" +
" list.add($s);" +
"end\n";


KieSession kSession = new KieHelper().addContent( drl, ResourceType.DRL ).build().newKieSession();

List<String> list = new ArrayList<String>();
kSession.setGlobal( "list", list );

Map<String, List<String>> comms = new HashMap<String, List<String>>();
comms.put("test", asList("result"));
kSession.insert( new Convention( comms ) );

kSession.fireAllRules();
assertEquals( 1, list.size() );
assertEquals( "result", list.get(0) );
}

However the interesting thing here is that just putting a couple of parenthesis around $conv.getComms() without adding any further explicit cast like in

"    $s : String() from ($conv.getComms()).get(\"test\")\n" +

is enough to fix the problem. Having noticed this another obvious way to workaround this issue is binding the map in the previous pattern like in

"    $conv : Convention( $comms : comms )\n" +
" $s : String() from $comms.get(\"test\")\n" +

Unfortunately the problem seems to be caused by mvel since the exception raised internally is the following:

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class
    at org.mvel2.compiler.PropertyVerifier.getMethod(PropertyVerifier.java:642)
    at org.mvel2.compiler.PropertyVerifier.analyze(PropertyVerifier.java:120)
    at org.mvel2.compiler.ExpressionCompiler.verify(ExpressionCompiler.java:373)
    at org.mvel2.compiler.ExpressionCompiler._compile(ExpressionCompiler.java:266)
    at org.mvel2.compiler.ExpressionCompiler.compile(ExpressionCompiler.java:52)
    at org.mvel2.MVEL.analyze(MVEL.java:680)
    at org.mvel2.MVEL.analyze(MVEL.java:685)
    at org.drools.compiler.rule.builder.dialect.mvel.MVELExprAnalyzer.analyzeExpression(MVELExprAnalyzer.java:214)
    at org.drools.compiler.rule.builder.dialect.mvel.MVELDialect.analyzeExpression(MVELDialect.java:510)

I'll try to reproduce and fix this issue inside mvel, but I cannot commit on when I'll have time to do this.

Will you add these further info to the StackOverflow question or do you want me to do that?

Regards,
Mario

Mario Fusco

unread,
Jan 5, 2017, 5:25:56 AM1/5/17
to Drools Usage
Wolfgang,

one last update: I've reproduced and fixed this issue inside mvel https://github.com/mvel/mvel/commit/5dc9fe365a26906bd73a6ab48cbe1b5b140eb5f8

The guy who answered the question on SO also opened a jira https://issues.jboss.org/browse/DROOLS-1397
I flagged it as solved accordingly.

Mario
Reply all
Reply to author
Forward
0 new messages