2017-07-06 26 views
2

我們有一個Java應用程序,它在Weblogic上部署了不同的模塊。我們在不同的模塊上使用drools,並試圖通過將KieContainer定義爲一個枚舉類來初始化KieContainer。來自不同ClassLoader的Drools KieContainer

然而,似乎當我們在生產環境(其中應用程序是通過EAR文件部署)有不同的類加載器初始化這個類,我們可以得到以下異常:

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); 

你有什麼建議如何解決這個問題?

回答

1

雖然在不同的環境中我們有同樣的問題(Kafka,Weld SE)。雖然反直覺的,調用

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

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

固定的大多數事情對我們來說。

此外,容器超出範圍之前,一定要調用 KieServices.Factory.get()。getKieClasspathContainer()。Dispose()方法 來釋放Drools的全球單容器和它的資源。

我們在Maven中運行單元測試時也遇到問題,因爲默認情況下,Surefire插件不會爲每個測試重新創建一個JVM,而Drools假定每個JVM調用只創建一次它的全局單例實例。這可以通過Surefire爲每個測試重新創建一個乾淨的JVM環境來解決。加入

<reuseForks>false</reuseForks> 

你一定能成功的配置調整 的pom.xml 。例如:

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

此外,你可能會考慮將每個Java EE模塊自身的KieContainer

KieContainer getKieClasspathContainer(String containerId); 

這將使每個Java EE組件的生命週期將被同步到每個Drools的容器模塊。