Can not set local variables when modifying a process instance starting before a user task with boundary events or input settings

Dear all,

I found setVariableLocal method would create a global(process instance) variable in some cases. I’m sure whether it is an expected behaviour or a bug.

modify-test-process.bpmn (4.6 KB)

For this test process, UserTask1 has input settings, UserTask2 has a timer boundary event and UserTask3 is just a single user task with out any further configurations. When calling method:

//code 1
runtimeService().createProcessInstanceModification(pid.getId())
                .startBeforeActivity("UserTask1")
                .setVariableLocal("test", "value")
                .execute();


//code 2
runtimeService().createProcessInstanceModification(pid.getId())
                .startBeforeActivity("UserTask2")
                .setVariableLocal("test", "value")
                .execute();

//code 3
runtimeService().createProcessInstanceModification(pid.getId())
                .startBeforeActivity("UserTask3")
                .setVariableLocal("test", "value")
                .execute();

the code 1 and code 2 both create a global variable test, meanwhile only the code 3 creates a local variable.

In order to check the variable scope and the execution tree, I uses the following method:

//for variable scope
var variable = runtimeService().createVariableInstanceQuery().variableName("test").singleResult();
log.info(variable.getActivityInstanceId());

//for execution tree
var ins = runtimeService().getActivityInstance(pid.getId());
printTree(1, ins);

private void printTree(int level, ActivityInstance... instance) {
        if (instance == null || instance.length == 0)
            return;
        log.info("Level {}", level);
        for (var a : instance) {
            log.info("id: {}, name:{}, parent:{}", a.getActivityId(), a.getActivityName(), a.getParentActivityInstanceId());
            printTree(level + 1, a.getChildActivityInstances());
        }
    }

It seems that the execution tree is nearly the same in the 3 cases likes:

xxx - Level 1
xxx - id: ModifyTestProcess:1:3, name:null, parent:null
xxx - Level 2
xxx - id: UserTask1/2/3, name:null, parent:5

But the ActivityInstanceId of case 1 and case 2 are just a single number (both is 5 in my test environment), for case 3 it is UserTask3:18 which shows it is a local variable for UserTask3.

By comparing the detail console log of with and without input variable as follows:

## without input variable
...
20:58:17.944 [main] DEBUG org.camunda.bpm.engine.persistence - ENGINE-03030 Child execution 'ScopeExecution[14]' created with parent 'ProcessInstance[5]'.
20:58:17.944 [main] DEBUG org.camunda.bpm.engine.pvm - ENGINE-20003 Execution ProcessInstance[5] leaves activity instance 5
20:58:17.944 [main] DEBUG org.camunda.bpm.engine.persistence - ENGINE-03030 Child execution 'ScopeExecution[15]' created with parent 'ProcessInstance[5]'.
20:58:17.948 [main] DEBUG org.camunda.bpm.application - ENGINE-07023 No target process application found for Execution[15], ProcessDefinition[ModifyTestProcess:1:3], Deployment[1] Registrations[]
20:58:17.948 [main] DEBUG org.camunda.bpm.engine.context - ENGINE-16001 Executing atomic operation org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityStartCreateScope@42f2cae8 on ConcurrentExecution[15]
20:58:17.948 [main] DEBUG org.camunda.bpm.engine.context - ENGINE-16001 Executing atomic operation org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityStart@3bbc47c9 on ConcurrentExecution[15]
20:58:17.948 [main] DEBUG org.camunda.bpm.engine.pvm - ENGINE-20008 Enter activity instance ConcurrentExecution[15] parent: 5
20:58:17.949 [main] DEBUG org.camunda.bpm.engine.context - ENGINE-16001 Executing atomic operation org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityStart@3bbc47c9 on ConcurrentExecution[15]
20:58:17.949 [main] DEBUG org.camunda.bpm.engine.context - ENGINE-16001 Executing atomic operation org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityStart@3bbc47c9 on ConcurrentExecution[15]
20:58:17.949 [main] DEBUG org.camunda.bpm.engine.context - ENGINE-16001 Executing atomic operation org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute@4abdd5e on ConcurrentExecution[15]
20:58:17.949 [main] DEBUG org.camunda.bpm.engine.pvm - ENGINE-20002 ConcurrentExecution[15] executed activity Activity(UserTask1): org.camunda.bpm.engine.impl.bpmn.behavior.UserTaskActivityBehavior
20:58:17.949 [main] DEBUG org.camunda.bpm.engine.cmd - ENGINE-13011 closing existing command context
...

## with input variable
...
20:59:58.225 [main] DEBUG org.camunda.bpm.engine.persistence - ENGINE-03030 Child execution 'ScopeExecution[17]' created with parent 'ProcessInstance[5]'.
20:59:58.225 [main] DEBUG org.camunda.bpm.engine.pvm - ENGINE-20003 Execution ProcessInstance[5] leaves activity instance 5
20:59:58.225 [main] DEBUG org.camunda.bpm.engine.persistence - ENGINE-03030 Child execution 'ScopeExecution[18]' created with parent 'ProcessInstance[5]'.
20:59:58.226 [main] DEBUG org.camunda.bpm.application - ENGINE-07023 No target process application found for Execution[18], ProcessDefinition[ModifyTestProcess:1:3], Deployment[1] Registrations[]
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.context - ENGINE-16001 Executing atomic operation org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityStartCreateScope@4c3fcbe7 on ConcurrentExecution[18]
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.persistence - ENGINE-03030 Child execution 'ScopeExecution[21]' created with parent 'ConcurrentExecution[18]'.
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.pvm - ENGINE-20010 Create scope: parent exection ConcurrentExecution[18] continues as  ScopeExecution[21]
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.persistence - ENGINE-03031 Initializing execution 'ScopeExecution[21]'
20:59:58.226 [main] DEBUG org.camunda.bpm.application - ENGINE-07023 No target process application found for Execution[21], ProcessDefinition[ModifyTestProcess:1:3], Deployment[1] Registrations[]
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.context - ENGINE-16001 Executing atomic operation org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityStart@1e592ef2 on ScopeExecution[21]
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.pvm - ENGINE-20008 Enter activity instance ScopeExecution[21] parent: 5
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.core - ENGINE-17001 Mapping value '123 from outer scope 'ConcurrentExecution[18]' to variable 'abc' in inner scope 'ScopeExecution[21]'.
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.persistence - ENGINE-03032 Initializing timer declaration 'ScopeExecution[21]'
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.context - ENGINE-16001 Executing atomic operation org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityStart@1e592ef2 on ScopeExecution[21]
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.context - ENGINE-16001 Executing atomic operation org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityStart@1e592ef2 on ScopeExecution[21]
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.context - ENGINE-16001 Executing atomic operation org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute@20f6b6e0 on ScopeExecution[21]
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.pvm - ENGINE-20002 ScopeExecution[21] executed activity Activity(UserTask1): org.camunda.bpm.engine.impl.bpmn.behavior.UserTaskActivityBehavior
20:59:58.226 [main] DEBUG org.camunda.bpm.engine.cmd - ENGINE-13011 closing existing command context
...

it seems that the process engine created a new sub-execution ScopeExecution[21] to execute the input variable setting. Thus, the setVariableLocal is executed in one execution (ConcurrentExecution[18]) which will set a variable in a super scope of the UserTask, so the variable will not be a local variable of the task.

By contrast, if the user task holds execution listener and/or task listener, they will be executed in the same scope of the modification instruction, viz, the setVariableLocal will create a local variable for the user task.

So, the question is why it creates a sub-scope for input mappings and boundary events?

I have also met this problem. Could you tell me how to deal with it. i hava to use local variables

I’ve got no idea about the problem, and the developers of Camunda says it’s an expected behaviour.