1 Reply Latest reply on Aug 10, 2015 8:27 AM by carlone

    JBPM 6 + Spring + Tomee + PostgreSQL

    carlone

      Hi everyone,

       

      i'm struggling to integrate JBPM 6.2 with Spring and PostgreSQL, because i'd like to use Audit mechanisms in my webapp that already store informations on PostgreSQL, but i'm encountering transactional issues.

      When i start Tomee i get a "java.lang.IllegalArgumentException: Named query not found: UnescalatedStartDeadlines" exception, but i don't worry about it for now: i think it's related to orm.xml Named queries.

      My webapp goes up well and tables ara created correctly whit Hibernate (SessionInfo, CorrelationKeyInfo etc etc), but when i try to execute a process, i get an exception

       

      org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.RuntimeException: Unable to begin transaction

       

      caused by

       

      java.lang.NullPointerException

      org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:697)

      org.kie.spring.persistence.KieSpringTransactionManager.getStatus(KieSpringTransactionManager.java:136)

      org.kie.spring.persistence.KieSpringTransactionManager.begin(KieSpringTransactionManager.java:50)

      org.drools.persistence.SingleSessionCommandService$TransactionInterceptor.execute(SingleSessionCommandService.java:517)

      org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:41)

      org.drools.persistence.jpa.OptimisticLockRetryInterceptor.execute(OptimisticLockRetryInterceptor.java:73)

      org.drools.core.command.impl.AbstractInterceptor.executeNext(AbstractInterceptor.java:41)

      org.drools.persistence.jta.TransactionLockInterceptor.execute(TransactionLockInterceptor.java:79)

      org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:358)

      org.drools.core.command.impl.CommandBasedStatefulKnowledgeSession.startProcess(CommandBasedStatefulKnowledgeSession.java:242)

      org.drools.core.command.impl.CommandBasedStatefulKnowledgeSession.startProcess(CommandBasedStatefulKnowledgeSession.java:233)

      it.arpav.eip2.service.impl.TestServiceImpl.test(TestServiceImpl.java:32)

      etc etc

       

      i'm not really sure that JBPM allow this kind of configuration with Spring, as i read in the documentation, but i'm so near to the solution that i have to make it

      Here's my source code:

       

      Call from the controller (line 24):

       

      public class TestServiceImpl implements TestService {
      
      
        RuntimeManager runtimeManager;
        AuditLogService logService;
      
      
        public void setRuntimeManager(RuntimeManager runtimeManager) {
        this.runtimeManager = runtimeManager;
        }
      
      
        public void setLogService(AuditLogService logService) {
        this.logService = logService;
        }
      
      
        @Override
        public void test() {
      
        RuntimeEngine engine = runtimeManager.getRuntimeEngine(ProcessInstanceIdContext.get());
        //RuntimeEngine engine = runtimeManager.getRuntimeEngine(EmptyContext.get());
              KieSession ksession = engine.getKieSession();
              ProcessInstance processInstance = ksession.startProcess("com.sample.process");
              System.out.println("Process started");
              ProcessInstanceLog log = logService.findProcessInstance(processInstance.getId());
              //assertNotNull(log);
              processInstance = ksession.getProcessInstance(processInstance.getId());
              //assertNull(processInstance);
              System.out.println("Process instance completed");
      
      
              runtimeManager.disposeRuntimeEngine(engine);
      
      
        }
      

       

      application-context.xml

       

      <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
        xmlns:util="http://www.springframework.org/schema/util" xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
      
      
        <!-- JBPM -->
      
        <bean id="jbpmEMF"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="postgresDataSource" />
        <property name="packagesToScan">
        <array>
        <value>it.arpav.eip2.model</value>
        <value>org.drools.persistence.info</value>
        <value>org.jbpm.persistence.processinstance</value>
        <value>org.jbpm.process.audit</value>
        <value>org.jbpm.persistence.correlation</value>
        <value>org.jbpm.runtime.manager.impl.jpa</value>
        <value>org.jbpm.services.task.impl.model</value>
        <value>org.jbpm.services.task.audit.impl.model</value>
        </array>
        </property>
      
      
        <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>
      
      
        <property name="jpaProperties">
        <props>
        <prop key="hibernate.dialect">${hibernate.postgresql.dialect}</prop>
        <prop key="hibernate.show_sql">true</prop>
        <prop key="hibernate.connection.pool_size">${hibernate.connection.pool_size}</prop>
        <prop key="hibernate.order_inserts">true</prop>
        <prop key="hibernate.order_updates">true</prop>
        <prop key="hibernate.connection.autocommit">true</prop>
        <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
        <!-- Enable the second-level cache -->
        <prop key="hibernate.cache.use_second_level_cache">false</prop>
        <prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.BTMTransactionManagerLookup 
        </prop>
        </props>
        </property>
      
        <property name="persistenceUnitName" value="org.drools.persistence.jpa.local" />
        <property name="mappingResources">
        <array>
        <value>META-INF/orm.xml</value>
        </array>
        </property>
        </bean>
      
      
        <bean id="process" factory-method="newClassPathResource"
        class="org.kie.internal.io.ResourceFactory">
        <constructor-arg>
        <value>test.bpmn</value>
        </constructor-arg>
        </bean>
      
      
        <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="jbpmEMF" />
        <property name="dataSource" ref="postgresDataSource" />
        </bean>
      
        <tx:annotation-driven transaction-manager="txManager" />
      
      
        <bean id="runtimeEnvironment"
        class="org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean">
        <property name="type" value="DEFAULT" />
      
      
        <property name="entityManagerFactory" ref="jbpmEMF" />
        <property name="transactionManager" ref="txManager" />
        <property name="assets">
        <map>
        <entry key-ref="process">
        <util:constant static-field="org.kie.api.io.ResourceType.BPMN2" />
        </entry>
        </map>
        </property>
        <!-- <property name="taskService" ref="taskService" /> -->
        </bean>
      
      
        <bean id="runtimeManager" class="org.kie.spring.factorybeans.RuntimeManagerFactoryBean"
        destroy-method="close">
        <property name="identifier" value="spring-rm" />
        <property name="runtimeEnvironment" ref="runtimeEnvironment" />
        </bean>
      
      
      
        <bean id="logService" class="org.jbpm.process.audit.JPAAuditLogService">
        <constructor-arg>
        <ref bean="jbpmEMF" />
        </constructor-arg>
        <constructor-arg value="STANDALONE_JTA_SPRING_SHARED_EM" />
        </bean>
      
      
      </beans>
      

       

      application-context-datasource.xml

       

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
      
      
        <bean id="postgresDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:app/eip2/postgresqlDS" />
        </bean>
      
      </beans>
      

       

      I have configured JNDI datastore Resource in my tomee.xml configuration file, and i'm sure it's working because, as already said, tables are created correctly.

       

       

      Anyone could give me a hint?

      Thank you

      Carlo

        • 1. Re: JBPM 6 + Spring + Tomee + PostgreSQL
          carlone

          I've reached some improvement

          As documentation says, JPBM support only JTA transations. The only way to get local transactions is by using Spring (that is my case).

          I tried to configure a Test environment, leaving out for now TomEE, setting a datasource not via JNDI.

          I changed my application-context.xml in this way


          <!-- JBPM -->
          
            <bean id="jbpmEMF"
            class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="dataSource" ref="postgresDataSource" />
            <property name="packagesToScan">
            <array>
            <value>it.arpav.eip2.model</value>
            <value>org.drools.persistence.info</value>
            <value>org.jbpm.persistence.processinstance</value>
            <value>org.jbpm.process.audit</value>
            <value>org.jbpm.persistence.correlation</value>
            <value>org.jbpm.runtime.manager.impl.jpa</value>
            <value>org.jbpm.services.task.impl.model</value>
            <value>org.jbpm.services.task.audit.impl.model</value>
            <value>org.jbpm.executor.entities</value>
            <value>org.jbpm.services.task.audit.impl.model</value>
            <value>org.jbpm.persistence.correlation</value>
            <value>org.jbpm.runtime.manager.impl.jpa</value>
            <value>org.jbpm.kie.services.impl.store</value>
          
          
            </array>
            </property>
          
          
            <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
            </property>
          
          
            <property name="jpaProperties">
            <props>
            <prop key="hibernate.dialect">${hibernate.postgresql.dialect}</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.connection.pool_size">${hibernate.connection.pool_size}</prop>
            <prop key="hibernate.order_inserts">true</prop>
            <prop key="hibernate.order_updates">true</prop>
            <prop key="hibernate.connection.autocommit">true</prop>
            <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
            <!-- Enable the second-level cache -->
            <prop key="hibernate.cache.use_second_level_cache">false</prop>
            </props>
            </property>
            <property name="mappingResources">
            <array>
            <value>META-INF/orm.xml</value>
            </array>
            </property>
            </bean>
          
          
            <bean id="btmConfig" factory-method="getConfiguration"
            class="bitronix.tm.TransactionManagerServices">
            </bean>
          
          
            <bean id="BitronixTransactionManager" factory-method="getTransactionManager"
            class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig"
            destroy-method="shutdown" />
          
          
            <bean id="jbpmTxManager"
            class="org.springframework.transaction.jta.JtaTransactionManager">
            <property name="transactionManager" ref="BitronixTransactionManager" />
            <property name="userTransaction" ref="BitronixTransactionManager" />
            </bean>
          
          
            <bean id="process" factory-method="newClassPathResource"
            class="org.kie.internal.io.ResourceFactory">
            <constructor-arg>
            <value>test.bpmn</value>
            </constructor-arg>
            </bean>
          
          
            <bean id="runtimeEnvironment"
            class="org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean">
            <property name="type" value="DEFAULT" />
            <property name="entityManagerFactory" ref="jbpmEMF" />
            <property name="transactionManager" ref="jbpmTxManager" />
            <property name="assets">
            <map>
            <entry key-ref="process">
            <util:constant static-field="org.kie.api.io.ResourceType.BPMN2" />
            </entry>
            </map>
            </property>
            </bean>
          
          
            <bean id="runtimeManager" class="org.kie.spring.factorybeans.RuntimeManagerFactoryBean"
            destroy-method="close">
            <property name="identifier" value="spring-rm" />
            <property name="runtimeEnvironment" ref="runtimeEnvironment" />
            </bean>
          
          
            <!-- LOG dell'esecuzione dei processi -->
          
          
            <bean id="logService" class="org.jbpm.process.audit.JPAAuditLogService">
            <constructor-arg>
            <ref bean="jbpmEMF" />
            </constructor-arg>
            <constructor-arg>
            <value>STANDALONE_LOCAL_SPRING_SHARED_EM</value>
            </constructor-arg>
            </bean>
          

           

          And this is my Test Case

           

          public class ConfigTest extends AbstractApplicationContextTest {
          
          
            @Autowired
            RuntimeManager runtimeManager;
          
            @Autowired
            AuditLogService logService;
          
          
            @Test
            @Rollback(true)
            public void testJbpmConfiguration() {
          
          
          
          
            RuntimeEngine engine = runtimeManager
            .getRuntimeEngine(ProcessInstanceIdContext.get());
          
            // RuntimeEngine engine =
            // runtimeManager.getRuntimeEngine(EmptyContext.get());
            KieSession ksession = engine.getKieSession();
            ProcessInstance processInstance = ksession
            .startProcess("com.sample.process");
            System.out.println("Process started");
            ProcessInstanceLog log = logService.findProcessInstance(processInstance
            .getId());
            // assertNotNull(log);
            processInstance = ksession.getProcessInstance(processInstance.getId());
            assertNull(processInstance);
            System.out.println("Process instance completed");
          
          
            runtimeManager.disposeRuntimeEngine(engine);
            }
          
          
          }
          

           

          As you can see, i setted Bitronix Transaction Manager for the test case, and the value STANDALONE_LOCAL_SPRING_SHARED_EM as constructor argument for the Audit Log Service.

          Everything is working now.

           

          Another problem will be make this stuff working with TomEE.

          But i'm confident

           

          Bye