使用Java 8在Drools 6.2中禁用JIT

时间:2015-10-12 05:56:43

标签: java drools jit kie

我们正在使用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);

一些帮助将非常有用。

2 个答案:

答案 0 :(得分:3)

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

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

我使用以下方法禁用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编译器。

答案 1 :(得分:0)

我在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。我建议你进一步调查你得到的例外是什么。

修改

萨蒂扬·罗伊是对的。用于ConstraintJittingThresholdOption-Ddrools.jittingThreshold以完全禁用JIT编译的propper值是负数而不是0.

希望它有所帮助,