• 那些Drools规则的坑(各种疑难杂症汇集)


    自定义方法函数调用的坑

    今天写了一段drools脚本,运行不报错,但是结果一直不正常,详细研究发现自定义方法函数调用是有坑的。
    代码如下:

    /*
    抽取日期串中的月日,转成数字。输入串: 20220831,返回831.
    */
    function int monthDay(String date) {
        if (date == null){
            return 0;
        }
        String md = date.substring(4);
        return Integer.parseInt(md);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    调用函数如下:

    int monthDay = monthDay($a.data_date);
    log.debug("monthDay = {}", monthDay);
    if (monthDay <= 430) {
        $a.corp_quar_date_2 = "0430";
    } else if (monthDay <= 830) {
       $a.corp_quar_date_2 =  "0630";
    } else if (monthDay <= 1031){
       $a.corp_quar_date_2 = "0930";
    } else {
       $a.corp_quar_date_2 = "1231";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行发现,无论$a.data_date是多少,结果一直是"1231"。
    查看日志,发现log.debug调试输出是:

    monthDay = org.mvel2.util.MethodStub@7d37f1c
    
    • 1

    估计是函数根本没执行,所以一直走到了else分支了。多次调试发现,改成如下写法就正确了:

    //int monthDay = monthDay($a.data_date);
    log.debug("monthDay = {}", monthDay($a.data_date));
    if (monthDay($a.data_date) <= 430) {
        $a.corp_quar_date_2 = "0430";
    } else if (monthDay($a.data_date) <= 830) {
       $a.corp_quar_date_2 =  "0630";
    } else if (monthDay($a.data_date) <= 1031){
       $a.corp_quar_date_2 = "0930";
    } else {
       $a.corp_quar_date_2 = "1231";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    然而,这样写法每次if比较都要调用一下函数,多浪费呀!我最后是把这个函数放java里了,不知大家由没有更好的办法。
    最后的脚本如下:

            int monthDay = DrlUtils.monthDay($a.data_date);
            log.debug("monthDay = {}", monthDay);
            if (monthDay <= 430) {
            ...
    
    • 1
    • 2
    • 3
    • 4

    日志的坑

    如下一段脚本,一直出很奇怪的错误。

            log.trace("6)	公司投资级判定 -----");//消息里面的"()"也要配对!!!
    
            if (($a.listed_company_flag == "T" || DrlUtils.in($a.exchange_cd, "1", "2", "3", "4"))
                && $a.debt_flag == "T"
                && $a.corp_fin_report_valid_flag_solo == "T"
                && $a.corp_fin_report_0_flag_solo_3years == "T"
                && $a.latest_quar_corp_fin_report_valid_flag_solo == "T"
                && $a.latest_quar_corp_fin_report_0_flag_solo == "T"){
                ...
                }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    看着不复杂,单规则编译老是出错:

    [Error: [Error: was expecting type: java.lang.Boolean; but found type: <Unknown>]
    [Near : {...  ....}]
                 ^
    [Line: 1, Column: 0]]
    [Near : {... ntl_overdue_flag == "F"; ....}]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    多次实验,终于找到原因:日志里面有个不封闭的括号!!!
    改成如下就好了:

            log.trace("(6)	公司投资级判定 -----");//消息里面的"()"也要配对!!!
    
            if (($a.listed_company_flag == "T" || DrlUtils.in($a.exchange_cd, "1", "2", "3", "4"))
                && $a.debt_flag == "T"
                && $a.corp_fin_report_valid_flag_solo == "T"
                && $a.corp_fin_report_0_flag_solo_3years == "T"
                && $a.latest_quar_corp_fin_report_valid_flag_solo == "T"
                && $a.latest_quar_corp_fin_report_0_flag_solo == "T"){
                ...
                }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    if else 语句的坑

    if else后面的花括号”{“不能放在新的一行,如下写法不行:

    if (true)
    { //这里{不能换行
    ...
    }
    
    • 1
    • 2
    • 3
    • 4

    要写成如下:

    if (true) {//这里的“{”不能换行
    ...
    }
    
    • 1
    • 2
    • 3

    注释的坑

    参见: https://blog.csdn.net/weixin_45357522/article/details/126538871

    其它小技巧

    drools文件格式化

    idea不支持直接对drl文件格式化,我们可以创建一个临时js,把then后面的语句复制到js文件里,对js文件格式化,再复制回去。

  • 相关阅读:
    Java——Stream流的学习
    JVM 内存和 GC 算法
    Vue学习笔记
    你真的了解微服务架构吗?
    常用的开源网关 API Gateway
    汽车安全气囊设计?Abaqus/Part特殊建模方法-附案例step-by-step教学
    [maven] 实现&使用 plugin 及 properties 简述
    AUTOCAD——文字显示方式、CAD怎么直接打开天正图纸
    水生植物拉丁文及缩写
    海底世界-第11届蓝桥杯Scratch省赛真题第3题
  • 原文地址:https://blog.csdn.net/weixin_45357522/article/details/126540070