2014-10-28 114 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表达式。