Drools 6.5.0.Final升级至7.73.0.Final时DRL加载异常求助
问题根源
该问题是Drools升级到兼容Java17的版本后,表达式解析器在严格模式下的误解析行为:当DRL中的变量名以下划线+数字结尾(如rule_ekart_90),且后续阈值为相同数字(如90)时,解析器错误地将变量名末尾的数字与阈值数字合并为浮点数格式(如把rule_ekart_90 >=90解析成rule_ekart_90.0 >=90.0),进而触发double.0()方法不存在的错误。
无需修改DRL的解决方案
1. 关闭Drools表达式解析的严格模式
通过配置KieBase的drools.parser.strict属性为false,让解析器以宽松模式处理表达式,避免误解析。可以通过两种方式实现:
方式一:写入kmodule.xml配置文件
修改createKieContainer方法,添加kmodule.xml到KieFileSystem中:
private KieContainer createKieContainer(String identifier, byte[] drlBlob) throws RulesSDKException { if (this.containerHashMap.containsKey(identifier)) { return (KieContainer)this.containerHashMap.get(identifier); } else { Resource resource = ResourceFactory.newByteArrayResource(drlBlob); KieServices kieServices = org.kie.api.KieServices.Factory.get(); KieFileSystem kieFileSystem = kieServices.newKieFileSystem(); kieFileSystem.write("src/main/resources/" + identifier + ".drl", resource); // 添加kmodule.xml配置,关闭严格解析模式 String kmoduleXml = """ <?xml version="1.0" encoding="UTF-8"?> <kmodule xmlns="http://www.drools.org/xsd/kmodule"> <kbase name="defaultKBase" packages="rule_table" default="true"> <ksession name="defaultKSession" default="true"/> <property name="drools.parser.strict" value="false"/> </kbase> </kmodule> """; kieFileSystem.write("src/main/resources/META-INF/kmodule.xml", ResourceFactory.newByteArrayResource(kmoduleXml.getBytes())); KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem).buildAll(); Results results = kieBuilder.getResults(); if (results.hasMessages(new Message.Level[]{Level.ERROR})) { LOGGER.error("Unable to load RuleSet " + results.getMessages()); throw new RulesSDKException("Unable to load RuleSet " + results.getMessages()); } else { KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId()); this.containerHashMap.put(identifier, kieContainer); return kieContainer; } } }
方式二:代码中直接配置KieBase
无需写入配置文件,直接在代码中创建KieBaseConfiguration设置属性:
// ... 原有代码构建KieContainer后 ... KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId()); // 创建KieBase配置并关闭严格模式 KieBaseConfiguration kieBaseConfig = kieServices.newKieBaseConfiguration(); kieBaseConfig.setProperty("drools.parser.strict", "false"); // 使用配置创建KieBase,后续从该KieBase创建KieSession即可 KieBase kieBase = kieContainer.newKieBase(kieBaseConfig); // ... 后续业务逻辑 ...
2. 升级到修复该解析bug的Drools版本
该问题属于Drools表达式解析器的特定版本bug,在较新的Drools版本(如8.44.0.Final及以上,或7.x系列的后期稳定版本)中已被修复。直接升级你的Drools依赖到兼容Java17的最新稳定版本,即可解决该问题,无需修改代码或DRL。
内容的提问来源于stack exchange,提问作者Ravuri Dhanush
相关产品推荐
相关产品推荐

