cancel
Showing results for 
Search instead for 
Did you mean: 

Java service classes

sheublein
Champ in-the-making
Champ in-the-making
Hi Forum,

I am currently trying to integrate Activiti with an application that is being developed at my company. I am still on a very low level regarding the understanding of Activiti and the interaction of its components but something struck me that I could not answer from reading the (btw excellent!) documentation or several developer blogs.

The Activiti implementation of Java service task in Activiti is very convenient for my Java project in order to execute custom Java code but I stumbled upon the following:

<b>Note: there will be only one instance of that Java class created for the serviceTask it is defined on. All process-instances share the same class instance that will be used to call execute(DelegateExecution). This means that the class must not use any member variables and must be thread-safe, since it can be executed simultaneously from different threads</b>

In my project I want to use a Java class to update a database with data from the user that has started the process. To do so I need to bring the name of the user along somehow and the class has to be called for each user (i.e. each process) with her own name specified.
Since the user guide states that all process-instances use the same class instance I wonder whether this is possible. I understand that the variable of the first process that contains the name would be overwritten as soon as the second process calls the Java class and if the first is not finished until then.

I am uncertain how to solve this and why Activiti does not support the construction of an own class instance for each process calling the same Java class. But maybe this is owed to a misunderstanding on my behalf as I am still quite new to Activiti and, frankly, also to Java.

A clarification would be greatly appreciated.

Best,

Steffen
2 REPLIES 2

frederikherema1
Star Contributor
Star Contributor
The JavaDelegate implementation is indeed shared between process-instances. Process-variables (set when starting the process, through API or by activities in the process) are stored in the database for each process-instance.

So if you have a process that is started by user X, you can use the activiti:initiator="personWhoStarted" construction (see user guide). Once your service-task is reached, you can use the DelegateExecution to extract the value of the "personWhoStarted" variable for the current process instance, using delegateExecution.getVariable("personWhoStarted"). This value can now be used to call your external service, being 100% sure that the call to that service is using the user for the process involved.

Another way to extract variables from the execution in a service-task is to use Field-injection (see user guide again). This field is stateless and thus can be shared between all instances. Once the javaDelegate is called, you can get the value of the field, based on the current process-instance (by passing in the DelegateExecution when getting value).

If you don't want to use JavaDelegates that are shared, you can always use, for example, spring-beans (using activiti:delegateExpression) or methods on spring-beans (or non-spreing beans set at configuration time), passing in execution-variables along with it (activiti:expression). Again, this is described in the user guide in more detail.

If you really really really want to create your own delegate classes, you can have the "delegateExpression" return a new instance every time. off course, if you think about the "stateless" nature of the process-logic Java, it makes no sense to have new instance every time. The logic in the delegates should use the process-variables and state…

Thanks a lot, Frederik, that really helped my understanding. 🙂