I have already
mentioned this issue previously here (see
http://n3.nabble.com/Mvel-and-multithreading-td50133.html)
Maybe I have
described the problem not detailed enough.
We are using Drools
version 5.0.1 and have a concrete problem with it in our production
environment. Our customer looks already interrogative at the developer team and
have „questions“ about drools… please help! J
Let us assume a
multithreaded application, that tries to initialise & start several
processes using a StatefulKnowledgeSession in order to use in these processes
rule flow. The flow in all the processes is the same but every process instance
must have an own StatefulKnowledgeSession instance because of stateful session.
Actually the
problem:
At the initializing
phase occurs an org.mvel2.CompileException exception from time to time at
KnowledgeBuilder.add(…):
Exception in thread "Thread-60" [Error: incomplete
statement: (possible use of reserved keyword as identifier: )]
[Near : {... globals != empt ....}]
^
[Line: 0, Column: 0]
at
org.mvel2.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:153)
at
org.mvel2.MVELInterpretedRuntime.parse(MVELInterpretedRuntime.java:44)
at org.mvel2.MVEL.eval(MVEL.java:514)
at
org.mvel2.templates.res.IfNode.eval(IfNode.java:61)
at
org.mvel2.templates.res.TextNode.eval(TextNode.java:46)
at
org.mvel2.templates.res.TerminalNode.eval(TerminalNode.java:39)
at
org.mvel2.templates.res.ForEachNode.eval(ForEachNode.java:116)
at
org.mvel2.templates.res.TextNode.eval(TextNode.java:46)
at
org.mvel2.templates.res.TerminalNode.eval(TerminalNode.java:39)
at
org.mvel2.templates.res.IfNode.eval(IfNode.java:64)
at
org.mvel2.templates.res.TextNode.eval(TextNode.java:46)
at
org.mvel2.templates.res.ExpressionNode.eval(ExpressionNode.java:53)
at
org.mvel2.templates.res.TextNode.eval(TextNode.java:46)
at org.mvel2.templates.TemplateRuntime.execute(TemplateRuntime.java:195)
at
org.mvel2.templates.TemplateRuntime.execute(TemplateRuntime.java:190)
at
org.mvel2.templates.TemplateRuntime.execute(TemplateRuntime.java:180)
at
org.mvel2.templates.TemplateRuntime.execute(TemplateRuntime.java:169)
at
org.drools.rule.builder.dialect.java.AbstractJavaRuleBuilder.generatTemplates(AbstractJavaRuleBuilder.java:126)
at
org.drools.rule.builder.dialect.java.JavaConsequenceBuilder.build(JavaConsequenceBuilder.java:128)
at
org.drools.rule.builder.RuleBuilder.build(RuleBuilder.java:86)
at
org.drools.compiler.PackageBuilder.addRule(PackageBuilder.java:1159)
at
org.drools.compiler.PackageBuilder.addPackage(PackageBuilder.java:649)
at org.drools.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:290)
at
org.drools.compiler.PackageBuilder.addKnowledgeResource(PackageBuilder.java:488)
at
org.drools.builder.impl.KnowledgeBuilderImpl.add(KnowledgeBuilderImpl.java:25)
at com.myfirm.RuleFlowProcess.init(RuleFlowProcess.java:25)
at com.myfirm.RuleFlowProcess.clone(RuleFlowProcess.java:53)
at
com.myfirm.ThreadTest$CloneThread.run(ThreadTest.java:35)
Caused by: java.lang.NullPointerException
at org.mvel2.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:113)
... 27 more
Exception in thread "Thread-72" [Error: incomplete
statement: (possible use of reserved keyword as identifier: )]
[Near : {... declarations != empt ....}]
^
[Line: 0, Column: 0]
at
org.mvel2.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:153)
at
org.mvel2.MVELInterpretedRuntime.parse(MVELInterpretedRuntime.java:44)
at org.mvel2.MVEL.eval(MVEL.java:514)
at
org.mvel2.templates.res.IfNode.eval(IfNode.java:61)
at
org.mvel2.templates.res.TextNode.eval(TextNode.java:46)
at
org.mvel2.templates.res.ExpressionNode.eval(ExpressionNode.java:53)
at org.mvel2.templates.res.TextNode.eval(TextNode.java:46)
at
org.mvel2.templates.res.ExpressionNode.eval(ExpressionNode.java:53)
at
org.mvel2.templates.res.TextNode.eval(TextNode.java:46)
at
org.mvel2.templates.res.TerminalNode.eval(TerminalNode.java:39)
at
org.mvel2.templates.res.ForEachNode.eval(ForEachNode.java:116)
at
org.mvel2.templates.res.TextNode.eval(TextNode.java:46)
at
org.mvel2.templates.res.TerminalNode.eval(TerminalNode.java:39)
at org.mvel2.templates.res.ForEachNode.eval(ForEachNode.java:116)
at
org.mvel2.templates.res.TextNode.eval(TextNode.java:46)
at
org.mvel2.templates.res.ExpressionNode.eval(ExpressionNode.java:53)
at
org.mvel2.templates.res.TextNode.eval(TextNode.java:46)
at org.mvel2.templates.res.ExpressionNode.eval(ExpressionNode.java:53)
at
org.mvel2.templates.res.TextNode.eval(TextNode.java:46)
at
org.mvel2.templates.TemplateRuntime.execute(TemplateRuntime.java:195)
at org.mvel2.templates.TemplateRuntime.execute(TemplateRuntime.java:190)
at
org.mvel2.templates.TemplateRuntime.execute(TemplateRuntime.java:180)
at
org.mvel2.templates.TemplateRuntime.execute(TemplateRuntime.java:169)
at org.drools.rule.builder.dialect.java.AbstractJavaRuleBuilder.generatTemplates(AbstractJavaRuleBuilder.java:135)
at
org.drools.rule.builder.dialect.java.JavaConsequenceBuilder.build(JavaConsequenceBuilder.java:128)
at org.drools.rule.builder.RuleBuilder.build(RuleBuilder.java:86)
at
org.drools.compiler.PackageBuilder.addRule(PackageBuilder.java:1159)
at
org.drools.compiler.PackageBuilder.addPackage(PackageBuilder.java:649)
at
org.drools.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:290)
at
org.drools.compiler.PackageBuilder.addKnowledgeResource(PackageBuilder.java:488)
at
org.drools.builder.impl.KnowledgeBuilderImpl.add(KnowledgeBuilderImpl.java:25)
at com.myfirm.RuleFlowProcess.init(RuleFlowProcess.java:25)
at com.myfirm.RuleFlowProcess.clone(RuleFlowProcess.java:53)
at
com.myfirm.ThreadTest$CloneThread.run(ThreadTest.java:35)
Caused by: java.lang.NullPointerException
at
org.mvel2.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:113)
... 33 more
To demonstrate this
problem I have created a simple test maven project that reproduces this error
(s. attach):
I have a class that
creates & inits stateful knowledge session in a init method (RuleFlowProcess):
/**
*
inits the rule flow
*/
public class RuleFlowProcess {
private StatefulKnowledgeSession ksession;
public void init() {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("threadSafeTest.rf"), ResourceType.DRF);
kbuilder.add(ResourceFactory.newClassPathResource("testRules1.drl"), ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("testRules2.drl"), ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("testRules3.drl"), ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("testRules4.drl"), ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
StringBuilder errorString = new StringBuilder();
for (KnowledgeBuilderError error : errors) {
errorString.append(error);
}
throw new RuntimeException(errorString.toString());
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
ksession =
kbase.newStatefulKnowledgeSession();
}
…
}
I create & init
concurrently in several (200) threads this RuleFlowProcess and some threads
crash with this exceptions while adding the resources.
I have run this
project on two PCs:
core 2 duo @ 2.6
ghz, win xp prof sp3, sun jdk 1.6.0_17
Pentium Dual CPU
E2160 @ 1.8GHz, XP prof SP3, sun jdk 1.6.0_16.
Could you please
help us to clear this problem? Are we doing here something wrong?
If it should be an
drools error, could you please create an issue for it?
Thanks!
Wbr,
Grigoriy Grigoriev