cancel
Showing results for 
Search instead for 
Did you mean: 

Activiti CDI startup in an EAR with multiple WARs

jkronegg
Champ in-the-making
Champ in-the-making
Hello,

I'm looking to build an EAR with the following features:
  • multiple WARs, some with Activiti, some without Activiti.
  • Activiti libraries are in the EAR's "lib" directory, so are in the same classloader.
  • WARs with Activiti uses CDI (i.e. they have a beans.xml and services\org.activiti.cdi.spi.ProcessEngineLookup)
  • WARs without Activiti also uses CDI (i.e. they have a beans.xml)
  • The custom ProcessEngineLookup used in the WARs with Activiti are in the EAR's "lib" directory
<!–break–>

The EAR Structure is the following:


    EAR
        +- lib
            +- activiti-engine-5.15.1.jar
            +- activiti-cdi-5.15.1.jar
            +- activiti-process-validation-5.15.1.jar
            +- activiti-bpmn-converter-5.15.1.jar
            +- activiti-bpmn-model-5.15.1.jar
            +- slf4j-jdk14-1.7.5.jar
            +- slf4j-api-1.7.6.jar
            +- mybatis-3.2.5.jar
            +- myLib.jar     containing "test.MyProcessEngineLookup"
        +- WAR1: TestWorkflow1  (with Activiti CDI)
            +- META-INF\services\org.activiti.cdi.spi.ProcessEngineLookup  containing "test.MyProcessEngineLookup"
            +- META-INF\beans.xml   containing nothing
        +- WAR2: TestWorkflow2  (with Activiti CDI)
            +- META-INF\services\org.activiti.cdi.spi.ProcessEngineLookup  containing "test.MyProcessEngineLookup"
            +- META-INF\beans.xml   containing nothing
        +- WAR3: TestWorkflow3  (without Activiti, but with CDI)
            +- META-INF\beans.xml   containing nothing

The
test.MyProcessEngineLookup
class implements
org.activiti.cdi.spi.ProcessEngineLookup
and its
getProcessEngine()
method returns a non-null instance of
ProcessEngine
(just for the sake of test:
new ProcessEngine(){…}
).

Note that
MyProcessEngineLookup
of the WARs with Activiti (WAR1 and WAR2) uses the same classloader:

com.ibm.ws.classloader.CompoundClassLoader@e0bdf1e5[app:application]
   Local ClassPath: C:\misc\activiti-cdi-5.15.1.jar;C:\misc\activiti-engine-5.15.1.jar;C:\misc\slf4j-jdk14-1.7.5.jar;C:\misc\slf4j-api-1.7.6.jar;C:\misc\mybatis-3.2.5.jar;C:\misc\activiti-process-validation-5.15.1.jar;C:\misc\activiti-bpmn-converter-5.15.1.jar;C:\misc\activiti-bpmn-model-5.15.1.jar;C:\misc\workspace\TestWorkflowLib\target\classes
   Parent: com.ibm.ws.classloader.ProtectionClassLoader@efeabbdb
   Delegation Mode: PARENT_FIRST

The deployment under WebSphere 8.5 works properly for the two first WARs but fails for the last WAR. It shows the following log:



[26.05.14 09:07:03:979 CEST] 00000703 webapp        I com.ibm.ws.webcontainer.webapp.WebGroupImpl WebGroup SRVE0169I: Loading Web Module: TestWorfklow.war.
[26.05.14 09:07:03:995 CEST] 00000703 WASSessionCor I SessionContextRegistry getSessionContext SESN0176I: Will create a new session context for application key default_host/TestWorfklow
[26.05.14 09:07:04:026 CEST] 00000703 ActivitiExten I org.activiti.cdi.impl.ActivitiExtension afterDeploymentValidation Initializing activiti-cdi.
[26.05.14 09:07:04:042 CEST] 00000703 servlet       I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [TestWorkflowEar] [/TestWorfklow] [my.TestServlet]: Initialization successful.

[26.05.14 09:07:04:073 CEST] 00000703 webapp        I com.ibm.ws.webcontainer.webapp.WebGroupImpl WebGroup SRVE0169I: Loading Web Module: TestWorkflow2.war.
[26.05.14 09:07:04:089 CEST] 00000703 WASSessionCor I SessionContextRegistry getSessionContext SESN0176I: Will create a new session context for application key default_host/TestWorkflow2
[26.05.14 09:07:04:120 CEST] 00000703 ActivitiExten I org.activiti.cdi.impl.ActivitiExtension afterDeploymentValidation Initializing activiti-cdi.
[26.05.14 09:07:04:120 CEST] 00000703 servlet       I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [TestWorkflowEar] [/TestWorkflow2] [my.TestServlet2]: Initialization successful.

[26.05.14 09:07:04:151 CEST] 00000703 webapp        I com.ibm.ws.webcontainer.webapp.WebGroupImpl WebGroup SRVE0169I: Loading Web Module: TestWorkflow3.war.
[26.05.14 09:07:04:167 CEST] 00000703 WASSessionCor I SessionContextRegistry getSessionContext SESN0176I: Will create a new session context for application key default_host/TestWorkflow3
[26.05.14 09:07:04:182 CEST] 00000703 ActivitiExten I org.activiti.cdi.impl.ActivitiExtension afterDeploymentValidation Initializing activiti-cdi.
[26.05.14 09:07:04:182 CEST] 00000703 ErrorStack    E ErrorStack logErrors
                                 org.activiti.engine.ActivitiException: Could not find an implementation of the org.activiti.cdi.spi.ProcessEngineLookup service returning a non-null processEngine. Giving up.
   at org.activiti.cdi.impl.ActivitiExtension.lookupProcessEngine(ActivitiExtension.java:106)
   at org.activiti.cdi.impl.ActivitiExtension.afterDeploymentValidation(ActivitiExtension.java:68)


The "failing WAR3 startup" issue comes from the org.activiti.cdi.impl.ActivitiExtension class which observes an
AfterDeploymentValidation
event which is raised for every deployed WAR.

There is another issue: the processes are deployed twice by
ActivitiExtension
, once in WAR1 and once in WAR2.

Do theses two issues come from a bad configuration or is there an issue with the Activiti-CDI deployment procedure ?
3 REPLIES 3

jbarrez
Star Contributor
Star Contributor
No, it seems that each war will deploy the processes. I don't think there is a way around that - you will need another way of deploying your processes (eg programmatically / through REST / …)

bardioc
Champ in-the-making
Champ in-the-making
Hello,

your setup is definitely a mess with CDI. The currently available Implementation for CDI is
  • WebSphere 8.0.0.x -> CDI OWB 1.0.1
  • WebSphere 8.5.5.x -> CDI OWB 1.1.0
  • WebSphere Liberty 8.5.5 -> CDI OWB 1.6.x
Even this makes it difficult to help you out, cause some major drawbacks of the CDI spec have been fixed with version 1.1.x.

What you can do to here is, that you provide a deployment.xml within your EAR and change the class loading strategy to SINGLE instead of MULTIPLE, thus all WARs, EJBs and JARs share the same class loader. We use this too in some projects to make sure CDI-interceptors and -decorators work over JAR/WAR boundaries. However, note, that this is a configuration that IBM itself considers as 'not-supported'. From our experiences it works quite well.

Some more information can be found here: https://issues.apache.org/jira/browse/DELTASPIKE-335

Deltaspike tries to get around this issue, however they can't really find a application server independent solution.

Regards,

Heiko

jbarrez
Star Contributor
Star Contributor
@Heiko: thanks for this insight. Very good information.