spring-enabled process applications and shared process engine = bad idea?

1,236 views
Skip to first unread message

kwma...@gmail.com

unread,
Feb 18, 2015, 2:45:01 AM2/18/15
to camunda-...@googlegroups.com
Hello Camunda Comunity,

I’ve heard at a Camunda Training that there are limitations when using spring-enabled process applications with a shared process engine (in our setup it would be on tomcat 7).

What are these limitiations in detail? E.g. will there be a problem with transactions so that this part of the documentation [1] is only valid for spring-enabled process applications and embedded process engine?

Thanks & Regards
Kristian

[1]: Spring transaction integration http://docs.camunda.org/latest/guides/user-guide/#spring-framework-integration-spring-transaction-integration

thorben....@camunda.com

unread,
Feb 18, 2015, 5:10:08 AM2/18/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi Kristian,

Note that you can bootstrap a process engine in a Spring application context using the ManagedProcessEngineFactoryBean (cf [1]). In this case, the process engine is registered as a shared engine. It's lifetime is coupled to the life time of the spring application, meaning that it is deregistered when application context is destroyed. For such an engine, you should be able to configure transaction integration.

On using Spring transaction integration with an existing (non-Spring) shared engine, I am not sure to be honest. I'll forward this to our Spring expert when he returns to office in two days.

Cheers,
Thorben

[1] http://docs.camunda.org/latest/guides/user-guide/#spring-framework-integration-process-engine-configuration-configuring-a-container-managed-process-engine-as-a-spring-bean

Jan Hölter

unread,
Feb 23, 2015, 10:12:14 AM2/23/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hello Torben,

i stumbled upon this thread while i was looking for a solution for my particular problem.
I already managed to bootstrap the engine in my spring application context and register it as a shared engine (i guess).
But now i am facing some problems.

But let me give you some context first:
We've been running our processes on a prepackaged tomcat using a shared engine configured in the server.xml.
In our Spring Application we published the default engine in the context as a Spring Bean using the "BpmPlattform" class and everything worked fine.
Now we have the requirement to configure the ProcessEngine to use a custom "Process Engine Plugin". We need that to send notifications on completed user tasks (by registering a custom BpmnParseListener).
This seemed like the way to achieve this, following some guides on one of your github repos.
But since the engine was not configured by our spring application i wasn't able to register the plugin (from the spring app) so i figured we have to bootstrap and configure the engine in our application.

The problem is that we still want to be able to use the camunda cockpit to administrate our processes and we also want to be able to deploy additional process applications independently to the same engine.

So i hoped what you described - bootstrapping the engine with spring and registering it as a shared engine - would do the trick.

Reading what i just wrote it sounds pretty much like i am already shaving a yak...

Anyway...unfortunately i was not able to deploy another process application to the same engine. The error message says there is no engine named "default" registered. That makes perfect sense as the spring application registering the engine seems to be deployed after the additional process application.
Also using Cockpit (the standalone war) doesn't work. The deployment works fine but none of my processes is visible...

What do i miss here ? Any suggestions, solutions or advices you could give me ? Am i even on the right track to solve my problem ?

Thank you & kind regards

Jan

thorben....@camunda.com

unread,
Feb 24, 2015, 11:51:56 AM2/24/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi Jan,

Unfortunately I am not able to give you advice on how to solve the problem of deployment orderings. I just don't know if and how this can be done on Tomcat.

For the processes not being visible in Cockpit:
The standalone webapp differs from the "regular" webapp in that it ships the camunda-engine.jar. This means, it can be used without having shared engines and without having camunda libraries in the global classpath. That is what we mean with "standalone".

Process engines are looked up from a static map (confer the class ProcessEngines). When you register a shared engine from your Spring application, the process engine will be registered in the class ProcessEngines of the global library camunda-engine. As the standalone webapp ships the camunda-engine library too, it tries to look up the engine from this library's ProcessEngines class. However, this is a different ProcessEngines class, so your shared engine cannot be found.

This means, if you use a shared engine, i.e. you have camunda-engine.jar in the global classpath, register process engines there and expect cockpit to find these engines, you should not use the standalone webapp.

This is especially important, if you have the requirement that your process engine plugins are also used performing actions in cockpit. If all you need is that Cockpit accesses the same database, then you can also use the standalone webapp. Then, you have to configure an engine in the standalone webapp that points to the same database though.

I hope this clarifies the logic of looking up shared engines a little.

Cheers,
Thorben

Melissa Palmer

unread,
Feb 25, 2015, 1:59:12 AM2/25/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi 

I have managed to get a spring-enabled process applications with a shared (Spring) process engine which uses a custom Plugin working, on tomcat. 
HOWEVER: I cannot answer the question of what limitations and if there are transaction issues. 

Steps to do this are worked out from [1], [2], [3] and are that
a) setup your tomcat/conf/server.xml and ensure you have configured it such that:
-- You don't have the "BPM Bootstrap Server Listener" eg: remove <Listener className="org.camunda.bpm.container.impl.tomcat.TomcatBpmPlatformBootstrap" />
-- JDBC Resource
-- ProcessEngineService  (note in the link they have "global/camunda-bpm-platform/process-engine/ProcessEngineService!org.camunda.bpm.ProcessEngineService" I used "java:global/camunda-bpm-platform/process-engine/ProcessEngineService!org.camunda.bpm.ProcessEngineService")
-- ProcessApplicationService   (note in the link they have "global/camunda-bpm-platform/process-engine/ProcessApplicationService!org.camunda.bpm.ProcessApplicationService" I used "java:global/camunda-bpm-platform/process-engine/ProcessApplicationService!org.camunda.bpm.ProcessApplicationService")

b) Modify the applicationContext.xml for the war which you want to deploy as your "embedded engine which is registered as a shared engine." as described in the link below:
in stead of using the "org.camunda.bpm.engine.spring.ProcessEngineFactoryBeanProcessEngineFactoryBean" you need to use the ManagedProcessEngineFactoryBean  as detailed in 

c) To have each process in a separate war (which does not bootstrap the engine) configure these wars according to the spring bonus chapter at: 

d) The IdentityProvider implementation is attached to the "processEngineConfiguration"  as below (MyIdentityPlugin implements ProcessEnginePlugin)
<bean id="processEngineConfiguration" class="org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration">
...
<property name="processEnginePlugins">
<list>
<ref bean="myIdentityPlugin" />
</list>
</property>
...
</bean>

e) camunda-engine*.jar must be at a global level (eg: in tomcat lib folder) and for all wars that you deploy must be removed from its own lib folder. This includes the rest-engine.war and camunda-webapp.war (a side note is that I build the camunda-webapp.war using a Maven War Overlay so its not the camunda-standalone-webapp.war)

f) ensure that you don't have the bpm-platform.xml under tomcat/conf/

g) And lastly you have to ensure that you war with the shared engine is started first! I have used the trick from [4] to ensure this and it seems to be working well. 
"If you want to specify the deployment order then define a context for your web app in $CATALINA_BASE/conf/[enginename]/[hostname]/MyApp.xml"



Regards
Melissa

Jan Hölter

unread,
Feb 25, 2015, 4:18:47 AM2/25/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi Melissa and Thorben.

First, thanks a lot for your help.
I figured out yesterday that the Problem was that I have two instances of the ProcessEngineService holding the map with the registered Engines in my setup (one per webapp).
My assumption was that the point of registering the engine as an MBean was to be able to share a reference to the engine between multiple webapps.
Unfortunately (at least for me ;) ) what the service does is registering the engine as a MBean but keeping the reference itself in a map and just looks up the map to get the reference as you pointed out, Thorben.
So that also makes it obvious why the standlone apps won't work for the reasons you describe.

That leaves me with Melissa's solution which is kind of a hybrid if i understand correctly. I assume i already got the main part of the configuration right (we use a Java based Config so i hat to translate it, maybe there's still something missing).
So the imporant part of your solution is to have a "global" container level instance of the EngineService (and ApplicationService) by configuring it in the server.xml, is that correct ? This is basically what is missing im my setup.

I will also try your "trick" for the deployment order, Melissa. Thanks a lot. I had already given up on this because i found the tomcat wiki FAQ answer claiming that "there is no expected startup order". Instead i tried to poll to find out if the engine was already deployed before deploying the processes, which finally led my to find out about the two engine service instances...

Wow...i never planned on digging so deep for just sending notifications on completed tasks ;).

Thanks a lot again to you two for your help.

Kind regards
Jan

Melissa Palmer

unread,
Feb 25, 2015, 4:27:11 AM2/25/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi Jan 

- Yes part of the key was the global EngineService (and ApplicationService) in server.xml 
- But the crux is that the camunda-engine*.jar needs to be at a global level and not within the lib of any of your webapps. (I'm understanding this to correct the issue Thorben describes about "Process engines are looked up from a static map" )
- Not sure if its correct to say this is a hybris setup.... it's the setup described for a "Configuring a container-managed Process Engine as a Spring Bean" described at: http://docs.camunda.org/latest/guides/user-guide/#spring-framework-integration-process-engine-configuration-configuring-a-container-managed-process-engine-as-a-spring-bean

Regards
Melissa

Jan Hölter

unread,
Feb 25, 2015, 5:09:47 AM2/25/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi Melissa,

that is basically what i meant. I guess having the .jar in tomcat lib is needed to be able for the server.xml configuration because otherwise the adressed classes won't be visible in the tomcat classpath.

About the map. I believe in the MBean Scenario the engine references are provided in a map in the MBeanServiceContainer class which is called by the JmxRuntimeContainerDelegate (an EngineService implementation).

 public ProcessEngine getDefaultProcessEngine() {
   
return serviceContainer.getServiceValue(ServiceTypes.PROCESS_ENGINE, "default");
 
}

But maybe i got something wrong here. Can you maybe clarify that, Thorben ?

About "hybris"...that was a missunderstanding, i guess. Actually i said "hybrid" (which has a completely different meaning) meaning that it kind of mixes parts of the standalone configuration with an embedded configuration.
This is by no means an invalid or somehow solution. In fact this is probably exactly what i was looking for. My problem was that i got rid of the complete "standalone" configuration from the tomcat before i set up the embedded container managed engine.
You really spelled that out for me, which helped me a lot.

Kind regards
Jan

thorben....@camunda.com

unread,
Feb 26, 2015, 12:04:51 PM2/26/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi Jan,

On the MBeanServiceContainer: It is correct that each engine that is registered as a shared engine can be looked up via JMX. So in fact, there are two registrations: One in the map managed by class ProcessEngines and one in the MBeanServer.

Rule of thumb:
* every process engine (shared or embedded) is registered in the class ProcessEngines
* every shared engine is also registered in the MBeanServer of the JVM

If the standalone webapp would use the lookup via JMX, it would be able to find a shared engine. However, as it contains the engine library itself, this would result in class casting exceptions because the shared engine is an instance of a different ProcessEngine class than the ProcessEngine class contained in the standalone webapp. That is also why the REST API and the REST resources used by the webapps do not use the lookup via BpmPlatform but rely on ProcessEngines.

Cheers,
Thorben
Reply all
Reply to author
Forward
0 new messages