我们正在使用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);
一些帮助将非常有用。
答案 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.
希望它有所帮助,