Drools 8.x是否兼容JSR94?求兼容使用示例代码
Drools 8.x 兼容JSR-94的实现方案
Drools 8.x 官方已移除了7.x版本中提供的drools-jsr94.jar封装包,且官方文档和发行说明未提及JSR-94兼容策略。不过可以基于Drools 8的核心Kie API自行实现JSR-94规范的适配层,以下是具体思路和示例代码:
现状说明
Drools 7.x的drools-jsr94.jar是JSR-94规范的官方封装,本质是对drools-compiler组件的上层适配。而Drools 8.x重构了核心API,直接复用7.x的封装包会导致依赖冲突或API不兼容问题,因此需要自行实现适配逻辑。
自定义JSR-94适配层实现
1. 实现RuleServiceProvider
RuleServiceProvider是JSR-94的核心入口,需要基于Drools 8的KieServices和KieContainer来实现:
import javax.rules.RuleServiceProvider; import javax.rules.RuleExecutionSet; import org.kie.api.KieServices; import org.kie.api.runtime.KieContainer; import java.util.Map; import java.io.InputStream; public class Drools8Jsr94Provider extends RuleServiceProvider { private final KieServices kieServices = KieServices.Factory.get(); private final KieContainer kieContainer; public Drools8Jsr94Provider() { // 初始化KieContainer,此处默认加载classpath下的kmodule.xml配置 this.kieContainer = kieServices.getKieClasspathContainer(); } @Override public RuleExecutionSet createRuleExecutionSet(InputStream ruleSetStream, Map properties) throws javax.rules.RuleException { // 若需从输入流加载规则,可在此扩展逻辑,当前示例直接复用已编译的KieBase return new Drools8RuleExecutionSet(kieContainer.getKieBase()); } // 实现其他未覆盖的接口方法,如getRuleExecutionSet等,按需补充 }
2. 实现RuleExecutionSet
该类负责创建规则会话,适配Drools的KieBase:
import javax.rules.RuleExecutionSet; import javax.rules.RuleSession; import javax.rules.RuleSessionType; import org.kie.api.runtime.KieBase; import java.util.Map; public class Drools8RuleExecutionSet implements RuleExecutionSet { private final KieBase kieBase; public Drools8RuleExecutionSet(KieBase kieBase) { this.kieBase = kieBase; } @Override public RuleSession createRuleSession(Map properties, int ruleSessionType) throws javax.rules.RuleException { // 根据会话类型创建对应的KieSession if (ruleSessionType == RuleSessionType.STATELESS_SESSION_TYPE) { return new Drools8StatelessRuleSession(kieBase.newStatelessKieSession()); } else { return new Drools8StatefulRuleSession(kieBase.newKieSession()); } } // 实现其他必填接口方法,如getName、getDescription等,按需返回对应值 @Override public String getName() { return "Drools8-JSR94-RuleSet"; } }
3. 实现RuleSession(分有状态/无状态)
分别实现无状态和有状态规则会话,适配Drools的StatelessKieSession和KieSession:
无状态会话实现
import javax.rules.RuleSession; import javax.rules.StatelessRuleSession; import org.kie.api.runtime.StatelessKieSession; import java.util.List; import java.util.Map; public class Drools8StatelessRuleSession implements StatelessRuleSession { private final StatelessKieSession statelessKieSession; public Drools8StatelessRuleSession(StatelessKieSession statelessKieSession) { this.statelessKieSession = statelessKieSession; } @Override public void execute(List objects) throws javax.rules.RuleException { statelessKieSession.execute(objects); } @Override public void execute(List objects, Map properties) throws javax.rules.RuleException { statelessKieSession.execute(objects); // 若需处理properties,可在此扩展 } @Override public void release() throws javax.rules.RuleException { // 无状态会话无需手动释放,此处留空或添加日志 } // 实现其他未覆盖的接口方法,如addObject、removeObject等,按需补充 }
有状态会话实现
import javax.rules.RuleSession; import javax.rules.StatefulRuleSession; import org.kie.api.runtime.KieSession; import java.util.Iterator; import java.util.Map; public class Drools8StatefulRuleSession implements StatefulRuleSession { private final KieSession kieSession; public Drools8StatefulRuleSession(KieSession kieSession) { this.kieSession = kieSession; } @Override public void addObject(Object object) throws javax.rules.RuleException { kieSession.insert(object); } @Override public void executeRules() throws javax.rules.RuleException { kieSession.fireAllRules(); } @Override public void release() throws javax.rules.RuleException { kieSession.dispose(); } @Override public Iterator getObjects() throws javax.rules.RuleException { return kieSession.getObjects().iterator(); } // 实现其他未覆盖的接口方法,如removeObject、getObjectsByClass等,按需补充 }
4. 注册并使用JSR-94 Provider
import javax.rules.RuleServiceProviderManager; import javax.rules.RuleServiceProvider; import javax.rules.RuleExecutionSet; import javax.rules.RuleSession; import javax.rules.RuleSessionType; import java.util.ArrayList; import java.util.List; public class Jsr94Drools8Demo { public static void main(String[] args) throws Exception { // 注册自定义的Drools8 JSR-94 Provider RuleServiceProviderManager.registerRuleServiceProvider( "com.example.drools8.jsr94", Drools8Jsr94Provider.class ); // 获取Provider实例 RuleServiceProvider provider = RuleServiceProviderManager.getRuleServiceProvider( "com.example.drools8.jsr94" ); // 创建规则执行集 RuleExecutionSet ruleExecutionSet = provider.createRuleExecutionSet(null, null); // 创建无状态规则会话并执行 RuleSession statelessSession = ruleExecutionSet.createRuleSession(null, RuleSessionType.STATELESS_SESSION_TYPE); List<Object> facts = new ArrayList<>(); facts.add(new Order(150.0)); // 自定义事实类,需根据业务规则定义 ((javax.rules.StatelessRuleSession) statelessSession).execute(facts); statelessSession.release(); // 创建有状态规则会话并执行 RuleSession statefulSession = ruleExecutionSet.createRuleSession(null, RuleSessionType.STATEFUL_SESSION_TYPE); statefulSession.addObject(new Order(200.0)); statefulSession.executeRules(); statefulSession.release(); } // 自定义事实类示例 public static class Order { private double amount; public Order(double amount) { this.amount = amount; } // getter/setter public double getAmount() { return amount; } } }
注意事项
- 需确保项目中正确引入Drools 8的核心依赖:
kie-api、kie-core、drools-compiler等,版本保持一致 - 自定义适配层需要覆盖JSR-94规范的所有接口方法,复杂场景下需完善异常处理、参数传递等细节
- 若规则需要动态加载,可扩展
createRuleExecutionSet方法,基于输入流构建自定义KieBase
内容的提问来源于stack exchange,提问作者itsajitsharma
相关产品推荐
相关产品推荐

