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

JBPM 7.52动态编译GDST时Kie Builder无法解析ObjectType问题求解

JBPM 7.52动态编译GDST找不到数据对象问题解决方案

问题背景

使用JBPM Business Central Workbench 7.52版本,动态编译GDST规则表时,Kie Builder无法识别自定义数据对象,报错Unable to resolve ObjectType 'message' : [Rule name='Row 1 MsgRules']。

相关代码与资源

自定义数据对象代码

package com.stackoverflow.question1;
/** This class was automatically generated by the data modeler tool. */
public class message implements java.io.Serializable {
    static final long serialVersionUID = 1L;
    private java.lang.String status;
    private java.lang.String name;
    private java.lang.String message;

    public message() {}
    public message(java.lang.String status, java.lang.String name,
            java.lang.String message) {
        this.status = status;
        this.name = name;
        this.message = message;
    }

    public java.lang.String getStatus() {
        return this.status;
    }
    public void setStatus(java.lang.String status) {
        this.status = status;
    }
    public java.lang.String getName() {
        return this.name;
    }
    public void setName(java.lang.String name) {
        this.name = name;
    }
    public java.lang.String getMessage() {
        return this.message;
    }
    public void setMessage(java.lang.String message) {
        this.message = message;
    }
}

GDST规则表对应生成的DRL代码

package com.stackoverflow.question1;

//from row number: 1
//Name was null
rule "Row 1 MsgRules"
    dialect "mvel"
    when
        MSG : message( name == null )
    then
        modify( MSG ) {
                setMessage( "Name was null" )
        }
end

//from row number: 2
//Name was not null
rule "Row 2 MsgRules"
    dialect "mvel"
    when
        MSG : message( name != null )
    then
        modify( MSG ) {
                setMessage( "Name was not null" )
        }
end

原编译代码

public static KieContainer loadGdstIntoContainer( String gdstFileName) {
    logger.info("KieUtilities:loadKieContainer - Started");
    try {
        KieServices   kieServices   = KieServices.Factory.get();
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        
        //URL resource = KieUtilities.class.getClassLoader().getResource("BaseClaim.class");
        //kieFileSystem.write(ResourceFactory.newUrlResource(resource));
        
        kieFileSystem.write(ResourceFactory.newClassPathResource("MsgRules.gdst"));
        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
        kieBuilder.buildAll();
        if (kieBuilder.getResults().hasMessages(Message.Level.ERROR)) {
            throw new RuntimeException("Build Errors:\n" + kieBuilder.getResults().toString());
        }
        KieRepository kieRepository = kieServices.getRepository();
        KieContainer kieContainer = kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
        logger.info("KieUtilities:loadKieContainer - Finished");
        return kieContainer;
    }
    catch(Exception ex) {
        logger.info("KieUtilities:loadKieContainer - Failed");
        logger.info(ex.getLocalizedMessage());
        throw ex;
    }
}

之前尝试的无效修复

URL resource = KieUtilities.class.getClassLoader().getResource("message.class");
kieFileSystem.write(ResourceFactory.newUrlResource(resource));

修复方案

错误原因

之前的修复无效有两个核心问题:

  1. KieBuilder编译规则时需要目标类在指定的类加载路径中,直接将.class文件写入KieFileSystem根路径,不符合Kie的资源路径规范,无法被识别
  2. 类文件没有按照包结构存放,com.stackoverflow.question1.message对应的路径应该是com/stackoverflow/question1/message.class,直接放根路径找不到对应类。

三种可行修复方式,按实现难度从低到高排序:

方式一:指定KieBuilder使用当前上下文类加载器(最便捷)

只要你的message类已经在当前项目的类路径中,不需要额外写入类文件到KieFileSystem,只需要在创建KieBuilder时传入当前线程的上下文类加载器即可,修改代码如下:

// 将原来创建KieBuilder的代码替换为下面这行
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem, Thread.currentThread().getContextClassLoader());

方式二:将数据对象Java源文件写入KieFileSystem一起编译

如果需要完全从零构建,不依赖当前类路径的类,可以把message.java源文件按包路径写入KieFileSystem,让KieBuilder先编译Java类再编译规则:

// 写入Java源文件,注意路径对应包结构
kieFileSystem.write("src/main/java/com/stackoverflow/question1/message.java",
    ResourceFactory.newClassPathResource("message.java"));
// 再写入GDST规则文件
kieFileSystem.write(ResourceFactory.newClassPathResource("MsgRules.gdst"));

方式三:修正class文件写入路径

如果你一定要使用已经编译好的.class文件,修改写入时的路径即可:

URL resource = KieUtilities.class.getClassLoader().getResource("com/stackoverflow/question1/message.class");
kieFileSystem.write("classes/com/stackoverflow/question1/message.class",
    ResourceFactory.newUrlResource(resource));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 15:06:03