cancel
Showing results for 
Search instead for 
Did you mean: 

Reusing Java Tasks with different configuration

lmollea
Champ in-the-making
Champ in-the-making
I have a modeling problem, I need to reuse a Java Service Task twice (or more) in the same process, passing him some "parameters" that alter slightly the behaviour.

Basically I will receive a signal from the outside that will tell a process instance that an event has happened (basically a file received event). The process will wait for more than one file over the process life, but the external system that receives files doesn't know which file will be picked up by which task so it just sends a "file received" event with the name of the file received. The process may be waiting for more than one file and all the File Received task will be woken up by the signal and will go back in the signal wait if the file is not the one they're expecting.

Besides, I'd like to use spring beans as tasks as they can integrate nicely with @Autowired dependencies from my spring environment.

So far I used a delegate expression when defining task (like ${fileLoaderTask}) and I have a @Component FileLoaderTask class that gets picked up by Spring component scanner and used by Activity.

Point is that I used an Expression fields in FileLoaderTask to indicate to the task which file that task will have to check for. Problem is that expression are set at task creation and task gets resued, so the value that the Expression will return in every path of the process will be the same and will be the last one set by the Engine. This of course screws up my process flow (as all those tasks will basically be the same).

Any suggestion about how to model this behaviour?

Only thing that comes to mind is if Activity can create those tasks instances via a Spring Factory bean so that instances will be different (and with different instance variables) specifying ${taskBeanFactory.createTask('file_1')}, ${taskBeanFactory.createTask('file_2')}, … instead of simply using ${fileLoaderTask}. That way seems working.
5 REPLIES 5

jbarrez
Star Contributor
Star Contributor
Why do you need to use expressions there, wouldn't it be more logical to depend on some other Spring beans for that? In that case, you don't have the issue that expressions are static. Of course, the actual runtime behaviour can only consult those dependent beans when they are actually needed rather than on creation time.

or am i completely misunderstanding your problem?

lmollea
Champ in-the-making
Champ in-the-making
Image worth a thousand words (sorry I could have added this before)

[img]http://s28.postimg.org/hamsam4d9/multitask.png[/img]

The issue: logic for handling file in both "Handle File 1" and "Handle File 2" is the same. What changes is the configuration that such code needs. What I have to do is make sure that when the logic for "Handle File 1" and "Handle File 2" are invoked they know which leg of the process they are on and act accordingly (basically, they need a pointer to a config that's in a database they have to retrieve).

For both tasks, we used a spring bean pointed by a delegate expression (${fileLoaderTask}), on "Handle File 1" we set a "config" field to the "File 1" value, while on "handle File 2" we set the same field ("config") to "File 2". In this scenario, we had only one ${fileLoaderTask} instance (not a bad thing per se) but the value of "name" field was set to the last one that the engine set, so both legs ended getting either "File 1" or "File 2", depending probably on the parsing order in the XML.

I can't create specialized beans for the two different legs, given the number of processes we have, we may end up creating thousands of beans in the spring context and it's not advisable.

I also cannot merge the different tasks into one as the two handle file tasks are in the middle of different, unmergeable process flows.

For the moment we solved by changing the delegate expression to ${fileLoaderTaskFactory.createTask("…")} using a factory bean that creates instances of FileLoaderTask each pointing to a different config. It's not optimal if each time a new fileLoaderTask instance gets create, but it's working.

Point is: is there a better way to do this?

jbarrez
Star Contributor
Star Contributor
I don't see a better way to do it … maybe store the config in variables and let the beans use those variables?
Altough i don't really like that approach either … hmmm good use case.

lmollea
Champ in-the-making
Champ in-the-making
Thanks for the reply.

If I may, and if the BPMN specs don't forbid it (sorry, I don't know them), why not add a sort of optional "force reassign" config on tasks so that every time it's executed, the expressions get reassigned before execution so that it may "mock" a "multiple instance" scenario for the Java Class?

Unless another nicer (more intuitive) approach would be add an optional config (like activiti:async), say activiti:reuse=false so that more than one instance of the same class can be created (it won't work with spring beans UNLESS the beans are picked from a factory that can create more instance on request)?

Uhm… while I was writing this last one sentence I have to explore if spring support such thing.

jbarrez
Star Contributor
Star Contributor
The Spring approach might work if you let it implement a FactoryBean interface I believe.

So to summarize: java service classes are cached, but you can always inject through expressions that are resolved at runtime.