cancel
Showing results for 
Search instead for 
Did you mean: 

Result Variable in JavaDelegate

boekhold
Champ in-the-making
Champ in-the-making
Hi,

When creating a BPMN model, there is a configuration field on a ServiceTask "Result variable". If my ServiceTask uses a delegateExpression backed by a JavaDelegate, can I access the value specified for "Result variable" so I can place the result in the requested variable?

Maarten
7 REPLIES 7

balsarori
Champ on-the-rise
Champ on-the-rise
The purpose of result variable is to save the service task result (for service task using expression only). For example,


<serviceTask id="serviceTask"
    activiti:expression="#{myService.toUpperCase(myVar)}"
    activiti:resultVariable="myVar" />
[java]
public class MyService {
  public String toUpperCase(String val) {
    return val.toUpperCase();
  }
}
[/java]
In above example, the myVar process variable will be updated to the value returned by the expression. This is useful when you want to use/build services that do not have dependency to Activiti.

When using JavaDelegate (either by using delegateExpression or using activiti:class attribute), the resultVariable has no meaning in that case since variables can be modified directly using the DelegateExecution instance (additionally the execute method return type is void). The above example can be done using the JavaDelegate as follows

[java]
public class MyService implements JavaDelegate {
  public void execute(DelegateExecution execution) throws Exception {
    String myVar = (String) execution.getVariable("myVar");
    execution.setVariable("myVar", myVar.toUpperCase());
  }
}
[/java]

boekhold
Champ in-the-making
Champ in-the-making
Hi

Thanks for the explanation Bassam. I do actually think that using the result variable would be useful for a JavaDelegate service task as well, because it would allow the workflow designer to decide where the result should be stored, instead of being stuck with what the JavaDelegate programmer decided. That could help in cases where you have 2 JavaDelegates that both place their result in the same process variable, possibly overwriting each other's result.

I suppose I could always achieve the same thing by passing a result variable name as a Class Field though…

Maarten

jbarrez
Star Contributor
Star Contributor
In the JavaDelegate option, the way to go is execution.setVariable() indeed. A class field would solve that problem at design time indeed.

> 'That could help in cases where you have 2 JavaDelegates that both place their result in the same process variable'

Could you elaborate what you mean with this? Or are you referring to the designer not having knowledge to the internals of a delegate?

boekhold
Champ in-the-making
Champ in-the-making
Hi,

Any JavaDelegate implementation will have a 'contract' that defines how it expects its inputs to be provided, and where it will make its result available. For JavaDelegates, the only way you have to return a result is to place it in a process variable.

If you have multiple (independent) teams writing Java Delegates, they could unwittingly used the same "result variable name", and if you then put 2 of these Java Delegates one after another in your model, the second one would overwrite the results of the first one…

If "result variable" was available somewhere in the DelegateExecution, you can avoid that by handing off the responsibility of selecting proper result variable names to the model designer/business analyst.

Maarten

jbarrez
Star Contributor
Star Contributor
I see. What you can do with the current code, is to fetch the BpmnModel and inspect the service task and check what value was set for the result variable.

boekhold
Champ in-the-making
Champ in-the-making
I tried setting a result variable on the service task executing a JavaDelegate, but there's a very early validation somewhere that prevents me from doing so. If I recall correctly, there's an exception on execution of the model.

jbarrez
Star Contributor
Star Contributor
Hmm would be interesting to see if you can get that stacktrace back again. That should work as advertised.