Bug 994475 - NPE raises when trying to set process instance variable from DRL
NPE raises when trying to set process instance variable from DRL
Status: CLOSED CURRENTRELEASE
Product: JBoss BPMS Platform 6
Classification: JBoss
Component: jBPM Core (Show other bugs)
6.0.0
Unspecified Unspecified
unspecified Severity high
: ER2
: 6.0.0
Assigned To: Maciej Swiderski
Marek Baluch
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2013-08-07 07:11 EDT by Radovan Synek
Modified: 2014-08-13 08:07 EDT (History)
3 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2014-08-06 16:09:52 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
full stacktrace (11.59 KB, text/x-log)
2013-08-07 07:11 EDT, Radovan Synek
no flags Details


External Trackers
Tracker ID Priority Status Summary Last Updated
Red Hat Knowledge Base (Solution) 1163633 None None None Never

  None (edit)
Description Radovan Synek 2013-08-07 07:11:15 EDT
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 07:35:18 EDT
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 09:55:37 EDT
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 13:30:16 EDT
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 08:25:13 EDT
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 02:03:10 EDT
Verified on ER4.

Note You need to log in before you can comment on or make changes to this bug.