【问题标题】:Disable JIT in Drools 6.2 with Java 8使用 Java 8 在 Drools 6.2 中禁用 JIT
【发布时间】:2015-10-12 05:56:42
【问题描述】:

我们正在使用 Drools 版本 6.2.0.Final 来解析我们的一些规则。但有时当我们运行很多次时,Drools 会调用导致失败的 JIT 编译器。我们在 Junit 测试中涵盖了这一点,我们收到以下错误

java.lang.NoSuchMethodError: org.mvel2.compiler.BlankLiteral.<init>(Ljava/lang/String;)V
at ConditionEvaluatoref4dc802b6174038b0307f5e6196e229.evaluate(Unknown Source)
at org.drools.core.rule.constraint.MvelConstraint.evaluate(MvelConstraint.java:248)
at org.drools.core.rule.constraint.MvelConstraint.isAllowed(MvelConstraint.java:204)
at org.drools.core.reteoo.AlphaNode.assertObject(AlphaNode.java:141)
at org.drools.core.reteoo.CompositeObjectSinkAdapter.doPropagateAssertObject(CompositeObjectSinkAdapter.java:494)
at org.drools.core.reteoo.CompositeObjectSinkAdapter.propagateAssertObject(CompositeObjectSinkAdapter.java:384)
at org.drools.core.reteoo.ObjectTypeNode.propagateAssert(ObjectTypeNode.java:298)
at org.drools.core.phreak.PropagationEntry$Insert.execute(PropagationEntry.java:93)
at org.drools.core.phreak.SynchronizedPropagationList.flush(SynchronizedPropagationList.java:96)
at org.drools.core.phreak.SynchronizedPropagationList.flush(SynchronizedPropagationList.java:69)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.flushPropagations(StatefulKnowledgeSessionImpl.java:1993)
at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1289)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.internalFireAllRules(StatefulKnowledgeSessionImpl.java:1294)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1281)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1260)
at org.drools.core.impl.StatelessKnowledgeSessionImpl.execute(StatelessKnowledgeSessionImpl.java:306)

我们在 Java 7 中也遇到了这个错误,但是通过使用选项来避免这个错误

KieBaseConfiguration kbConfig = KieServices.Factory.get().newKieBaseConfiguration();
kbConfig.setOption(PermGenThresholdOption.get(0));

设置此选项禁用 JIT,我们的代码运行良好。但由于 Java 8 完全删除了 PermGen 选项,我无法找到实现相同目标的选项。当执行大量运行时,这会导致规则失败。

我尝试了很多选项来禁用它,但无法让它工作。

- OptimizerFactory.setDefaultOptimizer(OptimizerFactory.SAFE_REFLECTIVE);
- System.setProperty("-Ddrools.dialect.java.compiler", "JANINO");
- System.setProperty("-Djava.compiler", "NONE");
- System.setProperty("-Dmvel2.disable.jit", "true");
- kbConfig.setOption(RuleEngineOption.PHREAK);

一些帮助将非常有帮助。

【问题讨论】:

  • 您应该澄清这不是 Java 的 JIT。 - 但是,它看起来像一个 MVEL 错误,您应该在 Drools JIRA 上报告它 - 并附有重现问题的示例。

标签: java drools jit kie


【解决方案1】:

在进行大量调试后,我们发现我们的一条规则导致了问题。但是规则是有效的,我们不能放弃它。

最后我找到了一种禁用 JIT 编译器的方法,它解决了我们的问题并且错误消失了。这是与 Esteban Aliveti 提到的不同的解决方案。下面提到的一种适用于我们的案例,并且适用于大多数案例。

我使用以下方式禁用 JIT 编译器:

KieBaseConfiguration kbConfig = KieServices.Factory.get().newKieBaseConfiguration();
kbConfig.setOption(ConstraintJittingThresholdOption.get(-1));

实际解释如下:

0 -> force immediate synchronous jitting (it's adviced to use this only for testing purposes).
-1 (or any other negative number) -> disable jitting
Default value is 20.

所以一旦我们将 ConstraintJittingThresholdOption 设置为 -1,它就会禁用 JIT 编译器。

【讨论】:

  • 还可以在启动时为运行时赋予以下 JVM 属性:-Ddrools.jittingThreshold=-1
【解决方案2】:

我在 Drools 6.4(也许它也适用于 6.2)中发现禁用 MVEL 表达式的 JIT 编译的方法是将其阈值设置为 0。 JIT 阈值基本上告诉 Drools 在编译 JIT 之前必须计算表达式多少次。阈值 0 表示“从不 JIT 编译表达式”。

我发现这样做的方法是在我的 KieBases 中使用 org.kie.internal.conf.ConstraintJittingThresholdOption KieBaseConfiguration:

KieHelper helper = new KieHelper();
helper.addResource(ResourceFactory.newClassPathResource("rules/jit/jit-sample.drl"));

KieSession ksession = helper.build(ConstraintJittingThresholdOption.get(0)).newKieSession();

我无法从 kmodule.xml 文件中找到方法。

我也没有尝试使用-Ddrools.jittingThreshold=0,但我认为它应该也可以。

注意:在 Drools 中禁用表达式的 JIT 编译的问题在于它会影响整个 KieBase。我建议您进一步调查一下您得到的异常是什么。


编辑:

Satyam Roy 是对的。用于 ConstraintJittingThresholdOption-Ddrools.jittingThreshold 以完全禁用 JIT 编译的 propper 值是负数而不是 0。

希望对你有帮助,

【讨论】:

  • 您好 Esteban Aliverti,感谢您的回答。可用的最新版本是 Drools 6.3.0.Final,我尝试了您的建议。但我无法让它工作。 Drools 6.2 中不存在 org.kie.internal.conf.ConstraintJittingThresholdOption 类,从 6.3 开始引入。
  • 所以我认为你的问题是错误的。这里的问题不是 Drools JIT 编译表达式,而是 MVEL 表达式求值器本身。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-24
  • 1970-01-01
  • 2011-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多