Drools规则编写报Unterminated Collection Element错误排查
Drools规则报
unterminated collection element错误定位 该错误是规则编译阶段的语法解析错误,并非运行时进入else分支才触发的异常——报错位置指向if/else交界处,只是解析器读取到该位置时才识别到语法结构不匹配。
触发原因
Drools默认使用MVEL作为then块的表达式解析器,该解析器对if-else结构的花括号位置有严格要求:不支持if块的闭合}和后续的else关键字拆分到不同行。
当前代码中if块的写法为:
if (enquiry.isEmpty()) { $block.getBusinessValidationResult().add(ValidationResult.NOT_FOUND); $block.getMsg().setStatusText(Constants.NOT_FOUND); } else {
MVEL读取到单独成行的}时,会优先将其识别为内联集合/Map字面量的闭合标记,不会关联下一行的else组成完整if-else结构。由于这个}前面不存在合法的集合起始定义,解析器判定集合结构未正常闭合,就抛出unterminated collection element错误。
另外代码中还存在一处会触发后续运行时错误的笔误:else块第一行使用了未定义的变量statusEnquiry,实际try块中定义的查询结果变量名为enquiry。
修复方案
- 调整if-else的花括号格式,将闭合
}和else写在同一行,即改成} else {的形式 - 修正变量名笔误,把
statusEnquiry.getString(Constants.NUMBER)改成enquiry.getString(Constants.NUMBER)
修复后对应代码段参考:
then Service $service = new Service(); try { JsonObject enquiry = $service.execute($block.getTransaction().getNumber()).get(); if (enquiry.isEmpty()) { $block.getBusinessValidationResult().add(ValidationResult.NOT_FOUND); $block.getMsg().setStatusText(Constants.NOT_FOUND); } else { String numberFromService = enquiry.getString(Constants.NUMBER); String cardExpiryFromService = enquiry.getString(Constants.EXPIRY_DATE); // 剩余原有业务逻辑保持不变即可
补充:如果使用的是Drools 8+版本,也可以在规则配置中指定then块使用Java语言解析,避免MVEL的特殊语法限制,但要保证then块代码完全符合Java语法规范。
内容的提问来源于stack exchange,提问作者Spitz
相关产品推荐
相关产品推荐

