对于循环迭代以在 arraylist 中注入对象在 Drools 中不起作用
For loop iteration to inject the object in arraylist is not working in Drools
我正在使用 Spring Boot 2.1.6.RELEASE 和 drools 版本 7.28.0.Final.
我们有两个模型 classes 并且正在尝试在其上使用 DRL 文件来执行规则
型号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 容器配置 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 文件
//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 文件中,我正在尝试迭代数组列表以设置 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]
我无法理解为什么 drools 试图研究一些不同的 class DefaultKnowledgeHelper 来检查方法而不是模型 class。
如何解决上述错误?
我拿走了你所有的代码并创建了一个测试。测试为我通过并成功执行然后阻止。我使用的是完全相同的 drools 版本。
我发现向 RedHat 报告了类似的 issue。我可以看到抛出异常的代码是 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)
我建议如下
- 检查你是否不小心 override mvel version 正在使用哪个 drools,即 mvel2:2.4.4.Final in maven
- 尝试disable optimizer
- 你为什么要在没有自动完成、验证的情况下在文本文件中编写 java 代码?..帮自己一个忙,用静态方法奉献一个 class,每个静态方法都包含各自的规则然后块或 spring 服务方法,获取处理所需的所有参数,如果您需要与会话交互,甚至是 drools 对象。
示例 drl
rule "Product Rule"
no-loop true
when
$submissionObject: SubmissionObject(product!= null)
then
MyRules.onProductRule(vendorList, lstDistributionVendor);
示例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");
}
}
我正在使用 Spring Boot 2.1.6.RELEASE 和 drools 版本 7.28.0.Final.
我们有两个模型 classes 并且正在尝试在其上使用 DRL 文件来执行规则
型号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 容器配置 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 文件
//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 文件中,我正在尝试迭代数组列表以设置 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]
我无法理解为什么 drools 试图研究一些不同的 class DefaultKnowledgeHelper 来检查方法而不是模型 class。
如何解决上述错误?
我拿走了你所有的代码并创建了一个测试。测试为我通过并成功执行然后阻止。我使用的是完全相同的 drools 版本。
我发现向 RedHat 报告了类似的 issue。我可以看到抛出异常的代码是 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)
我建议如下
- 检查你是否不小心 override mvel version 正在使用哪个 drools,即 mvel2:2.4.4.Final in maven
- 尝试disable optimizer
- 你为什么要在没有自动完成、验证的情况下在文本文件中编写 java 代码?..帮自己一个忙,用静态方法奉献一个 class,每个静态方法都包含各自的规则然后块或 spring 服务方法,获取处理所需的所有参数,如果您需要与会话交互,甚至是 drools 对象。
示例 drl
rule "Product Rule"
no-loop true
when
$submissionObject: SubmissionObject(product!= null)
then
MyRules.onProductRule(vendorList, lstDistributionVendor);
示例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");
}
}