10-24-2012 11:20 AM
10-24-2012 02:53 PM
or should I just not store any state in the service task class?
10-25-2012 03:36 AM
To inject values that are dynamically resolved at runtime, expressions can be used. Those expressions can use process variables, or Spring defined beans (if Spring is used). As noted in Service Task Implementation, an instance of the Java class is shared among all process-instances in a service task. To have dynamic injection of values in fields, you can inject value and method expressions in a org.activiti.engine.delegate.Expression which can be evaluated/invoked using the DelegateExecution passed in the execute method.
<serviceTask id="javaService" name="Java service invocation"
activiti:class="org.activiti.examples.bpmn.servicetask.ReverseStringsFieldInjected">
<extensionElements>
<activiti:field name="text1">
<activiti:expression>${genderBean.getGenderString(gender)}</activiti:expression>
</activiti:field>
<activiti:field name="text2">
<activiti:expression>Hello ${gender == 'male' ? 'Mr.' : 'Mrs.'} ${name}</activiti:expression>
</activiti:field>
</ extensionElements>
</ serviceTask>
The example class below uses the injected expressions and resolves them using the current DelegateExecution. Full code and test can be found in org.activiti.examples.bpmn.servicetask.JavaServiceTaskTest.testExpressionFieldInjection
public class ReverseStringsFieldInjected implements JavaDelegate {
private Expression text1;
private Expression text2;
public void execute(DelegateExecution execution) {
String value1 = (String) text1.getValue(execution);
execution.setVariable("var1", new StringBuffer(value1).reverse().toString());
String value2 = (String) text2.getValue(execution);
execution.setVariable("var2", new StringBuffer(value2).reverse().toString());
}
}
11-04-2014 12:49 AM
11-05-2014 05:42 AM
12-09-2014 05:13 AM
12-18-2014 12:02 PM
Hello I created two processes with two service tasks each as below
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlnsmgdc="http://www.omg.org/spec/DD/20100524/DC" xmlnsmgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="myProcess" name="My process" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<serviceTask id="servicetask1" name="Service Task" activiti:expression="${businessRules.checkBalance(execution)}"></serviceTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
<serviceTask id="servicetask2" name="Service Task" activiti:expression="${businessRules.addAccount(execution, context)}"></serviceTask>
<sequenceFlow id="flow2" sourceRef="servicetask1" targetRef="servicetask2"></sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow3" sourceRef="servicetask2" targetRef="endevent1"></sequenceFlow>
</process>
</definitions>
businessRules is a bean I have configured in the activiti.cfg.xml file as below
<bean id="businessRules" class="com.company.BusinessRules" />
Note that there are two service tasks in this process definition using expression to call method on the same bean. I also created a second process called "otherProcess" which is a mirror image of this process. I then ran both processes one after the other using the code below.
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
repositoryService.createDeployment()
.addClasspathResource("MyProcess.bpmn20.xml")
.deploy();
repositoryService.createDeployment()
.addClasspathResource("OtherProcess.bpmn20.xml")
.deploy();
Map<string, object=""> variables = new HashMap<string, object="">();
variables.put("context", new WorkflowContext());
RuntimeService runtimeService = processEngine.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess", variables);
Map<string, object=""> variables2 = new HashMap<string, object="">();
variables2.put("context", new WorkflowContext());
ProcessInstance processInstance2 = runtimeService.startProcessInstanceByKey("otherProcess", variables2);
processInstance2 = runtimeService.createProcessInstanceQuery().processDefinitionKey("otherProcess").singleResult();
System.out.println("Is Ended = " + processInstance.isEnded() + " Current Task: " + processInstance.getActivityId());
What I notice is that an instance of BusinessRules bean is only created once. I put a println message in the constructor of the BusinessRules and I see that it is hit only once across both processes, across the calls to the two service tasks in each process. Is this the expected behavior or should the BusinessRules bean be instantiated once per process, or once per service task? Thanks in advance for the clarification.
Tags
Find what you came for
We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.