You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 07:45:32