修改Drools事实时触发drools-wiring-dynamic错误的原因咨询
问题背景与原因解析
操作步骤
- 通过Maven原型生成Drools Rule Unit项目:
mvn archetype:generate -DarchetypeGroupId=org.kie -DarchetypeArtifactId=kie-drools-exec-model-ruleunit-archetype -DarchetypeVersion=8.33.0.Final - 给
Measurement类添加setter方法:public void setVal(final String val) { this.val = val; } - 编写规则,在动作块中直接修改事实对象的属性:
rule "will execute per each Measurement having ID color" when $measure: /measurements[ id == "color", $colorVal : val ] then $measure.setVal("BS"); end
报错信息
运行测试时抛出异常:
java.lang.UnsupportedOperationException: You're trying to dynamically define a class, please add the module org.drools:drools-wiring-dynamic to your classpath. at org.drools.wiring.statics.StaticProjectClassLoader$DummyInternalTypesClassLoader.defineClass(StaticProjectClassLoader.java:83) at org.drools.wiring.api.classloader.ProjectClassLoader.defineType(ProjectClassLoader.java:208) at org.drools.wiring.api.classloader.ProjectClassLoader.tryDefineType(ProjectClassLoader.java:192) at org.drools.wiring.api.classloader.ProjectClassLoader.loadType(ProjectClassLoader.java:181) at org.drools.wiring.api.classloader.ProjectClassLoader.loadClass(ProjectClassLoader.java:135) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
为什么需要手动添加drools-wiring-dynamic依赖
Drools 8.x的执行模型(Exec Model)和Rule Unit默认采用静态类加载器(StaticProjectClassLoader),这个类加载器的设计目标是避免动态类生成,提升性能和安全性,因此默认不包含动态类定义的能力。
当你在规则的动作块中直接修改事实对象的属性(比如调用$measure.setVal("BS"))时,Drools需要生成动态代理类来跟踪对象的状态变化——这是为了保证规则引擎能感知到事实更新,进而触发相关的规则重匹配。这种动态类生成的操作,静态类加载器无法处理,必须依赖drools-wiring-dynamic提供的动态类加载器实现。
官方原型默认只引入了静态类加载相关的依赖,因为其默认推荐的用法是使用不可变对象,或者通过Rule Unit的数据流API(比如DataStore的update方法)来更新事实状态,这类场景不需要动态类生成。而直接修改对象属性的用法属于进阶场景,文档尚未覆盖到,因此需要手动添加该依赖。
Kogito的Rule Unit项目基于Drools执行模型构建,所以会出现完全一致的报错和解决方式。
内容的提问来源于stack exchange,提问作者Eugene Shvartsman
相关产品推荐
相关产品推荐

