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

Spring Boot控制器调用RuleUnitProvider.get()报错,无法找到规则单元

解决Spring Boot中Drools RuleUnit运行时找不到规则的问题

问题描述

我在Spring Boot项目中引入了Drools RuleUnit依赖:

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-ruleunits-engine</artifactId>
    <version>8.33.0.Final</version>
</dependency>

通过RuleUnit配置规则后,单元测试中调用RuleUnitProvider.get().createRuleUnitInstance(requestAccessUnit);可以正常创建实例,但在@RequestController中执行相同代码时抛出错误:

java.lang.RuntimeException: Cannot find any rule unit for RuleUnitData of class:yyyy.xxxx.zzzz.RuleUnit

日志同时显示KieProject - No files found for KieBase defaultKieBase,推测规则文件未被加载到KieBase中。

想确认是否必须使用kie-maven-plugin并打包为kjar才能解决?有没有不使用kjar的方案?我们的构建架构引入kjar会非常麻烦,官方Spring Boot集成RuleUnit的文档很少,在Kogito中也遇到了相同问题。


不需要强制使用kjar,以下是可行的替代方案

1. 手动构建KieContainer并指定规则文件

Drools默认会在kjar结构中自动扫描规则文件,但普通Spring Boot jar中需要手动构建KieContainer,明确指定规则文件路径。

步骤1:创建Drools配置类,初始化KieContainer Bean

import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.builder.KieRepository;
import org.kie.api.runtime.KieContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DroolsConfig {

    @Bean
    public KieContainer kieContainer() {
        KieServices kieServices = KieServices.Factory.get();
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        
        // 添加规则文件,替换为你的实际规则文件路径
        // 示例:规则文件放在src/main/resources/rules目录下
        kieFileSystem.write("src/main/resources/rules/AccessControlRules.drl");
        // 多个规则文件可多次调用write方法
        
        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
        kieBuilder.buildAll(); // 编译规则
        
        KieRepository kieRepository = kieServices.getRepository();
        KieModule kieModule = kieRepository.getKieModule(kieRepository.getDefaultReleaseId());
        
        return kieServices.newKieContainer(kieModule.getReleaseId());
    }
}

步骤2:在Controller中注入KieContainer,关联RuleUnit

import org.kie.api.runtime.rule.RuleUnitInstance;
import org.kie.api.runtime.rule.RuleUnitProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AccessControlController {

    @Autowired
    private KieContainer kieContainer;

    @PostMapping("/check-access")
    public AccessResponse checkAccess(@RequestBody AccessRequest request) {
        // 初始化RuleUnit数据对象
        RequestAccessUnit ruleUnitData = new RequestAccessUnit();
        ruleUnitData.setRequest(request);
        
        // 使用指定的KieContainer创建RuleUnit实例
        RuleUnitInstance<RequestAccessUnit> ruleInstance = RuleUnitProvider.get()
                .createRuleUnitInstance(kieContainer, ruleUnitData);
        
        ruleInstance.fire(); // 执行规则
        ruleInstance.close();
        
        return ruleUnitData.getResponse();
    }
}

2. 确保规则文件被正确打包到Spring Boot Jar中

检查pom.xml的资源配置,确保规则文件(.drl、.rule等后缀)被包含在最终jar里:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.drl</include>
                <include>**/*.rule</include>
                <include>**/*.dslr</include>
            </includes>
        </resource>
    </resources>
</build>

3. (可选)使用kmodule.xml简化规则扫描

如果不想手动逐个添加规则文件,可以在src/main/resources/META-INF下创建kmodule.xml,定义KieBase和KieSession的扫描路径:

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <kbase name="defaultKieBase" packages="rules.*">
        <ksession name="defaultKieSession"/>
    </kbase>
</kmodule>

这里packages="rules.*"表示扫描src/main/resources/rules目录下的所有规则文件,此时Drools会自动加载这些文件,无需在配置类中手动写入路径。


为什么单元测试正常但Controller中报错?

单元测试环境中,类路径直接包含了src/main/resources下的规则文件,Drools默认扫描机制可以找到文件;但Spring Boot打包后,默认的KieBase扫描逻辑不会自动识别普通jar中的规则文件,必须手动指定加载路径或通过kmodule.xml配置扫描规则。


内容的提问来源于stack exchange,提问作者Eugene Shvartsman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 08:23:55