Drools KieContainer from another ClassLoader

We have a Java application with various modules that are deployed to Weblogic. We are using drools in different modules and trying to make a class that initializes the KieContainer singleton by defining it as an enum class.

However, it looks like when we are in a production environment (where the app is deployed via an ear file) there are various ClassLoaders initializing this class and we get the following exception:

null    java.lang.IllegalStateException: There 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);

      

Do you have any suggestion on how to solve this?

+3


source to share


1 answer


We had the same problem, albeit in a different environment (Kafka, Weld SE). Although intuitive, defiant

// Answer the cuurent container if it exists else create a new container
KieServices.Factory.get().getKieClasspathContainer();

      

not

// Always create a new container
KieServices.Factory.get().newKieClasspathContainer();

      

fixed most things for us.

Also, before the container goes out of scope, be sure to call:

KieServices.Factory.get().getKieClasspathContainer().dispose();

      

This will free the container and its resources from the Drools global singleton.



We also had problems running unit tests in Maven, since by default the Surefire plugin does not recreate the JVM per test, and Drools assumes that its global singleton will be instantiated only once when the JVM is called. This is resolved if Surefire recreates a clean JVM environment for each test. Adjust pom.xml by adding

<reuseForks>false</reuseForks>

      

to your Surefire configuration. For example:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <executions>
        <execution>
            <id>default-test</id>
            <configuration>
                 <reuseForks>false</reuseForks>
            </configuration>
        </execution>
       </executions>
  </plugin>

      

Alternatively, you might consider assigning each Java EE module its own KieContainer

KieContainer getKieClasspathContainer(String containerId);

      

This will keep the lifecycle of each Java EE module in sync with the content of each Drools container module.

+2


source







All Articles