cancel
Showing results for 
Search instead for 
Did you mean: 

get fieldDeclarations through DelegateExecution

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

Is there any way to get the "List<fieldDeclarations>" of the executing service task (JavaDelegate) through the DelegateExecution instance?

Regards, Maarten
5 REPLIES 5

jbarrez
Star Contributor
Star Contributor
I'm not sure what you mean with this? Can you elaborate?

boekhold
Champ in-the-making
Champ in-the-making
Is there any way to get the <code>List<FieldDeclaration></code> of the executing service task (JavaDelegate) through the DelegateExecution instance?

I'm not sure what you mean with this? Can you elaborate?

(original question updated, I was asking about<code>List<FieldDeclaration></code>)

I wanted to keep the question short and to the point, because the background of this is quite long, and I'm afraid it will open up a can of worms. However I should probably describe it anyways.

We're using Activiti inside an OSGi container, and use delegateExpressions for Service Tasks (which I believe is the only method supported if you run inside an OSGi container). We now want to use Field Injection to pass parameters to our custom service tasks. We believe however that the current implementation in Activiti is not thread-safe.

The way Activiti works when using delegateExpression for a service task is that the expression is evaluated inside <code>ServiceTaskDelegateExpressionActivityBehavior</code> when the activity is being executed. The JavaDelegate returned by the expression evaluation is always the same instance. Next, Activiti performs Field Injection on that instance (which is effectively a singleton instance).

If you reference the same JavaDelegate from different process models, or from parallel flows inside the same model, there is a risk that a specific execution is getting the expressions from another execution.

So, I'm trying to come up with a way to make this thread safe. The first step is to prevent Activiti from doing the reflection-based field injection. I can do that. I've implemented a <code>CustomBehaviorFactory extends DefaultActivityBehaviorFactory</code> that overrides the <code>createServiceTaskDelegateExpressionActivityBehavior()</code> method, and returns a <code>CustomServiceTaskDelegateExpressionActivityBehavior extends ServiceTaskDelegateExpressionActivityBehavior</code> instance. In my custom activity behavior, I skip the <code>applyFieldDeclarations()</code> call for JavaDelegate instances.

I'm now looking at finding another way of getting the <code>List<FieldDeclaration></code> into our JavaDelegate in a threadsafe way. The best option seems to be to try to somehow get that list into the DelegateExecution that's passed to <code>JavaDelegate.execute()</code>. Right now the only option I see is to add each FieldDeclaration to the local variables before the <code>handleInvocation()</code> call, and remove them again after <code>leave(execution)</code>. I'm hoping however that there's a better way?

Maarten

jbarrez
Star Contributor
Star Contributor
You're reasoning is not quite correct: what is injected in the delegate is an instance of an Expression. This is always the same instance.
In the method itself, the expression is resolved using the execution to resolve (if needed). So this is thread-safe, there is no instance member being used, but rather an Expression that can resolve to different things depending on the context.

boekhold
Champ in-the-making
Champ in-the-making
No, because you can use the same <code>MyServiceTask implements JavaDelegate</code> multiple times in different models, or in different places in the same model. Each of those places can have its own set of expressions configured on the class fields.

At least in our OSGi deployment, each time Activiti calls <code>expression.getValue(execution)</code> (like in <code>ServiceTaskDelegateExpressionActivityBehavior</code>, that getValue() returns the same instance of the JavaDelegate.

there is no instance member being used

Uh, you are injecting instance members…?!?

Maarten

jbarrez
Star Contributor
Star Contributor
> Uh, you are injecting instance members…?!?

Expression, and the expressions are the same.
It is by design that Activiti returns the same instance (which you could override if really needed). Not sure what you are looking for looking at the original post and where we are at now 🙂