cancel
Showing results for 
Search instead for 
Did you mean: 

Error on loop with asynchronous activities

mmaker1234
Champ in-the-making
Champ in-the-making
Hello Activiti developers,

I wanted to better understand what is the actual behavior of the "local" and "global" process variables and started with an example, which revealed many problems.

Please find attached a simplified example to demonstrate two of these problems: a process definition with three script (JavaScript) activities (
initVars
,
inc
, and
printVars
) and an XOR gateway.

The problem with the attached process definition is that any process instance execution fails with[java]May 13, 2013 3:00:21 PM org.activiti.engine.impl.interceptor.CommandContext close
SEVERE: Error while closing command context
org.activiti.engine.ActivitiException: Query return 2 results instead of max 1
    at org.activiti.engine.impl.AbstractQuery.executeSingleResult(AbstractQuery.java:162)
    at org.activiti.engine.impl.AbstractQuery.execute(AbstractQuery.java:141)
    at org.activiti.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
    at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:61)
    …[/java]

The process definition is attached as TestLocalVariablesSimple.bpmn_.txt (of course you should rename it to TestLocalVariablesSimple.bpmn in order to review it) and a process instance execution log is attached as TestLocalVariablesSimple.log_.txt

While reading the execution log you will see
org.activiti.engine.impl.cmd.NoJobRetriesCmd
- this is my modification of the Activiti's DecrementJobRetriesCmd - I just do not want the jobs to retry. I can provide its code if you need it.

If I remove the Asynchronous flag from the activities included in the loop (
inc
and
printVars
) the process instance runs fine for small number of cycle repetitions.

The other problem is that each run fails with the following error when I increase the limit of the cycle to 100 : [java]
INFO: start Activity definitionId=inc, processId=77915, executionId=77915, name='inc', with properties: {default=null, name=inc, documentation=null, type=scriptTask}, persistent state: {isActive=true, activityId=inc, parentId=null, isScope=true, cachedEntityState=4, businessKey=null, suspensionState=1, isEventScope=false, superExecution=null, processDefinitionId=TestLocalVariablesSimple:5:77914, isConcurrent=false}, ProcessInstance id=77915, Execution id=77915, ProcessDefinition(id)='TestLocalVariablesSimple:5:77914', vegas_version: 'null', Scope
Exception in thread "pool-1-thread-4" java.lang.StackOverflowError
    ….
[/java]It seems that the execution of the consecutive activities runs in the context of the JavaScript expression, which does not seems correct.

Please find the details in the attached process definition TestLocalVariablesSimpleSynchronous .bpmn_.txt and the corresponding execution log TestLocalVariablesSimpleSynchronous.log_.txt

Please help me to sort out these two problems.

Best Regards,
Monique
18 REPLIES 18

jbarrez
Star Contributor
Star Contributor
It's pretty hard to test it like that. Can't you add the parsers to the maven project and change the config so it matches the setup? That way I can execute it directly.

mmaker1234
Champ in-the-making
Champ in-the-making
Hello Joram,

Please find attached, although I'm not sure what happens - the project points to an Activiti engine in a Maven repository, i.e. without my modifications, but the test still managed to start an engine before I to add these classes to the project, i.e. the test finds my modifications somewhere outside the project (otherwise, when <code>postBpmnParseHandlers</code> property points to non-existing classes, no engine is started). Therefore I, unfortunately, can not guarantee the test will work correct at your side.

jbarrez
Star Contributor
Star Contributor
Ok, it ran perfectly now.

The problem is actually pretty simple. If you check lower in the stacktrace, you see this line:

<code>
at org.activiti.engine.parse.ActivityInstanceLogger.formatInfo(ActivityInstanceLogger.java:47)
at org.activiti.engine.parse.ActivityInstanceLogger.notify(ActivityInstanceLogger.java:26)
</code>

which matches this code:

<code>
HistoricActivityInstance historicActivity = execution.getEngineServices().getHistoryService().createHistoricActivityInstanceQuery().activityId( activity.getId() ).executionId( execution.getId() ).singleResult();
</code>

However, since you're looping over the same activity, there will be multiple entries in the historic activity instance table for the same activity id. That is the reason why it fails, you specifically add 'singleResult' which forces the check on one element.

So what you need to do is this:

<code>
     List<HistoricActivityInstance> historicActivityInstances = execution.getEngineServices().getHistoryService().createHistoricActivityInstanceQuery().activityId( activity.getId() ).executionId( execution.getId() ).orderByHistoricActivityInstanceEndTime().desc().list();
      HistoricActivityInstance historicActivity = historicActivityInstances.isEmpty() ? null : historicActivityInstances.get(0);
  </code>

Sort end time and take the newest from the list.

Hope that helps.

mmaker1234
Champ in-the-making
Champ in-the-making
Hello Joram,

Thank you for your help.

The problem is that according the process definition I expect two instances of the same activity to never co-exist. The run on Linux environment is a proof for that (on my Linux run the process instance finishes without errors). As I already stated it seems the problem is in the Windows environment and I can not find any rational explanation of this misbehavior. Actually this was the question behind the problem demonstration - what is the reason (on Windows environment) two instances of the same activity to (unexpectedly) co-exist?

My intention was additionally to warn you that you might be walking on a thin ice in some areas of the Activiti implementation (and that was the reason I mentioned "(hidden) racing conditions" in my previous posts). My fear is that the demonstrated misbehavior might be a time-bomb that could fire in a future version of Activiti, i.e. my current process definition or my (logging) tools to stop working with a future version of Activiti due to not API but implementation changes, and such changes might pass our tests and display only on production systems.

Actually the process definition demonstrated in the test case is a huge simplification of my real process, which currently doesn't suffer of the described problem.

jbarrez
Star Contributor
Star Contributor
I didn't say it in the previous post, but I did run the test on my machine. And their it failed the way you described it. So I don't think it is a rece condition problem at all.

<code>The problem is that according the process definition I expect two instances of the same activity to never co-exist. </code>

It does when you use multi instance. or any looping for that matter.
So it is not a matter of not expecting it - the way I understood your process definition … there will always be multiple records for the same activity.

<code>The run on Linux environment is a proof for that (on my Linux run the process instance finishes without errors)</code>

So the test you posted here runs on Linux? Cause my OS X is pretty close to Linux in that respect … but I can always retry.

mmaker1234
Champ in-the-making
Champ in-the-making
Hello Joram,

I'm very sorry but I didn't paid the needed attention to this conversation (it's a small asylum here these days 😞 ). Please accept my apologies. To be honest, I didn't run the unit test on the Linux environment before to sent it to you.

I just found some peace and re-red the thread. Definitely you're right that the history should contain several records for each activity. I also managed to run the (unit) test on an Oracle DB. It failed on both Windows and Linux, as you expected, although it was somewhat unexpected to me.

Now the pre-history of this thread: Initially I observed the problem using an Ant task for starting process instances (once their definition(s) were uploaded in the DB). Actually it is very simple task and I could provide the code if you're still interested.

Currently the things are still strange to me because I (still) use the same Ant task on both Windows and Linux and I still observe the behavior described above - the process instance execution fails on Windows, as expected by you, but runs fine on Linux as (wrongly) expected by me.

OK, this posting is just a note on the progress. I'm not quite sure the discussion deserves more attention… It seems the problem (if it is a problem at all) is in some environment but it might became too complex to be investigated.

Thank you for your time and explanations,
Monique

jbarrez
Star Contributor
Star Contributor
No problem at all. Such discussions are needed to discover problems with Activiti. Sometimes it's nothing, sometimes it's a real bug 🙂

It sure sounds really strange it works on Windows with ant … Are you sure it is actually executing anything at all 😉

mmaker1234
Champ in-the-making
Champ in-the-making
Hello Joram,

Actually it fails on Windows with Ant and runs smoothly on Linux with Ant 🙂

I think it executes something because it outputs all the values for the variable 🙂

mmaker1234
Champ in-the-making
Champ in-the-making
Damn it! This is some kind of black magic! Or it's the moon phase… *DONT_KNOW*

When I experimented, I started process instances on Windows and was able to terminate them only on Linux exactly for this behavior difference. I tried to reproduce the execution on Linux to provide you a log as a proof but now it also fails.

Hmmm, probably I should try to run it on Windows - the places might be exchanged… 😄

Whatever, strange things happen. Lets look into the future *drinks*