JUnit测试在使用Drools 5.4.0.Final和JDK 8时无法正常工作

24

最近我开始升级我的应用程序JDK版本,从jdk1.7.0_121_x64升级到jdk1.8.0_202_x64。我有一些使用Drools 5.4.0.Final的旧代码。这段代码在JDK版本jdk1.7.0_121_x64下运行正常。

Maven依赖关系如下:

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-core</artifactId>
    <version>5.4.0.Final</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-decisiontables</artifactId>
    <version>5.4.0.Final</version>
</dependency>

DRL文件的加载方式如下:

final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(resource, ResourceType.DRL);
knowledgeBase.addKnowledgePackages(kbuilder.getKnowledgePackages());

我知道在使用JDK 8时使用Drools可能会出现问题。我参考了其他SO线程进行了起步。


当我使用JDK 8构建我的应用程序并执行Junit测试时,测试失败并显示错误:

testRunRule(com.company.app.RuleTest)  Time elapsed: 0.073 sec  <<< ERROR!
java.lang.RuntimeException: java.lang.RuntimeException: wrong class format
    at org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader.<init>(ClassFileReader.java:372)
    at org.drools.commons.jci.compilers.EclipseJavaCompiler$2.createNameEnvironmentAnswer(EclipseJavaCompiler.java:287)
    at org.drools.commons.jci.compilers.EclipseJavaCompiler$2.findType(EclipseJavaCompiler.java:258)

此SO线程所述,我找到了这个bugfix票据DROOLS-329的参考。


根据这个bugfix票据中提到的方法,我尝试使用JANINO编译器:

添加以下Maven依赖项:

<dependency>
    <groupId>org.codehaus.janino</groupId>
    <artifactId>janino</artifactId>
    <version>2.5.16</version>
</dependency>

我添加了以下VM参数(我是从Eclipse运行测试的,因此在Eclipse启动配置中的JRE VM参数中添加了该参数):

我添加了以下VM参数(我是从Eclipse运行测试的,因此在Eclipse启动配置中的JRE VM参数中添加了该参数):

-Ddrools.dialect.java.compiler=JANINO

我仍然看到了错误的类格式错误。因此,我修改了我的代码,将DRL文件加载为:

final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
final Properties props = new Properties();
props.setProperty("drools.dialect.java.compiler", "JANINO");
final KnowledgeBuilderConfiguration config = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration(props, null);
final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(config);
kbuilder.add(resource, ResourceType.DRL);
knowledgeBase.addKnowledgePackages(kbuilder.getKnowledgePackages());

没用,我仍然能看到错误的类格式错误。


我按照这个外部链接提到的另一种方法尝试。我更新了Maven依赖,添加/更新如下:

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-core</artifactId>
    <version>5.4.0.Final</version>
    <exclusions>
      <exclusion>
          <groupId>org.mvel</groupId>
          <artifactId>mvel2</artifactId>
      </exclusion>
   </exclusions>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-decisiontables</artifactId>
    <version>5.4.0.Final</version>
    <exclusions>
      <exclusion>
          <groupId>org.eclipse.jdt.core.compiler</groupId>
          <artifactId>ecj</artifactId>
      </exclusion>
      <exclusion>
          <groupId>org.mvel</groupId>
          <artifactId>mvel2</artifactId>
      </exclusion>
   </exclusions>
</dependency>
<dependency>
    <groupId>org.mvel</groupId>
    <artifactId>mvel2</artifactId>
    <version>2.1.9.Final</version>
</dependency>
<dependency>
   <groupId>org.eclipse.jdt.core.compiler</groupId>
   <artifactId>ecj</artifactId>
   <version>4.6.1</version>
</dependency>

mvel2 补丁是使用以下方式构建的: https://github.com/mkornipati/mvel/tree/2.1.9.Final.Patch

由此,错误的类格式问题已经解决。但我的测试现在失败,出现以下错误:

testRunRule(com.company.app.RuleTest))  Time elapsed: 4.684 sec  <<< ERROR!
java.lang.RuntimeException: org.drools.rule.InvalidRulePackage: Rule Compilation error : [Rule name='ruleCheck']
    org/drools/template/parser/Rule_ruleCheck_8eb4621227714a36b7b84c8b764527e4.java (2:80) : Only a type can be imported. java.util.Map resolves to a package
    org/drools/template/parser/Rule_ruleCheck_8eb4621227714a36b7b84c8b764527e4.java (2:101) : Only a type can be imported. java.util.HashMap resolves to a package
    org/drools/template/parser/Rule_ruleCheck_8eb4621227714a36b7b84c8b764527e4.java (6:299) : org.drools.spi.KnowledgeHelper cannot be resolved to a type
    org/drools/template/parser/Rule_ruleCheck_8eb4621227714a36b7b84c8b764527e4.java (6:339) : org.drools.template.parser.Row cannot be resolved to a type
    org/drools/template/parser/Rule_ruleCheck_8eb4621227714a36b7b84c8b764527e4.java (6:373) : org.drools.FactHandle cannot be resolved to a type
    org/drools/template/parser/Rule_ruleCheck_8eb4621227714a36b7b84c8b764527e4.java (6:411) : org.drools.template.parser.DefaultGenerator cannot be resolved to a type
    org/drools/template/parser/Rule_ruleCheck_8eb4621227714a36b7b84c8b764527e4.java (6:487) : org.drools.runtime.rule.RuleContext cannot be resolved to a type
    at org.drools.rule.Package.checkValidity(Package.java:445)
我不知道该怎么继续下去。如果你能让Drools 5.4适配JDK 8,请告诉我。

3
感谢你的努力,但我希望能获得一个答案。 - Eugene
你考虑过升级Drools吗? - Boris
@Boris:尝试使用Drools 5.6.0.Final版本,输出结果与5.4.0.Final版本相同。 - user613114
1
@Boris:只有在确有必要的情况下才会这样做:1)我们没有关于此代码的任何文档。编写此代码的人已经离开了我们。2)需要额外的努力来迁移/测试此代码。Drools API本身已经发生了改变。3)有人引用能够很少修改就可以在JDK 8上运行Drools 5.x的参考资料(例如我发帖中提到的URL)。因此,我真的会尝试使用更简单的方法使其运行。 - user613114
那个 RuleTest 类在哪里? - hfontanez
显示剩余7条评论
1个回答

1
我使用了Drools 7.7.0和Java 8,效果非常好。我不确定哪个是与Java 8兼容的最旧版本Drools。话虽如此,Drools 5.4.0于2011年发布。Java 8在2014年发布,因此您可以假设它不兼容。Java 7于2011年7月发布。根据5.4.0发布的时间,它可能兼容也可能不兼容。基于这一点,我预计Drools 5.4.0与Java 6或更早版本兼容。如果您想使用Java 8和Drools,则必须升级。我认为最早兼容的版本是6.1.0 download.jboss.org/drools/release
总之:要么将项目降级为Java 6以使用Drools 5.4.0,要么升级Drools以使用6.1.0。更好的选择是升级到最新的Drools,然后找出它支持的最新Java版本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接