Bug 1035191

Summary: Unable to execute CompleteTaskCommand via JMS because of NullPointerException
Product: [Retired] JBoss BPMS Platform 6 Reporter: Ivo Bek <ibek>
Component: Business CentralAssignee: Marco Rietveld <mrietvel>
Status: CLOSED CURRENTRELEASE QA Contact: Ivo Bek <ibek>
Severity: high Docs Contact:
Priority: high    
Version: 6.0.0CC: ibek, kverlaen, mbaluch, rrajasek, smcgowan, vigoyal
Target Milestone: ER1   
Target Release: 6.0.1   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
When a task containing a human task has been started and a call to complete the task is sent via a REST call, it results in a NullPointerException and the task is not completed. This is because the call to complete the task is provided without a deployment id. There are no known workarounds at this stage. Cause: Consequence: Fix: Result:
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-08-06 20:03:50 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:
Attachments:
Description Flags
the process definition with a human task
none
server log none

Description Ivo Bek 2013-11-27 09:26:19 UTC
Created attachment 829615 [details]
the process definition with a human task

Description of problem:

When I send a request to complete a task, I receive:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><command-response><exception index="0"><command-name>CompleteTaskCommand</command-name><message>KieRemoteServicesRuntimeException thrown with message 'Unable to execute CompleteTaskCommand because of NullPointerException: null'</message><causeMessage>NullPointerException thrown with message 'null'</causeMessage></exception></command-response>

In the server log I found this NPE:

03:38:06,894 WARN  [org.kie.services.remote.jms.RequestMessageBean] (Thread-3 (HornetQ-client-global-threads-20938010)) Unable to execute CompleteTaskCommand because of NullPointerException: null: java.lang.NullPointerException
	at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:333) [rt.jar:1.7.0_40]
	at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:988) [rt.jar:1.7.0_40]
	at org.kie.services.remote.cdi.RuntimeManagerManager.getRuntimeManager(RuntimeManagerManager.java:46) [kie-services-remote-6.0.0-redhat-6.jar:6.0.0-redhat-6]
	at org.kie.services.remote.cdi.RuntimeManagerManager.getRuntimeEngine(RuntimeManagerManager.java:57) [kie-services-remote-6.0.0-redhat-6.jar:6.0.0-redhat-6]
	at org.kie.services.remote.jms.RequestMessageBean.processJaxbCommandsRequest(RequestMessageBean.java:333) [kie-services-remote-6.0.0-redhat-6.jar:6.0.0-redhat-6]
	at org.kie.services.remote.jms.RequestMessageBean.onMessage(RequestMessageBean.java:189) [kie-services-remote-6.0.0-redhat-6.jar:6.0.0-redhat-6]

It's important to mention that remote java api worked via JMS. Just when I send the command via my own jms client it fails.

This issue is not caused by the user called admin as there exists many other bugs!

Version-Release number of selected component (if applicable):


How reproducible:


Steps to Reproduce:
1. Start a process containing a human task (the process definition is attached)
2. Start the single task
3. Complete the task via own JMS client
4. See the response and server log

Actual results:


Expected results:


Additional info:

Comment 1 Marco Rietveld 2013-12-04 12:01:06 UTC
Ivo, 

Could you attach or link to a code snippet that shows how you create and send the CompleteTaskCommand command?

Thanks!

Comment 3 Ivo Bek 2013-12-04 13:47:52 UTC
Created attachment 832651 [details]
server log

Comment 5 Ivo Bek 2014-01-02 09:19:23 UTC
Hi Marco,

I do not think the client should be forced to request CompleteTaskCommand with deploymentId (JaxbCommandsRequest req = new JaxbCommandsRequest(deploymentId, command);). In REST it is possible to complete a task without the deploymentId and AFAIK that information is get internally https://github.com/droolsjbpm/droolsjbpm-integration/blob/master/kie-remote/kie-services-remote/src/main/java/org/kie/services/remote/rest/TaskResource.java#L242

Comment 6 Marco Rietveld 2014-01-09 15:53:50 UTC
Hi Ivo, 

The choice was between performance and convience: by making the deploymentId mandatory for these task commands, that means that the Task instance doesn't need to be retrieved, which is necessary in order to avoid race conditions (under load) when executing these commands:  

  CompleteTaskCommand
  ExitTaskCommand
  FailTaskCommand
  SkipTaskCommand

However, if convienence is more important than performance, I can change it. 

Are you sure about this?

Comment 7 Marek Baluch 2014-01-11 12:50:52 UTC
Hi Marco,

Performance is the key - I believe that we all agree that the statement is true. If making the 'deploymentId' mandatory helps performance then we should not change it.

One thing I don't understand is how does the user provided 'deploymentId' remove the need to retrieve the task? Could you please provide a link to the source code? Or provide more context?

Another thing which is not clear to me is how can a user start/complete/etc. a task (using the remoting interface) which is not associated with a deployment? The business-central allows to create and assign tasks which are not tight to a process and therefor not bound to a deployment.

Many thanks.

@MB

Comment 8 Marco Rietveld 2014-01-14 19:00:06 UTC
Hi Marek, 

See the following commits: 

This shows the code as it is, where the deployment id is required: 

https://github.com/droolsjbpm/droolsjbpm-integration/blob/6.0.x/kie-remote/kie-services-remote/src/main/java/org/kie/services/remote/jms/RequestMessageBean.java#L361

You'll see that for task commands that are _not_ in the  "TASK_COMMANDS_THAT_INFLUENCE_KIESESSION" set of Task commands, no deployment Id is required, but if it is a command that influences the KieSession, it is required. 

For those small set of commands that do (see my comment above), the deployment Id is required in order to be able to (basically) lock around the kiesession. 

. 

Now, if we don't require the deployment id, then we _can_ get it, but only by first retrieving the Task instance. I actually coded up a solution for this, you can find it here: 

https://github.com/droolsjbpm/droolsjbpm-integration/blob/700e9fb0311d4feac544e4104ed345fadebfcb91/kie-remote/kie-services-remote/src/main/java/org/kie/services/remote/jms/RequestMessageBean.java#L354

This is the same "try" block as above, except that we're now doing the following: 

- If it's a TASK_COMMANDS_THAT_INFLUENCE_KIESESSION Task command, then we first retrieve the task. This is because the Task instance contains the deployment id information. 

This extra step is what will decrease performance. 

. 

Let me know what you guys decide -- the "solution" is available, if we choose to do that. I can always unrevert the original commit. ;)

Comment 9 Marco Rietveld 2014-01-14 19:04:27 UTC
Marek, with regards to your second question: 

"Another thing which is not clear to me is how can a user start/complete/etc. a task (using the remoting interface) which is not associated with a deployment?"

The majority of the Task operations are possible without submitting a deployment id. In fact, all Task operations that do not involve the process engine can be done without having to get the deployment id. 

However, the following commands all impact the process engine: they end up signalling the process engine that the associate _process instance_ should be signalled (that the task is complete and that the process instance can continue):

  CompleteTaskCommand
  ExitTaskCommand
  FailTaskCommand
  SkipTaskCommand

Because these commands affect the process instance, it's important to make sure that nothing else is concurrently doing something with the process instance, which is why we need the deployment id to lock around the kiesession that holds the process instance. 

Does that make sense? Please feel free to ask more questions if it's not!

Comment 10 Marek Baluch 2014-01-15 13:41:02 UTC
At this time the task commands above require the deployment Id, This should be documented for GA1.

Comment 11 Ivo Bek 2014-01-30 10:13:02 UTC
Vikram,

a workaround exists. A developer use this complete command:

Command<?> cmd = new CompleteWorkItemCommand(workItemId, results);

then he/she can use:

JaxbCommandsRequest req = new JaxbCommandsRequest(deploymentId, cmd); // here the deploymentId must be put there, this is currently mandatory for the commands stated above

instead of:

JaxbCommandsRequest req = new JaxbCommandsRequest(cmd);


The developer can get deploymentId information from TaskData (through GetTaskCommand), so the taskId is the only thing needed to complete a task, just he has to do this approach himself.

Comment 12 Ivo Bek 2014-01-30 10:15:30 UTC
Also it is not a REST call as you stated but JMS.

Comment 15 Lukáš Petrovický 2014-02-07 16:19:25 UTC
This no longer has a target release of 6.0.0.

Comment 16 Ivo Bek 2014-02-17 12:32:04 UTC
Verified in BPMS 6.0.1.ER1