cancel
Showing results for 
Search instead for 
Did you mean: 

Deploying in Tomcat

walterjs
Champ in-the-making
Champ in-the-making
Hi there,

I've been running the process engine using spring and now I want to deploy this to the tomcat instance where the activiti-rest webapp is deployed. I renamed my "main" spring config file to activiti.cfg.xml and removed the original activit-cfg.jar from the activiti-rest/WEB-INF/lib dir and the activiti-explorer works perfectly.

The problem is that none of my spring beans are instantiated. Doing a remote debug, I see all the beans and I can even reference them (then they are created) during this session. But my jms listener, for instance, is not started:


    <bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="destination" ref="topic"/>
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="messageListener" ref="connector"/>
    </bean>

My standalone server consists of the following line in the main method:
new ClassPathXmlApplicationContext("applicationContext.xml")

I've also deployed this in my own standalone webapp in the same container (everything starts up fine using an ApplicationContextListener), but I'm not sure how to get the rest webapp to use my spring configured engine. Modifying the rest webapp web.xml sounds wrong to me.

Any help would be appreciated.

Thanks
Walter
8 REPLIES 8

frederikherema1
Star Contributor
Star Contributor
Walter,

Can you show how exactly you use/configure/startup your process-engine?

walterjs
Champ in-the-making
Champ in-the-making
I presume you want to see my spring config. Here is the relevant section:


    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <property name="processEngineConfiguration" ref="processEngineConfiguration" />
    </bean>

    <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
        <property name="databaseType" value="h2"/>
        <property name="dataSource" ref="dataSource"/>
        <property name="transactionManager" ref="transactionManager"/>
        <property name="mailServerHost" value="localhost"/>
        <property name="mailServerPort" value="5025"/>
        <property name="jpaHandleTransaction" value="true"/>
        <property name="jpaCloseEntityManager" value="true"/>
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
        <property name="targetDataSource">
            <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
                <property name="driverClass" value="org.h2.Driver"/>
                <property name="url" value="jdbc:h2:tcp://localhost/activiti"/>
                <property name="username" value="sa"/>
                <property name="password" value=""/>
            </bean>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>


As I said, this all starts up fine, it is the rest of my beans (most notably the jms listener) that do not start.

Thanks
Walter

frederikherema1
Star Contributor
Star Contributor
Walter,

There seems to be nothing wrong with your configuration, but the way it is used is a bit different than you would expect.

Since you renamed your spring-config file to activiti.cfg.xml, this will be picked up by the rest-webapp's ContextListener. This will read this configuration (using spring), but will only use the bean 'processEngineConfiguration'.

It's indeed a bit confusing, but in the case of activiti.cfg.xml, spring is only used to wire the configuration. We take advantage of spring-bean functionalities to read configuration, since we don't want to reinvent the wheel and write our ow IOC-container. check out http://activiti.org/userguide/index.html#configurationRoot for more info in the configuration.

walterjs
Champ in-the-making
Champ in-the-making
Ok, thanks.

Could you please let me know the preferred way of deploying the spring beans? When I complete a task (by submitting a form) through the activiti-explorer, how would a subsequent serviceTask evaluate an expression that refers to one of the beans in my spring configuration?

Here is my process for reference:


<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://www.activiti.org/test">
<process id="ModelTest" name="ModelTest">
  <startEvent id="startevent1" name="Start"></startEvent>
  <userTask id="usertask1" name="Review"
   activiti:candidateGroups="accountancy" activiti:formKey="approval.form"></userTask>
  <userTask id="usertask2" name="Approve"
   activiti:candidateGroups="manager" activiti:formKey="approval.form"></userTask>
  <sequenceFlow id="flow1" name="" sourceRef="startevent1"
   targetRef="usertask1"></sequenceFlow>
  <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
  <sequenceFlow id="flow2" name="" sourceRef="usertask1"
   targetRef="exclusivegateway1"></sequenceFlow>
  <sequenceFlow id="flow4" name="" sourceRef="exclusivegateway1"
   targetRef="endevent1">
   <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!approved}]]></conditionExpression>
  </sequenceFlow>
  <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
  <sequenceFlow id="flow5" name="" sourceRef="usertask2"
   targetRef="exclusivegateway2"></sequenceFlow>
  <sequenceFlow id="flow7" name="" sourceRef="exclusivegateway1"
   targetRef="usertask2">
   <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approved}]]></conditionExpression>
  </sequenceFlow>
  <sequenceFlow id="flow8" name="" sourceRef="exclusivegateway2"
   targetRef="endevent1">
   <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!approved}]]></conditionExpression>
  </sequenceFlow>
  <serviceTask id="servicetask1" name="Retry"
   activiti:expression="#{myBean.invoke()}"></serviceTask>
  <sequenceFlow id="flow9" name="" sourceRef="exclusivegateway2"
   targetRef="servicetask1"></sequenceFlow>
  <sequenceFlow id="flow10" name="" sourceRef="servicetask1"
   targetRef="endevent1"></sequenceFlow>
  <endEvent id="endevent1" name="End"></endEvent>
</process>
</definitions>

walterjs
Champ in-the-making
Champ in-the-making
Ok, I've got this to work by changing org.activiti.engine.ProcessEngineConfiguration.


  protected static ProcessEngineConfiguration parseProcessEngineConfiguration(Resource springResource, String beanName) {
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    xmlBeanDefinitionReader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_XSD);
    xmlBeanDefinitionReader.loadBeanDefinitions(springResource);
    GenericApplicationContext ctx = new GenericApplicationContext(beanFactory); // <– new
    ctx.refresh(); // <– new
    return (ProcessEngineConfiguration) ctx.getBean(beanName);
  }

I added the two lines to be able to refresh the context.

Now my deployed processes can access spring variables in expressions when running from inside the tomcat container.

Please let me know if this was the original intention or if I'm just not deploying this as you would recommend.

Thanks
Walter

walterjs
Champ in-the-making
Champ in-the-making
Changing the subject to hopefully get a response

tombaeyens
Champ in-the-making
Champ in-the-making
Walter,

Can you explain how refreshing the context is related to the visibility of beans in expressions?  I didn't get that part.

walterjs
Champ in-the-making
Champ in-the-making
Thanks for your reply Tom,

I'm not sure why this is happening, but without those lines of code I added (refreshing the context), my process fails when it tries to execute the expression referencing my spring configured bean. In addition to that, any of the beans that should be started up automatically, don't (for example my JMS listener).

Is this the way to deploy my spring context to be used by activiti-explorer? Should I rename my spring context to activiti.cfg.xml and replace the activiti-cfg.jar in the rest webapp lib directory with my own set of jars and dependencies?

Thanks
Walter