zoukankan      html  css  js  c++  java
  • 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");
  • 相关阅读:
    第2章 创建基础框架
    目录
    工厂方法模式(Factory Method)
    petshop4.0 详解之七(PetShop表示层设计)
    第1章 启动电子商务网站
    第3章 创建商品目录:第Ⅰ部分
    编写一个JAVA应用程序,用户从键盘只能输入整数,程序输出这些整数的乘积
    书上例题练习第一章
    java与C/C++的区别
    安装JDK遇到的问题
  • 原文地址:https://www.cnblogs.com/kobe-lin/p/14141756.html
Copyright © 2011-2022 走看看