Drools 9结合SpringBoot 3使用RuleUnit无法从文件系统加载规则
问题:Drools 9.44 + SpringBoot 3集群部署时规则加载报错(StringIndexOutOfBoundsException)
我正尝试将Drools从7版本升级至9.44版本,应用基于SpringBoot 3运行。已实现RuleUnit并将所有规则迁移至新格式,DRL文件按规范放在与RuleUnit包名匹配的目录中,且已迁移到resources文件夹遵循推荐目录结构。本地SpringBoot单元测试运行正常,规则可正常加载,但部署到集群运行时出现如下错误:
java.lang.StringIndexOutOfBoundsException: begin 5, end 3, length 97 at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4606) at java.base/java.lang.String.substring(String.java:2709) at org.drools.ruleunits.impl.RuleUnitProviderImpl.collectResourcesInJar(RuleUnitProviderImpl.java:189)
该错误表明KIE容器正尝试从JAR而非文件系统加载规则,不清楚如何修改配置让规则从文件系统指定文件夹加载。
解决方案
1. 自定义KieFileSystem指定文件系统规则路径
通过Spring配置类手动构建KieFileSystem,直接加载文件系统中的DRL文件,绕过JAR资源扫描:
@Configuration public class DroolsConfiguration { @Bean public KieServices kieServices() { return KieServices.Factory.get(); } @Bean public KieFileSystem kieFileSystem(KieServices kieServices) { KieFileSystem kfs = kieServices.newKieFileSystem(); // 替换为集群环境中实际的规则文件目录 File ruleDirectory = new File("/opt/app/rules"); if (ruleDirectory.exists() && ruleDirectory.isDirectory()) { for (File drlFile : Objects.requireNonNull(ruleDirectory.listFiles((dir, name) -> name.endsWith(".drl")))) { kfs.write(ResourceFactory.newFileResource(drlFile)); } } return kfs; } @Bean public KieContainer kieContainer(KieServices kieServices, KieFileSystem kieFileSystem) { KieBuilder builder = kieServices.newKieBuilder(kieFileSystem); builder.buildAll(); KieModule module = builder.getKieModule(); return kieServices.newKieContainer(module.getReleaseId()); } }
2. 关闭RuleUnit自动JAR资源扫描
添加Spring配置属性,禁用RuleUnit默认的JAR内资源扫描行为:
# application.properties drools.ruleunits.scan.enabled=false
或者通过代码配置RuleUnitConfig关闭扫描:
@Bean public RuleUnitConfig ruleUnitConfig() { RuleUnitConfig config = new RuleUnitConfig(); config.setScanResources(false); return config; }
3. 验证集群环境的规则目录权限
确认集群服务器上指定的规则目录存在,且应用运行进程拥有该目录的读权限,避免因路径不存在或权限不足导致的加载异常。
内容的提问来源于stack exchange,提问作者user27989825
相关产品推荐
相关产品推荐

