1

I am using Spring Boot 2.1.6.RELEASE with drools version 7.28.0.Final.

We have two model classes and am trying to execute rules using DRL file on top of it

Model Classes

public class VendorReferences {

    private String vendorCode;
    private String vendorName;
    private boolean isChecked;
    private boolean isEnabled;

    //gettters setters defult contructor and parametrized constructor for all args

}

public class Vendor {

    private String vendorCode;
    private String vendorName;
    private boolean isChecked;
    private boolean isEnabled;
    //other additional attributes
}

public class SubmissionObject {
    private String product;
}

Kie Container Config Class

@Configuration
public class RulesConfig {

    @Bean
    public KieContainer kieContainer() {
        KieServices kieServices = KieServices.Factory.get();
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        kieFileSystem.write(ResourceFactory.newClassPathResource(DRL_FILE));
        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
        kieBuilder.buildAll();
        KieModule kieModule = kieBuilder.getKieModule();

        return kieServices.newKieContainer(kieModule.getReleaseId());
    }
}

DRL file

//model classes imports
import java.util.ArrayList;
import java.util.Iterator;
import java.util.stream.Collectors;
global  java.util.ArrayList vendorList;
global  java.util.ArrayList lstDistributionVendor;

dialect  "mvel"

rule "Product Rule"
no-loop true
    when
        $submissionObject: SubmissionObject(product!= null);
    then
        for(VendorReferences vendorRef:lstDistributionVendor){
            VendorReferences vendorObj=new VendorReferences();
            vendorObj.setVendorCode(vendorRef.getVendorCode());
            vendorObj.setChecked(vendorRef.isChecked());
            vendorList.add(vendorObj);
        }
    end

In above DRL file am trying to iterate the arraylist to set the limited properties of VendorReferences object and then trying to add in the arraylist.

public List<VendorReferences> applicableVendors(SubmissionObject submissionObject) {
        KieSession kieSession = kieContainer.newKieSession();
        ArrayList<VendorReferences> vendorList = new ArrayList<>();
        kieSession.setGlobal("vendorList", vendorList);
        kieSession.setGlobal("lstDistributionVendor", lstDistributionVendor);
        kieSession.insert(submissionObject);
        kieSession.fireAllRules();
        kieSession.dispose();
        return vendorList;
}

When I am trying to execute the DRL file using the above code I am getting below error.

Exception executing consequence for rule "Product Rule" in defaultpkg: [Error: unable to resolve method: org.drools.core.base.DefaultKnowledgeHelper.isChecked() [arglength=0]]
[Near : {... endorObj.setChecked(vendorRef.isChecked());            v ....}]
                                 ^
[Line: 1, Column: 269]

I am not able to understand why drools is trying to look into some different class DefaultKnowledgeHelper to check the method instead of model class.

How can I solve the above error?

Beast
  • 639
  • 2
  • 14
  • 29

1 Answers1

2

I took all your code and created a test. Test passed for me and successfully executed then block. I was using exactly the same drools version.

I found similar issue reported to RedHat. I can see the code which throw an exception is mvel optimizer.

at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:1079)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:1071)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:987)

I would suggest the following

  • check whether you did not accidentally override mvel version which drools is using, namely mvel2:2.4.4.Final in maven
  • try to disable optimizer
  • why are you trying to write java code in text files without autocomplete, validation?.. Make yourself a favor, dedicate a class with static methods each containing respective rule then block or spring service with methods, taking all parameters needed for processing and even drools object if you need to interact with the session.

example drl

rule "Product Rule"
no-loop true
when
    $submissionObject: SubmissionObject(product!= null)
then
    MyRules.onProductRule(vendorList, lstDistributionVendor);

example class

public class MyRules {
    public static void onProductRule(ArrayList vendorList, ArrayList lstDistributionVendor) {
        for(VendorReferences vendorRef:lstDistributionVendor){
            VendorReferences vendorObj=new VendorReferences();
            vendorObj.setVendorCode(vendorRef.getVendorCode());
            vendorObj.setChecked(vendorRef.isChecked());
            vendorList.add(vendorObj);
        }
    }

    public static void onOtherRule(SubmissionObject submissionObject, org.drools.core.spi.KnowledgeHelper drools) {
        drools.insert("blah");
    }
}
Mike
  • 20,010
  • 25
  • 97
  • 140
  • @Thanks Adamovych for the details. But I am new to drools, hence I might need few pointers for the first 2 points. How should to identify if version of drools is getting overridden or not and also how to disable the optimizer in drools. I have edited the question to add the configuration class I used to configure the KieContainer. I hope based on that if you can give me more pointers for first 2 points. – Beast May 28 '20 at 03:43
  • added some links, it is really easier to resolve such issues if you isolate small piece of code with a test – Mike May 28 '20 at 06:34
  • @Adamovych I have tried to disable optimizer by passing the JVM argument -Ddrools.jittingThreshold=-1 and also verified the mvl version 2.4.4.Final using the eclipse dependency tree. But still same issue is coming when I tried to execute the program. I request you to explain your last point with some sample. – Beast May 28 '20 at 13:02
  • added an example – Mike May 28 '20 at 14:15
  • btw, your when block should not contain `;`, just noticed. It works either way but it is not needed there – Mike May 28 '20 at 14:43
  • 1
    @Adamovych: We found the issue it was my mistake as i was iterating lstDistributionVendor containing DistributionVendor object rather than VendorReferences object. DistributionVendor does not have name,isChecked attribute hence it was throwing the error. Thanks for help. – Beast May 28 '20 at 19:14