2014-10-28 130 views
0

我有一個junit測試用例,它創建兩個線程來運行應用程序。在這個應用程序中,有一個方法updateStatus用於fire drools規則。而在這個規則文件,我有一些功能,如未來:多線程連接錯誤

function Object updateItem() { 
    ..... 
} 

function boolean isNullOrEmpty(Object obj) { 
    ... 
} 

function Object getValueFromFact(Object obj) { 
    .... 
} 

我重新啓動我的tomcat,運行這個單元測試,但一個線程失敗,錯誤是:

org.apache.cxf.interceptor.Fault: loader (instance of org/drools/rule/JavaDialectRuntimeData$PackageClassLoader): attempted duplicate class definition for name: "com/icil/sofs/booking/rules/GetValueFromFact"

「getValueFromFact '是規則文件中定義的函數。

然後再次運行它,而不重新啓動tomcat,沒有錯誤。然後運行第三次而不重新啓動tomcat,也沒有錯誤。

嘗試後,我發現'重複類'錯誤只發生在重新啓動tomcat後第一次運行。

我還發現,第一次,2個線程在「同一時間」執行'knowldegeSession.execute()',但2個線程在第二次和第三次依次運行'knowledgeSession.execute()'時間。

那麼爲什麼這個錯誤'重複的類定義'總是在第一次運行後發生,重新啓動後tomcat?

以及爲什麼錯誤是函數'getValueFromFact'(這是規則文件中的第3個函數)而不是第一個函數'updateItem'(這是規則文件中的第一個函數)?

在此先感謝!

回答

0

因爲有多個線程正在運行'execute()',並且它們在'同一時間'加載函數,所以此錯誤被拋出。

當調用'addKnowledgePackages()'時,drools會加載規則,但此時可能不會加載函數,可能會在調用'execute()'時加載它們。

調試後,我發現如果規則條件在調用'addKnowldegePackages()'時使用mvel表達式而不是java表達式,drools將加載函數。

我正在使用drools 5.5.0.Final,目前我無法將drools升級到6.0,因爲6.0有很大差異。但是我必須找出一個解決方案,因爲這個問題需要儘快解決:

當tomcat啓動時,可以運行代碼'addKnowledgePackages()',例如,把它放在一個靜態塊中,以及改變你的規則來使用mvel表達式而不是java表達式。