1. 项目概述
1.1 为什么2025年还有人写JRules
先交代一下背景。WebSphere ILOG JRules,老牌商业规则引擎,后来被IBM收编,改名叫IBM Operational Decision Manager,也就是ODM。这套东西在银行、保险、电信这些行业的遗留系统里存量极大,尤其在国内,很多核心交易系统的风控、定价、核保规则跑在上面,一跑就是十几年。
你要是刚接手这类项目,第一反应大概率是崩溃——商业产品,文档要上IBM官网翻,社区讨论少得可怜,网上搜到的资料全是英文PDF,版本还都对不上。我自己当年从零开始摸这个玩意儿,光是搭环境就折腾了好几天,期间无数次想摔键盘。
这篇是连载第三篇,前两篇分别讲了规则引擎的基本概念、JRules的体系架构,没看过的回头翻一下。这篇聚焦一个最基础也最绕不开的操作:在JRules里新建一个规则项目。别小看这一步,项目结构建不对、资源库连不上、运行环境没配好,后面写规则、调试、部署全是坑。
适合谁看?刚接触JRules的Java开发、从Drools等开源规则引擎转过来的同学,以及那些被派去维护老系统、需要快速上手的“救火队员”。这篇会把我踩过的坑、摸索出来的经验全部写出来,按着做能少走很多弯路。
1.2 新建规则项目到底在解决什么问题
先说个本质问题:JRules里说的“规则项目”,跟Eclipse里普通的Java项目有什么区别?
区别大了。普通Java项目你只管写代码,编译、打包、运行,一套标准流程。但规则项目是跑在JRules的规则引擎上的,它需要承载的东西远不止Java代码:
- 规则本身(用BAL语言写,后面细说)
- 业务对象模型(BOM)和技术对象模型(XOM)之间的映射
- 规则集(Ruleset)以及规则集打包后的二进制文件
- 规则流(Ruleflow)——控制规则执行顺序的流程图
- 决策表、决策树这类可视化规则的存储
- 版本管理和部署配置信息
- 关联的测试用例、模拟数据
这些内容如果散落在普通Java工程里,管理起来就是灾难。JRules通过“规则项目”这个统一载体,把规则开发、测试、版本管理、部署打包整个生命周期串起来。新建项目的操作看似简单——不就是File > New > Project吗——但背后涉及的资源库连接、依赖配置、运行环境准备,每一步都有讲究。
说白了,新建规则项目就是你整个规则应用的第一块地基。地基打歪了,后面盖的楼越高越危险。
2. 前期准备与环境认知
2.1 三种开发模式,别搞混
JRules的开发工具不是只有一个视图,它有三种模式,新手最容易在这上面迷失。
业务模式(Business Mode):面向业务人员,界面极简,只能操作决策表、规则流这类面向业务的可视化元素,看不到底层的规则语言和Java代码。这个模式对开发人员没什么用,但对业务分析师很友好。
技术模式(Technical Mode):开发人员的主力模式。可以写BAL规则、操作BOM/XOM、配置规则集、打规则包。所有规则相关的技术资产都在这个模式下管理。
企业模式(Enterprise Mode):涉及团队协作、版本控制、与企业存储库关联的开发模式。如果你在团队里开发、需要共享规则资产,必须切换到企业模式。
刚上手的人容易犯的错是:装完JRules,打开Rule Designer,发现界面上这也没有那也没有,急得不行。其实大概率只是没切到正确的模式。在Window > Open Perspective里选择对应的视图,Rule Team Perspective是业务模式,Rule Developer Perspective是技术模式,企业模式则是配置了资源库之后自动启用的。
当前这篇讲的是单个开发者的规则项目创建流程,所以默认使用技术模式。等到后面讲团队协作和版本控制,再单独展开企业模式。
2.2 资源库:规则项目的“大本营”
JRules有一个概念叫“资源库”(Repository),这是很多从开源规则引擎转过来的人不太适应的点。
Drools你建个项目就是本地文件系统,跟Git关联一下就完事。但JRules的设计哲学是:规则资产必须集中存储,统一管理,才能支持多人协作、版本追溯、权限控制。所以它搞了一个基于数据库的资源库(JRBRMS,Java Rule Builder Repository Management System),默认支持Derby,生产环境一般用Oracle或DB2。所有规则项目的元数据、规则定义、规则集配置都存在这个库里。
本地开发和测试阶段,你需要先启动一个资源库实例,然后在Rule Designer里配置数据源连接。我第一次搞的时候就是不知道这个流程,直接File > New > Project,填了名字点Finish,提示创建成功但列表里根本看不到项目,一脸懵。
后来才明白,新建项目之前必须先确保资源库连接是通的。资源库连接不上,项目建了也白建。
2.3 开发环境版本匹配,血泪教训
JRules版本众多,7.0、7.1、8.x,到了IBM手里又出了ODM 8.5、8.6、8.7、8.10等等。不同版本依赖不同的JDK和Eclipse版本,配错了启动都启动不了。
我自己遇到过最无语的一次:项目用的是JRules 7.1,配套的Rule Designer基于Eclipse 3.4,JDK必须用1.6,结果机器上装了JDK 8,启动时报了个莫名其妙的UnsupportedClassVersionError,排查了半天才定位到是JDK版本问题。
还有一次,规则项目里的Java类引用了外部Jar包,这些Jar是JDK 8编译的,但JRules引擎运行在JDK 6环境里,一加载就报NoSuchMethodError,追了很久才发现是编译版本冲突。
所以新建规则项目之前,先把版本矩阵理清楚:
| 组件 | 版本要求 | 说明 |
|---|---|---|
| JDK | 与JRules版本匹配(如7.1用JDK 1.6,8.x可能用JDK 1.7/1.8) | 建议安装多个JDK,用环境变量切换 |
| Eclipse | 由Rule Designer自带,不要手动升级 | 手动升级Eclipse极易导致插件不兼容 |
| 资源库 | 默认Derby即可;团队生产环境建议Oracle/DB2 | 本地开发不必追求生产级配置 |
| 应用服务器 | 按需配置(WebSphere、Tomcat等) | 本地调试可以先不配,用内置执行服务器 |
这里强调一句,版本匹配是硬规矩,不要挑战,不要侥幸。你花一小时升级了一个“看起来挺好”的新版JDK,可能换来一整天的环境排错。老老实实按官方兼容矩阵来,烦恼少一大半。
3. 新建规则项目的完整步骤
3.1 启动资源库并准备开发环境
先装好Rule Designer,这一步踩过坑的都懂,我直接给标准操作流程:
第一,启动Rule Designer,选择Workspace目录。建议单独建一个目录,不要跟其他Java项目的Workspace混在一起,规则项目和其他项目的构建路径、依赖关系容易互相干扰。
第二,配置资源库连接。在Rule Designer中执行以下操作:
- 打开Window > Preferences,找到Rule Projects分类下的Repository连接配置项
- 添加一个新的Repository连接,默认使用本地Derby数据库,连接URL类似
jdbc:derby://localhost:1527/rulemgmt - 填写用户名和密码,默认一般是
rtsadmin/rtsadmin,如果记不清了,装的时候注意看一下安装日志
第三,测试连接成功。连接失败时,先检查Derby服务是否启动。JRules安装目录下有启动脚本(start_server.bat或start_server.sh),手动启动一次,再回Rule Designer里重试。
第四,启动本地执行服务器。本地调试规则集时需要一个执行环境,JRules自带了一个基于Tomcat的执行服务器(RES,Rule Execution Server)。确保它能正常启动,规则跑起来才有地方。
3.2 新建项目向导:关键配置项逐字段说明
资源库通了,开发环境正常,下一步就是真正的新建项目。在Rule Designer中执行File > New > Rule Project,弹出新建向导。
这里有几个关键配置项,一个个说:
Project name:项目名称,命名规则跟Java项目类似,建议用有业务含义的名字,比如PremiumCalcRules、CreditCheckRules。别起test1、newproject这种名字,规则项目维护周期长达数年,项目名会出现在部署包、资源库目录、日志里,取个好名字能省很多事。
Project location:项目在本地文件系统中的存放路径。默认会在Workspace下生成同名目录。如果你有特殊的目录规划,可以自定义,但不建议放在含有中文或空格的路径下,某些版本在解析路径时会有兼容性问题。
Rule project type:JRules的项目类型选择。这个要重点讲,它决定了项目的基础能力。
| 项目类型 | 说明 | 适用场景 |
|---|---|---|
| Rule Project | 基础规则项目,可以创建规则、决策表、规则流、规则集 | 大多数规则应用的默认选择 |
| Java Project | 普通Java项目,可以引用已有的规则项目 | 需要把规则项目打包发布为普通Java程序的场景 |
实际开发中还有一个常见的组合:先用Rule Project建规则资产,同时建一个Java Project作为规则应用宿主,通过RuleApp API加载并执行规则集。如果你用的是新版ODM,项目类型里还会出现Business Rule Project、Decision Service Project之类的细分类型,本质上是把之前的规则资产和部署配置进一步区分开了。
Use a specific rule runtime version:是否指定规则引擎的目标版本。一般选择与当前安装的Rule Designer版本一致即可。这里要注意,如果你的规则项目最终要部署到生产环境的JRules服务器上,目标运行版本必须和生产环境一致,不然部署后运行行为可能会有差异。
配置完成点Finish,项目就建出来了。
3.3 项目创建后的默认结构和使用方式
项目建好后,Rule Designer左侧的Project Explorer里能看到一堆文件和目录。刚建完时别急着写规则,先把目录结构和各自用途搞清楚。做一个简单的“规则项目导航”:
MyRuleProject/ ├── src/main/java // Java类源码(XOM层代码通常放这里) ├── src/main/resources // 资源文件 ├── src/test/java // 测试代码 ├── brms // 规则资产目录(重点) │ ├── mypackage // 规则包(Rule Package) │ │ ├── .brm // 规则集配置文件 │ │ ├── balance.bal // 规则文件(BAL语言写的规则) │ │ └── decisiontable.dtable.xml // 决策表文件 ├── itm // 技术模型目录(XOM定义、BOM映射关系等) │ ├── model │ └── pom.xml ├── pom.xml └── build.properties这个结构并不绝对,不同版本可能略有差异,但brms和itm两个核心目录是固定的。brms下存的是规则资产——你写给业务看的规则;itm下存的是实现资产——规则和Java之间的桥接层。
了解这个结构有实际意义:你在写规则时,规则文件里引用的业务对象(比如Order、Customer、Premium)并不是直接从Java类里取的,而是通过itm目录下的BOM(Business Object Model)映射过来的。JRules有一个巧妙的抽象:业务人员看到的是业务友好的对象模型(BOM),技术人员维护的是底层Java对象模型(XOM),两者通过映射配置关联。新建项目的时候这个映射关系是空的,所以你得先定义BOM,规则里才能引用业务对象。
3.4 配置项目构建路径和依赖
项目建好不代表万事大吉。很多新手在建完项目后直接开始写第一条规则,结果发现规则里引用不了任何Java类,或者编译直接报错。
原因是漏了关键一步:配置项目的构建路径,把规则引擎的API和依赖库加进去。
在项目上右键 > Properties > Java Build Path > Libraries,需要确认以下几类依赖是否齐全:
- JRules引擎的核心库(通常位于JRules安装目录的
lib文件夹下,如jrules-res-execution.jar、jrules-engine.jar等) - 规则项目引用的外部业务库(比如你的规则要使用的领域对象、服务类的Jar包)
- 应用服务器运行时的依赖(如果规则集要部署到WebSphere等服务器,可能需要引入对应的J2EE API)
另外在Rule Project的Properties里,还需要检查“Rule Project”相关的设置,确认资源库连接、项目依赖关系等配置正确。
之所以强调这一步,是因为JRules编译规则集时,底层会调用Java编译器把BAL规则翻译成Java代码再编译。构建路径不全,翻译出来的代码引不到类,直接编译失败。
4. 规则编写的核心概念与第一个规则
4.1 规则集、规则引擎与执行流程
项目建好了,紧接着就是写第一条规则。但要写出像样的规则,先得把几个基本概念搞清楚。
规则集(Rule Set)是JRules中的核心概念之一。它是一组规则的集合,这些规则可能在同一个业务域里,比如“保费计算规则集”包含正常费率规则、折扣规则、加费规则等等。规则集是部署和执行的最小单位。
规则引擎(Rule Engine)是执行规则集的基础设施。它有一个工作区(Working Memory),规则执行时,引擎从工作区读取事实对象(Fact),不断匹配规则条件、执行规则动作,直到没有可触发的规则为止。这个过程被称为“推理循环”(Inference Loop)。
生活化类比一下:把规则引擎想象成一支装修队,事实对象就是房子的现状,规则集就是装修标准手册。装修队(引擎)先观察房子(匹配条件),然后按手册执行操作(执行动作);房子变了(规则动作修改了事实对象),再重新观察、再执行,直到房子达到所有条款的要求。
BAL规则是JRules提供的一种接近自然语言的规则书写语言。看起来像英文句子,比如:
if the order is urgent then increase the shipping cost by 20%;这里的the order is urgent是条件部分,increase the shipping cost by 20%是动作部分。BAL的优雅之处在于它屏蔽了Java的语法噪音,业务人员也能读懂。但BAL并不是纯文本随意写的,它在Rule Designer里有专门的编辑器,带语法提示、自动补全,编译时还会做语义检查。你写规则时,编辑器会自动识别order、shipping cost这些词汇——前提是这些词汇已经在BOM里定义好了。
4.2 创建BOM与词汇表
规则是面向业务词汇的,但底层Java代码不认识“order”和“shipping cost”这些词。这中间的桥梁就是BOM。
BOM的本质是一张映射表:把Java类、Java方法、Java属性,映射成业务友好的词汇和逻辑表达。比如Java类com.example.Order映射成“order”,getAmount()方法映射成“amount”,isUrgent()方法映射成“urgent”。
在JRules的实际操作中,BOM有“技术BOM”(XOM)和“词汇表”(Vocabulary)两个层次:
- XOM(eXecution Object Model):真实执行的Java对象模型,就是普通的Java类
- BOM(Business Object Model):面向业务的模型,规则里写的业务词汇对应的就是这个
- 词汇表(Vocabulary):BOM中属性、方法、条件、动作所使用的业务术语定义,即规则语言中业务词汇的字典
新建规则项目后,如果要写规则,先确认XOM类是否存在;然后通过Rule Designer的BOM编辑器,把XOM类导入到项目并映射为BOM;再定义词汇表,为BOM中的元素指定业务词汇——比如方法getOrderAmount()在规则语言中显示为“the order amount”。这套映射配置完成后,规则编辑器就认识业务词汇了。
坦白说,第一次接触这个体系的人会觉得很绕:Java写得好好的,为什么要多一层BOM和词汇映射?原因是规则不是给机器看的一等公民,它要给业务人员阅读、审核、维护。业务人员不关心OrderVO.getShippingFee()这种表达,他们说的是“加急订单加收20%运费”。BOM和词汇表就是把这句人话翻译成机器语言的“词典”。
4.3 手动创建第一条规则
理论说了一堆,来一条实在的。
场景:一个订单运费计算需求,要求当订单加急时,运费上浮20%。
第一步,创建XOM类。在项目的src/main/java下新建一个Order类:
package com.example.rules.model; public class Order { private String orderId; private double amount; private double shippingCost; private boolean urgent; public Order(String orderId, double amount, double shippingCost, boolean urgent) { this.orderId = orderId; this.amount = amount; this.shippingCost = shippingCost; this.urgent = urgent; } // getters and setters public String getOrderId() { return orderId; } public void setOrderId(String orderId) { this.orderId = orderId; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } public double getShippingCost() { return shippingCost; } public void setShippingCost(double shippingCost) { this.shippingCost = shippingCost; } public boolean isUrgent() { return urgent; } public void setUrgent(boolean urgent) { this.urgent = urgent; } }第二步,定义BOM映射。在Rule Perspective中执行“Insert > Business Object Model”,选择从现有Java类导入XOM,选中Order类,生成对应的BOM。生成后,可以修改部分元素的业务名称:
orderId→订单编号amount→订单金额shippingCost→运费urgent→加急
第三步,写规则。在brms下新建一个规则包,为规则包新建规则集,然后为规则集添加规则。编辑器里写:
if the Order is urgent then set the Order shippingCost to the Order shippingCost plus (the Order shippingCost * 0.2);如果BOM映射正确,规则编辑器里the Order后面会自动补全is urgent,then后面自动补全shippingCost相关操作。写完后,可以点编辑器上的执行按钮或通过执行服务器模拟运行,把创建好的Order实例作为事实传入,观察执行结果。
4.4 规则集和规则包的工程化理解
写第一条规则时容易忽略的一个点是“规则集”和“规则包”的角色分工。
规则包(Rule Package)是规则的组织单元。它承载了:
- 一组规则文件
- 可选的数据模型定义(BOM)
- 可选的决策表、决策树等规则文件
- 规则的变量和全局信息
规则集(Rule Set)则是在规则包基础上的可执行配置。它指定了:
- 该规则集包含哪些规则包中的规则
- 规则执行时需要的输入/输出类
- 规则执行的路径(Ruleflow)和决策表
- 生成二进制规则集文件时的参数
打个比方:规则包是“规则的文件柜”,里面分门别类放着规则;规则集是“用哪些规则来处理哪类业务问题的手册”。同一个规则包可以配置出多个规则集,应对不同的业务场景,这是JRules在工程上比较灵活的地方。
我实际建项目时的习惯是:每个业务模块建一个规则项目,项目下按业务子域划分规则包(比如premium.base、premium.discount、premium.risk),再为每个对外功能点配置一个规则集(比如premium.calculate)。这样后期排查问题时,定位到具体规则包和规则集非常快。
5. 常见问题与排查技巧实录
5.1 资源库连接失败,项目无法创建
这是新建项目阶段出现频率最高的问题,没有之一。
现象:配置资源库连接后,点Test Connection提示失败,或者新建项目向导走到最后一步报错“Cannot connect to repository”。
排查步骤:
- 检查Derby进程是否启动。JRules安装目录下执行
start_server.bat,看控制台是否正常输出启动日志。注意Derby启动到就绪需要一点时间,看到Startup successful字样再继续。 - 检查端口是否被占用。Derby默认监听1527端口,被占用时换个端口或结束占用进程。
- 检查连接URL是否写对。新版JRules的默认URL末尾可能要加
;create=true参数表示自动创建数据库,不同版本略有差异。 - 检查用户名密码。安装时的默认账号和后续修改过的账号容易混,建议在安装文档里确认后再填。
经验之谈:我遇到过一次非常隐蔽的问题——Rule Designer和Derby的JVM位数不一致,一个是32位一个是64位,数据库连接直接报错。后来统一了JDK位数才解决。Windows下尤其容易碰到这种问题,建议开发机统一用64位JDK+64位Derby+64位Rule Designer。
5.2 规则编辑器不识别业务词汇
现象:规则编辑器里输入if the Order is urgent后,urgent没有高亮,回车后直接红叉,编译报错。
原因:BOM映射里没有把Order.isUrgent()方法映射到业务词汇“urgent”,或者映射的类型不对。
解决:
- 检查BOM编辑器里是否成功导入了
Order类,isUrgent()方法是否出现在方法列表里 - 检查词汇表定义中,“urgent”是布尔类型还是字符串类型,必须与Java方法的返回类型匹配
- 确认规则中使用的业务词汇前缀是否正确,JRules里通常用“the”作为变量的冠词,比如
the Order表示一个Order类型的对象引用
如果BOM映射没问题但编辑器还是报错,把规则集里的“执行对象模型”刷新一下,有时候是编译缓存的问题。
5.3 规则集编译通过,运行时找不到类
这是最让人抓狂的问题:规则在Rule Designer里测试正常,部署到服务器或者用Java程序调用时,报ClassNotFoundException。
原因:几乎所有这类问题都出在“XOM类没有打进规则集部署包”上。
规则集部署时需要同时携带两类字节码:
- 规则集本身的二进制文件(.jar)
- 规则引用的XOM类(也就是
Order这些Java类)的字节码
JRules在打包规则集时,默认不会把所有引用的Java类都打包进去,需要管理员在构建规则集时,把XOM依赖加入到规则集Jar中或作为应用的一部分部署上去。很多新手项目在本地测试没问题——因为本地类路径里能找到这些类——但部署到服务器后就炸了。
解决:在生成规则集项目(.jar)时,检查构建选项“Add the project to the RuleApp”或“Include XOM in RuleApp”等选项,确认规则引用的XOM已被包含。如果XOM由其他团队维护,则以外部依赖形式发布到目标环境。
5.4 规则执行结果与预期不符
排除部署和编译问题后,最常见的业务逻辑问题是:规则触发了,但结果不对。
举例:我原来写过一个折扣规则,预期是“订单金额满1000元打9折”,实际执行却发现满500元就打了9折。排查之后发现是BOM映射里约定的词汇有歧义,业务人员理解的“订单金额”是订单实付金额,而Java类里的getAmount()返回的却是商品总额(含运费),两个概念对不上。
排查思路:
- 先看规则条件里引用的每个属性,确认它在BOM词汇表中到底映射的是哪个Java方法
- 再确认Java方法的返回值是否符合业务预期
- 利用Rule Execution Server的Trace功能,打开规则执行追踪,查看每次规则触发的条件匹配结果、变量取值变化
JRules自带执行追踪功能,运行时可以打开,能记录每条规则的触发顺序和结果。排查复杂规则问题时,这是最有力的工具,没有之一。
5.5 新手最容易忽视的三个工程习惯
最后分享几个新建规则项目阶段就应该建立的工程习惯,不然后面维护老项目时会想穿越回去打自己。
第一,规则命名要有业务含义。规则在运行时出问题,日志里会打出规则名。叫rule_001的规则和叫UrgentOrderShippingMarkup的规则,出问题时排查效率完全不是一个级别。
第二,规则集和规则包要分清楚。一个项目里可以有很多规则包,但规则集一定要和对外业务功能一一对应。一个规则集对应一个业务场景,不要图省事把所有规则都塞进一个规则集。
第三,版本和变更记录必须维护。JRules的资源库本身有版本能力,但很多开发团队根本不使用,导致上线后出了问题无法回退。建议从第一天起就养成习惯:规则集每次修改后都打一个新版本,保留历史版本记录。
6. 总结与后续规划
走到这里,一个新的JRules规则项目已经从无到有搭起来了:资源库连接、项目创建、构建路径配置、BOM映射、第一条规则编写、常见问题排查,一条线全走通。
我个人在实际操作中最深的体会是:JRules是一个“概念先行”的系统。它不像Drools那样给你一个相对自由的规则书写环境,而是先逼你建立起XOM、BOM、词汇表、规则包、规则集这一整套心智模型。这套模型虽然初学阶段繁琐,但一旦理解并习惯,它的工程化能力——多人协作、版本管理、业务人员参与规则维护——确实比开源框架成熟得多。
下一篇继续聊规则集的具体配置和部署,重点讲RuleApp打包、Rule Execution Server发布,以及不同部署方式(本地RES、远程服务器、嵌入应用)的实操区别。如果你正在接触JRules,可以先把这篇里的步骤亲手走一遍,卡在哪一步基本都能对照常见问题找到答案。规则引擎这个领域,理论再多都是虚的,真正上手建一个项目、写一条规则、部署一次跑通,你对它的理解才算是入了门。