• Drools使用注意事项


    使用场景:

    public void doCustomer() {
    //
    People people = new People();
    people.setName("哒");
    people.setSex(1);
    people.setDrlType("people");
    //
    KieServices kieServices = KieServices.Factory.get();
    StatelessKieSession kieSession = kieServices.getKieClasspathContainer().newStatelessKieSession("my-test");
    List<Command> commands = new ArrayList<>();
    KieCommands kieCommands = kieServices.getCommands();
    commands.add(kieCommands.newInsert(people, "input"));

    ExecutionResults execute = kieSession.execute(kieCommands.newBatchExecution(commands));

    }
    项目中,有两个地方调用doCustomer方法,一个是rabbitMq的监听类,一个是Controller接口处
    这两处的调用,由于当前线程的上下文加载器不同,导致只能有其中一处的调用正常,另外一个报错

    异常问题:

    抛出异常There's already another KieContainer created from a different ClassLoader

    解决方案:

    通过分析源码,发现:
    // 使用Holder内部类的方式,创建了一个单例对象
    KieServices kieServices = KieServices.Factory.get();

    // 使用Volatile + Double-Check的方式,创建了一个单例对象;
    KieContainer kieContainer = kieServices.getKieClasspathContainer(); 但是,代码中,会校验classLoader != classpathClassLoader ???

    前者为当前线程上下文类加载器,后者为第一次创建KieContainer的线程类加载器这么一分析,发现是两处的调用,线程上下文加载器不一致导致的报错。
    解决办法之一,就是,在项目启动的时候,初始化 KieServices 和 KieContainer 对象
    或者
    KieServices kieServices = KieServices.Factory.get();
    StatelessKieSession kieSession = kieServices.getKieClasspathContainer(this.getClass().getClassLoader()).newStatelessKieSession("my-test");
  • 相关阅读:
    JavaScript原生对象属性和方法详解——Array对象[转]
    SVN的trunk branch tag (二)
    git入门使用摘录
    文字画工具推荐
    mysql 基础操作
    mobile 测试入门思维导图
    淘宝性能测试线下测试与线上跟踪体系
    github使用入门 之GIT GUI Windows版
    C++ 单向链表反转
    shell脚本实例一,移动文件夹中大于2000B的文件到另一个文件夹
  • 原文地址:https://www.cnblogs.com/kobe-lin/p/14141756.html
Copyright © 2020-2023  润新知