Bug 1021631

Summary: Compensation scope not found
Product: [Retired] JBoss BPMS Platform 6 Reporter: Tomas Schlosser <tschloss>
Component: jBPM CoreAssignee: Marco Rietveld <mrietvel>
Status: CLOSED CURRENTRELEASE QA Contact: Tomas Schlosser <tschloss>
Severity: high Docs Contact:
Priority: medium    
Version: 6.0.0CC: smcgowan, tschloss
Target Milestone: ER5   
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:56 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
Process demonstrating the issue none

Description Tomas Schlosser 2013-10-21 16:53:55 UTC
Created attachment 814712 [details]
Process demonstrating the issue

Description of problem:
Running the attached process throws a NullPointerException. After running the scripts with assertions enabled, the code throws AssertionError saying "Compensation scope for node [subprocess] could not be found!"

The process is handwritten, with inspiration from similar processes created in designer and Eclipse modeler. it uses boundary event and association (as specification describes) to handle one element compensation.

Version-Release number of selected component (if applicable):
BPMS 6.0.0.ER4

How reproducible:
Run the attached process

Steps to Reproduce:
1. Run process

Comment 1 Marco Rietveld 2013-10-22 12:16:09 UTC
If possible, it would be great if you could include the stack trace (of the assertion error). Thanks!

Comment 2 Tomas Schlosser 2013-10-22 12:35:09 UTC
Hi,
this is the one without assertions enabled:
http://pastebin.test.redhat.com/171844

and this one is with assertions enabled:
http://pastebin.test.redhat.com/171846

Comment 3 Marco Rietveld 2013-10-23 09:13:02 UTC
Ah, caused by a (somewhat obvious) typo by me here: 

https://github.com/droolsjbpm/jbpm/commit/ed34d8b6dac56e9391e62809518292aae34f6559#diff-83432dfcb823fd6eb29b661f68924594R909

Fixing and double checking this now. I'll also add a clear explanation of why this typo caused problems (including some info about Compensation). Tomas did a good job testing this, but I want to make sure that people looking back at the bug (including myself!) get the right info.

Comment 4 Marco Rietveld 2013-10-23 09:55:24 UTC
In the (bpmn2) process that showed this bug, there's the following end event: 

    <endEvent id="end" name="end">
      <compensateEventDefinition activityRef="subprocess" />
    </endEvent>

This event throws a Compensation event. The compensation event is "user-defined" as opposed to "implicit", because it targets the "subpprocess" task. If you wanted an end event that was "implicit" and would cause compensation for *all* (visible!) compensation handlers, then you would use this end event: 

    <endEvent id="end" name="end">
      <compensateEventDefinition />
    </endEvent>

Obviously, within the jbpm engine, implicit compensation (which targets all visible compensation handlers) is handled slightly different than user-defined or specific compensation. Unfortunately, in the (jbpm-bpmn2) ProcessHandler class, which does most of the work in setting up compensation during parsing, I had made a typo where I was basically flagging any user-defined compensation events as implicit compensation events. 

See the link above for the actual code, but in short, I was doing this: 

  if( there is NOT an activityRef attribute 
      in the throwing event's compensationEventDefinition ) { 
     -> use the flag to indicate that this is implicit/general compensation
  } else { 
     -> use the flag to indicate that this is implicit/general compensation
  }

(Obviously, the else clause should *not* flag for implicit compensation and just use the activityRef value to specify the compensation handler). 

I didn't catch this in my existing tests because I was mostly only testing whether or not compensation happened -- not whether or not it only happened for some handlers. 

Furthermore, what really caused the problem is that the jbpm implicit compensation mechanism targets the "container" or (sub)process that contains the compensation handler. This code can be found in the (jbpm-flow) CompensationEventListener. jBPM implicit compensation targets (sub)processes instead of specific nodes because it needs to find all *visible* compensation handlers. 

(Basically, visibility for compensation means that the compensation handler (boundary event + associated task in this case) is on the same (sub)process level as the throwing event (although it's slightly more complicated).)

In this case, what basically happened during the test is that the jbpm engine expected to find a NodeContainer node (used for (sub)processes) because implicit compensation was being (mistakenly) used. However, the compensation handler in the process is boundary event compensation handler (not a subprocess compensation handler), and so it couldn't be found. (Okay, I didn't explain that well.. but in short, because implicit/general compensation was flagged, it couldn't find the compensation handler that it expected to find). 

As a result, the assertion error was thrown. If the assertion error had not been thrown, then a NPE would've been thrown 2 lines later.

Comment 6 Tomas Schlosser 2013-12-10 20:12:08 UTC
Verified in BPMS-6.0.0 ER5