]
Mark Proctor resolved JBRULES-2797.
-----------------------------------
Resolution: Out of Date
No feedback as to whether the problem exists, so closing. Please re-open if problems
persist.
HashTableIterator of AbstractHashTable is not Thread Safe
----------------------------------------------------------
Key: JBRULES-2797
URL:
https://issues.jboss.org/browse/JBRULES-2797
Project: Drools
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: drools-core, drools-core (flow)
Affects Versions: 5.1.1.FINAL, FUTURE
Environment: N/A
Reporter: Anatoly Polinsky
Assignee: Mark Proctor
Labels: drools-core, drools-flow, thread-safety
Attachments:
AbstractHashTable-thread_localing_a_table_HashTableIterator_s_row_and__entity_.patch
Original Estimate: 1 hour
Remaining Estimate: 1 hour
public static class HashTableIterator has a shared state that gets inconsistent when
multiple threads work on the getting the next entity:
public Object next() {
if ( this.entry != null ) {
PART 1 >> this.entry = this.entry.getNext();
}
// if no entry keep skipping rows until we come to the end, or find
one that is populated
while ( this.entry == null && ++this.row < this.length ){
PART II >> this.entry = this.table[this.row];
}
return this.entry;
}
In "PART 1", the race condition causes "this.entry" be NULL in
"this.entry.getNext()", and throws the exception below.
In "PART 2", the race condition causes inconsistent state of
"this.row", and throws multiple exceptions, but mostly the one that is described
in:
https://jira.jboss.org/browse/JBRULES-2794
java.util.concurrent.ExecutionException: org.drools.RuntimeDroolsException: Unexpected
exception executing action
org.drools.reteoo.ReteooWorkingMemory$WorkingMemoryReteAssertAction@1ff323
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
at java.util.concurrent.FutureTask.get(FutureTask.java:83)
at
org.custom.workflow.stress.test.WorkflowStressTest.shouldRunFlow(WorkflowStressTest.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at
org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at
org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at
org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at
com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:94)
at
com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:192)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:115)
Caused by: org.drools.RuntimeDroolsException: Unexpected exception executing action
org.drools.reteoo.ReteooWorkingMemory$WorkingMemoryReteAssertAction@1ff323
at
org.drools.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:1473)
at
org.drools.common.AbstractWorkingMemory.startProcess(AbstractWorkingMemory.java:1631)
at
org.drools.impl.StatefulKnowledgeSessionImpl.startProcess(StatefulKnowledgeSessionImpl.java:318)
at
org.drools.command.runtime.process.StartProcessCommand.execute(StartProcessCommand.java:99)
at
org.drools.command.runtime.process.StartProcessCommand.execute(StartProcessCommand.java:38)
at
org.drools.persistence.session.SingleSessionCommandService.execute(SingleSessionCommandService.java:285)
at
org.drools.command.impl.CommandBasedStatefulKnowledgeSession.startProcess(CommandBasedStatefulKnowledgeSession.java:193)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
at
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:692)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
at org.custom.workflow.stress.test.WorkflowRunner.call(WorkflowRunner.java:38)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.NullPointerException
at
org.drools.core.util.AbstractHashTable$HashTableIterator.next(AbstractHashTable.java:312)
at org.drools.reteoo.EntryPointNode.updateSink(EntryPointNode.java:323)
at org.drools.reteoo.ObjectTypeNode.attach(ObjectTypeNode.java:303)
at
org.drools.reteoo.builder.PatternBuilder.attachObjectTypeNode(PatternBuilder.java:257)
at org.drools.reteoo.ClassObjectTypeConf.<init>(ClassObjectTypeConf.java:92)
at
org.drools.common.ObjectTypeConfigurationRegistry.getObjectTypeConf(ObjectTypeConfigurationRegistry.java:68)
at org.drools.reteoo.Rete.assertObject(Rete.java:111)
at org.drools.reteoo.ReteooRuleBase.assertObject(ReteooRuleBase.java:280)
at
org.drools.reteoo.ReteooWorkingMemory$WorkingMemoryReteAssertAction.execute(ReteooWorkingMemory.java:360)
at
org.drools.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:1471)
... 24 more
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: