Для l oop итерации для ввода объекта в arrayylist не работает в Drools - PullRequest
2 голосов
/ 27 мая 2020

Я использую Spring Boot 2.1.6.RELEASE с слюнями версии 7.28.0.Final.

У нас есть два класса моделей, и я пытаюсь выполнить правила, используя файл DRL поверх него

Классы моделей

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;
}

K ie Класс конфигурации контейнера

@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

//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

В приведенном выше файле DRL я пытаюсь выполнить итерацию по arrayylist чтобы установить ограниченные свойства объекта VendorReferences, а затем попытаться добавить в массив.

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;
}

Когда я пытаюсь выполнить файл DRL, используя приведенный выше код, я получаю ошибку ниже.

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]

Я не могу понять, почему слюни пытаются заглянуть в какой-то другой класс DefaultKnowledgeHelper, чтобы проверить метод, а не класс модели.

Как я могу решить указанную выше ошибку?

1 Ответ

3 голосов
/ 28 мая 2020

Я взял весь ваш код и создал тест. Тест прошел для меня и успешно выполнен, затем блок. Я использовал ту же самую версию слюни.

Я обнаружил похожую проблему , о которой сообщалось в RedHat. Я вижу код, который генерирует исключение, это оптимизатор mvel.

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)

Я бы предложил следующую

  • проверить, не случайно ли вы переопределили версию mvel какие слюни использует, а именно mvel2: 2.4.4.Final в maven
  • попробуйте отключить оптимизатор
  • почему вы пытаетесь написать код java в тексте файлы без автозаполнения, проверки? .. Сделайте себе одолжение, выделите класс с методами stati c, каждый из которых содержит соответствующее правило, затем заблокируйте или пружинный сервис с методами, принимая все параметры, необходимые для обработки, и даже пускайте слюни, если вам нужно взаимодействовать с сеанс.

пример drl

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

пример класса

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");
    }
}
...