Joã*_*ida 5 java weblogic drools kie
我们有一个Java应用程序,其中在Weblogic上部署了不同的模块。我们在不同的模块上使用了流口水,并试图通过将其定义为枚举类来使初始化KieContainer的类成为单例。
但是,似乎在生产环境中(通过耳文件部署应用程序)时,有不同的ClassLoader初始化该类,并且会收到以下异常:
null java.lang.IllegalStateException: There's already another KieContainer created from a different ClassLoader;
at org.drools.compiler.kie.builder.impl.KieServicesImpl.getKieClasspathContainer(KieServicesImpl.java:88);
at org.drools.compiler.kie.builder.impl.KieServicesImpl.getKieClasspathContainer(KieServicesImpl.java:73);
Run Code Online (Sandbox Code Playgroud)
您对如何解决这个问题有任何建议吗?
小智 3
尽管在不同的环境(Kafka、Weld SE)中,我们也遇到了同样的问题。虽然违反直觉,但调用
// Answer the cuurent container if it exists else create a new container
KieServices.Factory.get().getKieClasspathContainer();
Run Code Online (Sandbox Code Playgroud)
不是
// Always create a new container
KieServices.Factory.get().newKieClasspathContainer();
Run Code Online (Sandbox Code Playgroud)
为我们解决了大部分问题。
另外,在容器超出范围之前,请务必调用:
KieServices.Factory.get().getKieClasspathContainer().dispose();
Run Code Online (Sandbox Code Playgroud)
这将从 Drools 全局单例中释放容器及其资源。
我们在 Maven 中运行单元测试时也遇到了问题,因为 Surefire 插件默认情况下不会在每次测试时重新创建 JVM,而 Drools 则假定每次 JVM 调用只会创建一次其全局单例的实例。这个问题可以通过让 Surefire 在每次测试时重新创建一个干净的 JVM 环境来解决。通过添加来调整您的 pom.xml
<reuseForks>false</reuseForks>
Run Code Online (Sandbox Code Playgroud)
到您的 Surefire 配置。例如:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>default-test</id>
<configuration>
<reuseForks>false</reuseForks>
</configuration>
</execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
此外,您可能会考虑为每个 Java EE 模块分配其自己的 KieContainer
KieContainer getKieClasspathContainer(String containerId);
Run Code Online (Sandbox Code Playgroud)
这将允许每个 Java EE 模块的生命周期与每个 Drools 容器模块的生命周期同步。