Bug 994475

Summary: NPE raises when trying to set process instance variable from DRL
Product: [Retired] JBoss BPMS Platform 6 Reporter: Radovan Synek <rsynek>
Component: jBPM CoreAssignee: Maciej Swiderski <mswiders>
Status: CLOSED CURRENTRELEASE QA Contact: Marek Baluch <mbaluch>
Severity: high Docs Contact:
Priority: unspecified    
Version: 6.0.0CC: agiertli, mbaluch, rzhang
Target Milestone: ER2   
Target Release: 6.0.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-08-06 20:09:52 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
full stacktrace none

Description Radovan Synek 2013-08-07 11:11:15 UTC
Created attachment 783811 [details]
full stacktrace

NPE raises when trying to set process instance variable from DRL (activated in rule task):

Caused by: java.lang.NullPointerException
	at org.jbpm.process.instance.impl.ProcessInstanceImpl.getProcess(ProcessInstanceImpl.java:89) [jbpm-flow-6.0.0.CR1.jar:6.0.0.CR1]
	at org.jbpm.process.instance.impl.ProcessInstanceImpl.getContextInstance(ProcessInstanceImpl.java:158) [jbpm-flow-6.0.0.CR1.jar:6.0.0.CR1]
	at org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl.setVariable(WorkflowProcessInstanceImpl.java:265) [jbpm-flow-6.0.0.CR1.jar:6.0.0.CR1]
	at org.jboss.qa.bpms.clustering.Rule_initVariable1679671911.defaultConsequence(Rule_initVariable1679671911.java:7)
	at org.jboss.qa.bpms.clustering.Rule_initVariable1679671911DefaultConsequenceInvokerGenerated.evaluate(Unknown Source)
	at org.jboss.qa.bpms.clustering.Rule_initVariable1679671911DefaultConsequenceInvoker.evaluate(Unknown Source)
	at org.drools.core.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1016) [drools-core-6.0.0.CR1.jar:6.0.0.CR1]


I will add the reproducer soon.

Comment 1 Radovan Synek 2013-08-07 11:35:18 UTC
Here is the promised reproducer: https://github.com/droolsjbpm/jbpm/pull/175

It seems the exception raises only when persistence is configured.

Comment 2 Kris Verlaenen 2013-08-07 13:55:37 UTC
Maciej,

I believe this is probably because process instances are serialized as part of the session state, but ProcessInstanceResolverStrategy should probably be used instead.
Could you verify, and would it be possible to register this strategy somehow as one of the defaults?

Kris

Comment 3 Maciej Swiderski 2013-08-12 17:30:16 UTC
Kris, looks like it is caused by the disconnect on the transaction completion regardless if the marshaller strategy is default (serialized with all other facts) or we use process instance dedicated one. In both cases as soon as transaction ends given process instance is disconnected. Then the session is not loaded on every transaction which would make things work as then it would load the process instance with the dedicated strategy. So it must be done within the same transaction to have process instance entirely ready.

Comment 4 Maciej Swiderski 2013-08-15 12:25:13 UTC
When using persistence, process instance is considered read only after transaction, that has done any modification to the process instance (like start process), is completed. So when process instance is inserted into ksession as a fact it shall only be used to read values from it. When attempting to modify its content (like setting variable) will fail unless it's reloaded. To secure proper access to "write" operations on process instance from within RHS following is recommended:
- load process instance once again from knowledge runtime before any "write" operations on process instance:
processInstance = (WorkflowProcessInstance)kcontext.getKnowledgeRuntime().getProcessInstance(processInstance.getId());
then use that processInstance to modify its state:
processInstance.setVariable("test", test);

that way process instance will be reconnected with runtime engine and any changes to its state will be properly persisted. 

Important to note is that process instance is not automatically updated within working memory when it changes outside - for example when process instance was inserted at the start of the process it will represent the state of the first wait state regardless if the process instance has already been moved further.

With that in mind it is recommended to insert process instance into working memory just before the actual rule evaluation rather than keeping it within working memory all the time. And retract it as soon as it's not needed any more.

Another important aspect when using rules that reason over process instances with persistence enabled is that before process completes the process instance MUST be retracted from working memory since on next ksession load it will fail to load process instance from db as it was already completed and removed from data base.

Code has been enhanced to use proper serialization mechanism for process instances (ProcessInstanceResolverStrategy) when using RuntimeManager. Committed to master and 6.0.x
https://github.com/droolsjbpm/jbpm/commit/4de2e15ed8c9a67d0b6e8c2ba3102a81a3b0c9c6
https://github.com/droolsjbpm/jbpm/commit/439ade5a87cd773334ead6d4536b37c942439c37

Comment 9 Marek Baluch 2013-10-25 06:03:10 UTC
Verified on ER4.