Drools 6.x and Java 8 Lambdas in DRL files

3,764 views
Skip to first unread message

Jeff Jensen

unread,
Dec 8, 2015, 5:39:54 PM12/8/15
to Drools Setup
Hi, we've been successfully using Java 8 and Lambdas in DRL files with Drools 5.x and now we're upgrading to Drools 6.3.

Since it works in Drools 5, we're assuming it works in Drools 6.  Is this a correct assumption?

In converting to use the new Kie* classes, we have this to start:
KieBuilder builder = services.newKieBuilder(fileSystem);
builder.buildAll();

However, startup fails on Java 8 Lamba expressions with "Rule Compilation error Lambda expressions are allowed only at source level 1.8 or above".

None of the configuration attempts I made have worked to specify Java 8 for DRL files with Drools 6 and the Kie classes.  I'm hoping someone can provide some guidance please! :-)

I tried setting the two "lngLevel" properties (and some derivations I also found) in a KieBaseConfiguration, but had no effect:
final KieServices kieServices = KieServices.Factory.get();
final KieBaseConfiguration baseConfiguration = kieServices.newKieBaseConfiguration();
baseConfiguration.setProperty("drools.dialect.java.lngLevel", "1.8");
baseConfiguration.setProperty("drools.dialect.java.compiler.lngLevel", "1.8");

final KieContainer kieClasspathContainer =
kieServices.getKieClasspathContainer();

final KieBase kieBase =
// kieClasspathContainer.getKieBase();
kieClasspathContainer.newKieBase(baseConfiguration);


Also set them as <property> in kmodule but also no effect.
As suggested in another post, also created drools.packagebuilder.conf with the properties but again no effect.


For reference, this is the app's Drools 5 config:
KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder(buildConfiguration());


private KnowledgeBuilderConfigurationImpl buildConfiguration()
{
    KnowledgeBuilderConfigurationImpl config = new KnowledgeBuilderConfigurationImpl();
    JavaDialectConfiguration javaDialect = (JavaDialectConfiguration) config.getDialectConfiguration("java");
    javaDialect.setJavaLanguageLevel("1.8");
    return config;
}


Tom Pijl

unread,
May 26, 2016, 10:56:57 AM5/26/16
to Drools Setup

Hi Jeff,

I am having the same question using Drools 6.4.0.Final. Did you ever got an answer or solve this issue?

Jeff Jensen

unread,
May 26, 2016, 1:52:58 PM5/26/16
to Drools Setup
Hi Tom, 
In summary, three things I found:
1. Drools 6.3 runs with Java 8, but does not support lambdas in the rules.  This was the cause of our problem.

2. The Java version setting attempts were "overridden" because Drools had hardcoded treating Java 8 as Java 7.


So if you still experience an issue with that, I suggest making a small project of a rule, test, and build that reproduces it and submitting it for Drools team review.  (I did that for my original issue and allowed me to see the causes)


On Thu, May 26, 2016 at 9:56 AM, Tom Pijl <tom....@infor.com> wrote:

Hi Jeff,

I am having the same question using Drools 6.4.0.Final. Did you ever got an answer or solve this issue?

--
You received this message because you are subscribed to the Google Groups "Drools Setup" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drools-setup...@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-setup/af22fea8-a9c4-4fc3-a0eb-9819486d175f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Edson Tirelli

unread,
May 26, 2016, 2:46:49 PM5/26/16
to drools...@googlegroups.com
This should be working in Drools 6.4 and forward. Our unit test is here:

https://github.com/droolsjbpm/drools/blob/6.4.x/drools-compiler/src/test/java/org/drools/compiler/integrationtests/Misc2Test.java#L8202

Let us know if it is not working for you.

Edson
> https://groups.google.com/d/msgid/drools-setup/CAKumxBy4qiXKacVx%3Du-x0VqHBuh-6eJ%2BQgXCJ-Ego_EM_6aM%3DQ%40mail.gmail.com.
>
> For more options, visit https://groups.google.com/d/optout.



--
Edson Tirelli
Principal Software Engineer
Red Hat Business Systems and Intelligence Group

Tom Pijl

unread,
May 27, 2016, 3:52:33 AM5/27/16
to Drools Setup
Hi Edson,

Thanks for your quick support. My rule is as follows:
package com.infor.ion.rules;
import com.infor.ion.poc.rulesengine.api.model.detector.DetectorState;
import com.infor.ion.poc.rulesengine.api.model.BusinessEventData;
import java.util.ArrayList;


rule
'fc36dd77-b61e-4a84-aa8f-cb946ce1593c'
   
no-loop
   
when
        $lst
: ArrayList ( size == 3 ) from collect (
           
BusinessEventData(
                getProperty
('/SyncSalesOrder/sostatus') == 'Open'
           
) over window:time( #PERIOD# )
             
from entry-point 'SyncSalesOrder_stream'
       
)
   
then
       
DetectorState ds  = new DetectorState();
        ds
.setDefinitionId('fc36dd77-b61e-4a84-aa8f-cb946ce1593c');
       
for (Object bed : $lst) {
            ds
.addBusinessEventData((BusinessEventData)bed);
       
}
        ds
.setEvaluationResult(true);
        insert
(ds);
        $lst
.clear();
end

When I compile this inside the engine running in my Eclipse development environment in a test it compiles showing no errors. When I build the engine into a jar and run it inside another JVM (but on the same machine) this rule won't compile and gives me the following error:

Line 7, column 0: Rule Compilation error Syntax error, 'for each' statements are only available if source level is 1.5 or greater

So I thought maybe I have to force the engine to use a language level and tried to do this by adding the following properties to the kmodule.xml file (in this way I stumbled on Jeff's issue):
        KieModuleModel kmm = this.ks.newKieModuleModel();
        kmm
.setConfigurationProperty("drools.dialect.java.lngLevel", "1.8");
        kmm
.setConfigurationProperty("drools.dialect.java.compiler.lnglevel", "1.8");
but that didn't help.

What external property influences the Drools compiler to decide on the language level? And how can I force it to use a certain language level?

Edson Tirelli

unread,
May 30, 2016, 9:36:56 PM5/30/16
to drools...@googlegroups.com
Tom,

I haven't tried running your example, but a quick look at the code
shows me two things:

* If no property is set, then the engine tries to detect the version
of java by looking at the System.property java.version:

https://github.com/droolsjbpm/drools/blob/master/drools-core/src/main/java/org/drools/core/rule/builder/dialect/asm/ClassLevel.java#L56

So, which jvm are you using when running from the command line?

* If you do want to override the java language level, then you have
the right property set:

drools.dialect.java.compiler.lnglevel

But I think you need to set it as a system property, as I don't
think properties set in the kmodule are loaded into the system-wide
chained properties, but I might be wrong.

Edson
> https://groups.google.com/d/msgid/drools-setup/61bb207c-af6b-412c-a2c0-303b284a682b%40googlegroups.com.

Tom Pijl

unread,
May 31, 2016, 6:04:19 AM5/31/16
to Drools Setup
Edson,

Thanks again for the quick support.

We at Infor have our own PAAS that takes care of scalability and high availability. It is fed by jars combined in a module that are run in its own JVM (Java 8 SDK) per module.
In such a module I programmatically try to build rules into kjars that will be fed into a KieContainer as follows:

KieServices ks = KieServices.Factory.get();
KieFileSystem kf = ks.newKieFileSystem();
ReleaseId releaseId = ks.newReleaseId("com.infor.ion", "ACME_PRD.rules", "1.0.0-SNAPSHOT");
kf
.writePomXML(createPomFile());                               // POM file content given below
KieModuleModel kmm = ks.newKieModuleModel();
kf
.writeKModuleXML(kmm.toXML());
kf
.write("src/main/resources/ACME_PRD_MyRules.drl", "....." ); // the rules file given in previous post
KieBuilder kb = ks.newKieBuilder(kf);
kb
.buildAll();

using the POM file content:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   
<modelVersion>4.0.0</modelVersion>
   
<groupId>com.infor.ion</groupId>
   
<artifactId>acme.prd.rules</artifactId>
   
<version>1.0.0-SNAPSHOT</version>
   
<packaging>kjar</packaging>

   
<dependencies>
       
<dependency>
           
<groupId>com.infor.ion</groupId>
           
<artifactId>com.infor.ion.poc.rulesengine.api</artifactId>
           
<version>1.0.0-SNAPSHOT</version>
       
</dependency>
   
</dependencies>

   
<build>
       
<plugins>
           
<plugin>
               
<groupId>org.kie</groupId>
               
<artifactId>kie-maven-plugin</artifactId>
               
<version>6.4.0.Final</version>
               
<extensions>true</extensions>
           
</plugin>
       
</plugins>
   
</build>
</project>

The logging gives the following information:

2016-05-31 11:25:23,724 +0200Z {}  INFO EngineModule   com.infor.ion.poc.rulesengine.drools.DroolsCEPEngine: [web-request-0] System property: java.version=1.8
2016-05-31 11:25:23,724 +0200Z {}  INFO EngineModule   com.infor.ion.poc.rulesengine.drools.DroolsCEPEngine: [web-request-0] System property: drools.dialect.java.compiler.lnglevel=1.8
2016-05-31 11:25:24,540 +0200Z {} ERROR EngineModule org.drools.compiler.kie.builder.impl.AbstractKieModule: [web-request-0] Unable to build KieBaseModel:defaultKieBase
Rule Compilation error : [Rule name='d5ff31e0-cb98-4599-ae42-f29049f764db']
        com
/infor/ion/rules/Rule_d5ff31e0$u45$cb98$u45$4599$u45$ae42$u45$f29049f764db231039844.java (9:755) : Syntax error, 'for each' statements are only available if source level is 1.5 or greater

As you can see both system properties are set to 1.8 but the maven java compiler still has its own source level that is < 1.5.

Edson Tirelli

unread,
Jun 7, 2016, 11:08:26 AM6/7/16
to drools...@googlegroups.com
Tom,

Can you please open a JIRA if you haven't yet? We will take a
closer look into this.

Thanks,
Edson
> https://groups.google.com/d/msgid/drools-setup/a8e5aeb7-64e8-42ef-8ed1-7c8acfaa422b%40googlegroups.com.

Tom Pijl

unread,
Jun 8, 2016, 3:25:35 AM6/8/16
to Drools Setup
Edson,

While trying to isolate the problem into an executable jar for the issue I wanted to create, I couldn't reproduce the issue at hand.
So I must conclude that our PAAS environment is responsible for making this error appear.
I will now try to debug our PAAS environment to see why there is a difference between a "real" standalone JVM and a JVM created by the PAAS.

Sorry for the inconvenience and thanks for your support sofar.

Tom Pijl

unread,
Jun 8, 2016, 3:45:38 AM6/8/16
to Drools Setup
PS. I noticed that the drools compiler uses the Eclipse ecj-4.4.2.jar (JDT compiler). Is there a reason why you don't rely on the maven-compiler-plugin to perform the compilation?
The error message I got was thrown by the JDT compiler (I found it in the messages.properties file in the org.eclipse.jdt.internal.compiler.problem-package in the ecj-4.4.2.jar).
It looks as if the JDT compiler didn't get the correct Java source level in our PAAS JVM and it appears that besides the source level that the drools compiler provides there is another environment property that influences the source level of the JDT compiler.

sathish kumar

unread,
Jan 28, 2020, 5:41:02 AM1/28/20
to Drools Setup
we are using java 11 with kie-spring 7.0.0, we are getting Method references are allowed only at source level 1.8 or above and  Lambda expressions are allowed only at source level 1.8 or above, how can we resolve this issue

Santosh Nesaragi

unread,
Apr 29, 2020, 2:58:12 AM4/29/20
to Drools Setup
when i am trying to migrate JDK 1.8 to OpenJDK 11 with drools 6.5.0.Final it throws compilation error "Lambda expressions are allowed only at source level 1.8 or above", rules with lambda functions are failing ? is that drools 6 will not support JDK11?

sathish kumar

unread,
Apr 29, 2020, 8:55:20 AM4/29/20
to Drools Setup
You need to update you kie version, we are using kie-spring 7.31.0 and we are able to use lamdas

Santosh Nesaragi

unread,
May 2, 2020, 6:16:23 AM5/2/20
to Drools Setup
Hi sathish,

Thank you very much for your replay , It helped me lot.

Posting my analysis here so that it will be helpful to others.

While compiling (.drl) Rule files in KIE Builder , drool builder(Drool 6.5.0.Final) will choose java dialect version by comparing Project JDK version as shown below

 

https://github.com/kiegroup/drools/blob/6.5.x/drools-core/src/main/java/org/drools/core/rule/builder/dialect/asm/ClassLevel.java

 

public static int findJavaVersion(ChainedProperties chainedProperties) {

        String level = chainedProperties.getProperty(JAVA_LANG_LEVEL_PROPERTY,

                                                     System.getProperty("java.version"));

 

        if ( level.startsWith( "1.5" ) ) {

            return V1_5;                                                                                                                                                                                

        } else if ( level.startsWith( "1.6" ) ) {

            return V1_6;

        } else if ( level.startsWith( "1.7" ) ) {

            return V1_7;

        } else if ( level.startsWith( "1.8" ) ) {

            return V1_8;

        } else {

            return V1_7;

        }

    }

 

While migrating code base to Open Jdk11 , Rule builder dialect uses default jdk 1.7 as drool compiler due to unsupported Java version 11.

 

As stated above because of default drool compiler V1_7, Rules having Lambda expression (1.8 compatible code) is failing with below error

Rule Compilation error : [Rule name='<rule name>']
com/Rule_Name1212443411.java (13:1596) : Type mismatch: cannot convert from List<Object> to List<EmployeeSet>
com/Rule_INamet1212443411.java (13:1637) : Lambda expressions are allowed only at source level 1.8 or above

Drools 6.5.0.Final will whitelist java up to 1.8 as valid lang level.

 

To proceed further either we have set  “JAVA_LANG_LEVEL_PROPERTY"  to 1.8  or to upgrade Drools engine to 7.36.1 version

Thanks and Regards,
Santosh, 
Reply all
Reply to author
Forward
0 new messages