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

Spring Boot集成Drools 8.33.0.Final无法读取Excel规则文件求助

解决Drools无法加载Excel/CSV规则文件的问题

环境信息

  • Spring Boot:2.7.7
  • Drools:8.33.0.Final
  • Java:17

问题现象

开发Spring Boot RESTful服务时,使用Drools加载.xlsx/.xls/.csv格式的规则文件无效,控制台抛出警告:

No files found for KieBase defaultKieBase

测试请求URL:localhost:8080/getInterestRate?loanType=Fixed&age=45&durationInYear=1

相关代码

POM.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.7.7</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    <groupId>com.codeusingjava</groupId>
    <artifactId>boot-drools</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>boot-drools</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
        <drools.version>8.33.0.Final</drools.version>
        <!-- <drools.version>8.15.0.Beta</drools.version> -->
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-core</artifactId>
            <version>${drools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-mvel</artifactId>
            <version>${drools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-decisiontables</artifactId>
            <version>${drools.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>${drools.version}</version>
        </dependency>
        
         <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-ci</artifactId>
            <version>${drools.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Drools配置类

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.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DroolsConfiguration {

    private final KieServices kieServices = KieServices.Factory.get();

    @Bean
    public KieContainer kieContainer() {
        KieContainer kieCont = null;

        try {
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        kieFileSystem.write(ResourceFactory.newClassPathResource("rules/discount.xlsx"));
        KieBuilder kb = kieServices.newKieBuilder(kieFileSystem);
        kb.buildAll();
        KieModule kieModule = kb.getKieModule();
        kieCont = kieServices.newKieContainer(kieModule.getReleaseId());
        
        }catch(Exception exception) {
            exception.printStackTrace();
        }
        return kieCont;
    }
}

DepositRateController.java

package com.codeusingjava.bootdrools.controller;

import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.codeusingjava.bootdrools.model.DepositRequest;

@RestController
public class DepositRateController {

    @Autowired
    private KieContainer kieContainer;

    @RequestMapping(value = "/getInterestRate", method = RequestMethod.GET, produces = "application/json")
    public String getInterest(@RequestParam(required = true) String loanType,
            @RequestParam(required = true) Integer durationInYear, @RequestParam(required = true) Integer age) {
        KieSession kieSession = kieContainer.newKieSession();
        DepositRequest depositRequest = new DepositRequest(loanType, durationInYear, age);
        kieSession.insert(depositRequest);
        kieSession.fireAllRules();
        kieSession.dispose();
        return "The interest rate for this application is " + depositRequest.getInterestRate();
    }
}

DepositRequest.java

package com.codeusingjava.bootdrools.model;

public class DepositRequest {
    private String loanType;
    private Integer durationInYear;
    private Integer age;
    private String interestRate;

    public DepositRequest(String loanType, Integer durationInYear, Integer age) {
        super();
        this.loanType = loanType;
        this.durationInYear = durationInYear;
        this.age = age;
    }

    public String getLoanType() {
        return loanType;
    }

    public void setLoanType(String loanType) {
        this.loanType = loanType;
    }

    public Integer getDurationInYear() {
        return durationInYear;
    }

    public void setDurationInYear(Integer durationInYear) {
        this.durationInYear = durationInYear;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getInterestRate() {
        return interestRate;
    }

    public void setInterestRate(String interestRate) {
        this.interestRate = interestRate;
    }

}

控制台日志

Tomcat initialized with port(s): 8080 (http)
2023-02-17 13:20:01.551  INFO 19264 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-02-17 13:20:01.551  INFO 19264 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.70]
2023-02-17 13:20:01.955  INFO 19264 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-02-17 13:20:01.955  INFO 19264 --- [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1006 ms
2023-02-17 13:20:02.891  WARN 19264 --- [  restartedMain] o.d.c.kie.builder.impl.KieProject        : No files found for KieBase defaultKieBase
2023-02-17 13:20:03.073  INFO 19264 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2023-02-17 13:20:03.099  INFO 19264 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-02-17 13:20:03.105  INFO 19264 --- [  restartedMain] c.c.bootdrools.BootDroolsApplication     : Started BootDroolsApplication in 2.433 seconds (JVM running for 3.26)

解决步骤

1. 验证规则文件路径与格式

  • 确认discount.xlsx文件位于src/main/resources/rules/目录,路径大小写与代码中一致(Linux/macOS环境需注意大小写敏感)。
  • 确保Excel决策表符合Drools规范:包含RuleSet、RuleName、CONDITION、ACTION等必填表头,规则逻辑单元格格式正确。

2. 明确指定资源类型加载Excel文件

Drools 8.x需要显式声明决策表资源类型,修改配置类中的资源加载代码:

import org.kie.api.io.ResourceType;

@Configuration
public class DroolsConfiguration {

    private final KieServices kieServices = KieServices.Factory.get();

    @Bean
    public KieContainer kieContainer() {
        KieContainer kieCont = null;
        try {
            KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
            // 显式设置资源类型为决策表
            Resource resource = ResourceFactory.newClassPathResource("rules/discount.xlsx");
            resource.setResourceType(ResourceType.DTABLE);
            kieFileSystem.write(resource);
            
            KieBuilder kb = kieServices.newKieBuilder(kieFileSystem);
            kb.buildAll();
            KieModule kieModule = kb.getKieModule();
            kieCont = kieServices.newKieContainer(kieModule.getReleaseId());
            
        }catch(Exception exception) {
            exception.printStackTrace();
        }
        return kieCont;
    }
}

3. 添加kmodule.xml配置文件

在src/main/resources/META-INF/下创建kmodule.xml,定义KieBase和KieSession,让Drools正确识别规则目录:

<?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"对应resources/rules/目录,Drools会自动扫描该目录下的所有规则文件(包括决策表)。

4. 调试资源加载状态

在配置类中添加检查语句,确认资源是否存在:

Resource resource = ResourceFactory.newClassPathResource("rules/discount.xlsx");
System.out.println("规则文件是否存在:" + resource.exists());

若输出false,需调整文件路径或文件存放位置。

5. 清理并重新构建项目

执行Maven命令清理缓存并重新构建:

mvn clean install

内容的提问来源于stack exchange,提问作者Suresh Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 04:24:10