9 Replies Latest reply on Oct 3, 2009 2:50 PM by newcomer1

    Awesome job with jBPM 4.1

    unsavory

      I just wanted to say what a great job you guys did with the jBPM 4.1 release. Not only was it released on time, but the support promised for Tomcat was also delivered. Thank you!

      As of 3:30AM this morning we now have 2 production application servers running jBPM 4.1 in Tomcat with Spring + JPA + Hibernate + JTA + JOTM.

      I struggled for a long time trying to get this configuration to work with jBPM 4 and I never quite got it working right. Most of the issues were related to the Job Executor which now starts like it is supposed to in this environment and actually executes jobs correctly (ie: can find the spring transaction manager). But it all worked as soon as I plugged jBPM 4.1 in.

      There are some JTA transaction issues with JOTM I'm struggling with in regards to rollbacks on exceptions, but I do not believe it is related to jBPM.

      Thanks again for a great product and a great release!

        • 1. Re: Awesome job with jBPM 4.1
          kukeltje

          Thanks, I'll make sure I notify all others.

          btw, why not add the usage to http://www.jboss.org/community/wiki/jBPM3References

          (ignore the 3 in there, I'll change that in the near future)

          • 2. Re: Awesome job with jBPM 4.1
            koen.aers

            hey unsavory,

            do you care to blog about your experience? we can always use some good exposure ;-)

            cheers,
            koen

            • 3. Re: Awesome job with jBPM 4.1
              lperea

              hi, unsavory coud you please post some of your config files, I'm trying to do something like that (except for JPA) but I can´t figured out how.

              thanks

              • 4. Re: Awesome job with jBPM 4.1
                unsavory

                @koen

                I've been meaning to setup a blog for years and have not gotten around to it. But would be happy to blog about it if I ever get the time. =)

                @lperea

                Here are my configuration files:

                applicationContext.xml

                <?xml version="1.0" encoding="UTF-8"?>
                <!--
                 Application context definition for PetClinic on JPA.
                -->
                <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
                 xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee"
                 xmlns:tx="http://www.springframework.org/schema/tx"
                 xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
                 xsi:schemaLocation="
                 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
                 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                 http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd">
                
                 <!-- ========================= RESOURCE DEFINITIONS ========================= -->
                
                 <!--
                 Activates a load-time weaver for the context. Any bean within the context that
                 implements LoadTimeWeaverAware (such as LocalContainerEntityManagerFactoryBean)
                 will receive a reference to the auto-detected load-time weaver.
                 -->
                 <context:load-time-weaver aspectj-weaving="on" />
                 <!-- Use this to specify exactly which load-time weaver should be used, but
                 it should get auto-detected. -->
                 <!-- <context:load-time-weaver aspectj-weaving="on" weaver-class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver" /> -->
                
                 <!-- Configurer that replaces ${...} placeholders with values from a properties file -->
                 <!-- (in this case, JDBC-related settings for the dataSource definition below) -->
                 <context:property-placeholder location="classpath:/META-INF/lf.properties" />
                
                 <!-- Apply dependency injection to non-managed classes annotated with the @Configurable -->
                 <context:spring-configured />
                
                 <!-- Auto scan and load Spring components -->
                 <context:component-scan base-package="com.lf.service" />
                
                 <!-- enables interpretation of the @Required annotation to ensure that dependency injection actually occures -->
                 <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
                
                 <!-- enables interpretation of the @PersistenceUnit/@PersistenceContext annotations providing convenient
                 access to EntityManagerFactory/EntityManager -->
                 <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
                
                 <bean id="partnerDataSource" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
                 <property name="transactionManager" ref="jotm" />
                 <property name="driverName" value="${jdbc.driverClassName}"/>
                 <property name="url" value="${jdbc.partnerUrl}"/>
                 <property name="user" value="${jdbc.partnerUsername}"/>
                 <property name="password" value="${jdbc.partnerPassword}"/>
                 </bean>
                
                 <!-- Required because the stand-alone JOTM transaction manager is not auto-detected by the
                 JtaTransactionManager because it requires a static accessor method. -->
                 <bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean">
                 <property name="defaultTimeout" value="100000"/>
                 </bean>
                
                 <!-- Single XA data-source -->
                 <bean id="xaDataSource" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
                 <property name="transactionManager" ref="jotm" />
                 <property name="driverName" value="${jdbc.driverClassName}"/>
                 <property name="url" value="${jdbc.url}"/>
                 <property name="user" value="${jdbc.username}"/>
                 <property name="password" value="${jdbc.password}"/>
                 </bean>
                 <!-- XA data-source pool -->
                 <!-- <bean id="xaDataSource" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
                 <property name="transactionManager" ref="jotm" />
                 <property name="dataSource" ref="dataSource"/>
                 <property name="user" value="${jdbc.username}"/>
                 <property name="password" value="${jdbc.password}"/>
                 </bean> -->
                
                 <!-- supplying the JotmFactoryBean merely to the userTransaction property because JtaTransactionManager
                 auto-detects that the object returned by the JotmFactoryBean implements both the
                 UserTransaction and the TransactionManager interface -->
                 <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
                 <property name="userTransaction" ref="jotm"/>
                 <!-- <property name="userTransactionName" value="java:comp/UserTransaction" /> -->
                 <property name="transactionManager" ref="jotm"/>
                 <property name="allowCustomIsolationLevels" value="true"/>
                 </bean>
                
                 <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
                 p:database="${jpa.database}" p:showSql="${jpa.showSql}" />
                
                 <!-- JPA EntityManagerFactory -->
                 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
                 p:dataSource-ref="xaDataSource" p:jpaVendorAdapter-ref="jpaVendorAdapter" p:jpaDialect-ref="jpaDialect" >
                
                 <!-- configure Hibernate to participate in JTA transactions using the JOTM transaction manager and
                 specify further Hibernate specific configuration properties -->
                 <property name="jpaPropertyMap">
                 <map>
                 <!-- Database Configuration -->
                 <entry key="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
                 <entry key="hibernate.hbm2ddl.auto" value="${hibernate.hbm2ddl.auto}" />
                 <entry key="hibernate.format_sql" value="false" />
                 <entry key="hibernate.use_sql_comments" value="true" />
                 <entry key="hibernate.default_batch_fetch_size" value="25" />
                 <entry key="hibernate.order_updates" value="true" />
                 <!-- Cache Configuration -->
                 <!-- <entry key="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider" /> -->
                 <!-- <entry key="net.sf.ehcache.configurationResourceName" value="ehcache.xml" /> -->
                 <entry key="hibernate.cache.use_second_level_cache" value="false" />
                 <entry key="hibernate.cache.use_query_cache" value="false" />
                 <!-- Transaction Management -->
                 <entry key="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JOTMTransactionManagerLookup" />
                 <!-- <entry key="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory" /> -->
                 <entry key="hibernate.connection.autocommit" value="false" />
                 <entry key="hibernate.connection.release_mode" value="auto" />
                 <entry key="hibernate.transaction.auto_close_session" value="false" />
                 <entry key="hibernate.transaction.flush_before_completion" value="false" />
                 <entry key="hibernate.current_session_context_class" value="org.hibernate.context.JTASessionContext" />
                 <!-- Hibernate Search -->
                 <!-- <entry key="hibernate.search.default.directory_provider" value="false" />
                 <entry key="hibernate.search.default.indexBase" value="C:/Temp/hibernate_test_indexes" />
                 <entry key="hibernate.search.default.batch.merge_factor" value="10" />
                 <entry key="hibernate.search.default.batch.max_buffered_docs" value="10" />
                 <entry key="hibernate.search.default.optimizer.operation_limit" value="500" />
                 <entry key="hibernate.search.default.optimizer.transaction_limit.max" value="100" /> -->
                 </map>
                 </property>
                 <property name="persistenceUnitName" value="LeapforcePU" />
                 <!-- Custom implementation to enrich the PersistenceUnitInfo read from the persistence.xml
                 JPA configuration file with the JTA datasource. specifying the JTA datasource directly in
                 the Spring configuration file has the advantage that we can use a direct reference to the
                 datasource instead of using a JNDI name as requied by the jta-data-source setting in the
                 persistence.xml file -->
                 <property name="persistenceUnitPostProcessors">
                 <bean class="com.lf.service.jta.JtaPersistenceUnitPostProcessor">
                 <property name="jtaDataSource" ref="xaDataSource" />
                 </bean>
                 </property>
                 <property name="loadTimeWeaver">
                 <bean class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver" />
                 </property>
                 </bean>
                
                 <bean id="sessionFactory" factory-bean="entityManagerFactory" factory-method="getSessionFactory"/>
                
                 <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
                
                 <!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= -->
                
                 <!--
                 Activates various annotations to be detected in bean classes: Spring's
                 @Required and @Autowired, as well as JSR 250's @PostConstruct,
                 @PreDestroy and @Resource (if available) and JPA's @PersistenceContext
                 and @PersistenceUnit (if available).
                 -->
                 <context:annotation-config transaction-manager="transactionManager" />
                
                 <!--
                 Instruct Spring to perform declarative transaction management
                 automatically on annotated classes.
                 -->
                 <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />
                
                 <!--
                 Instruct Spring to retrieve and apply @AspectJ aspects which are defined
                 as beans in this context (such as the CallMonitoringAspect below).
                 -->
                 <aop:aspectj-autoproxy />
                
                 <!--
                 Post-processor to perform exception translation on @Repository classes (from native
                 exceptions such as JPA PersistenceExceptions to Spring's DataAccessException hierarchy).
                 -->
                 <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
                
                
                 <!-- JBPM Spring Configuration File -->
                 <import resource="classpath:com/lf/jbpm/applicationContext-process.xml" />
                </beans>


                applicationContext-process.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"
                 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
                
                 <bean id="jbpmConfiguration" class="org.jbpm.pvm.internal.cfg.SpringConfiguration">
                 <constructor-arg value="com/lf/jbpm/jbpm.cfg.xml" />
                 </bean>
                
                 <!-- <bean class="com.lf.jbpm.JobExecutorServlet" /> -->
                
                 <bean id="processEngine" factory-bean="jbpmConfiguration" factory-method="buildProcessEngine" />
                 <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
                 <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
                 <bean id="executionService" factory-bean="processEngine" factory-method="getExecutionService" />
                 <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
                 <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
                 <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
                
                </beans>


                jbpm.cfg.xml:
                <?xml version="1.0" encoding="UTF-8"?>
                
                <jbpm-configuration>
                
                 <import resource="jbpm.jpdl.cfg.xml" />
                 <import resource="jbpm.identity.cfg.xml" />
                 <!-- Uncomment this to enable job executor -->
                 <import resource="jbpm.jobexecutor.cfg.xml" />
                
                 <process-engine-context>
                 <repository-service />
                 <repository-cache />
                 <execution-service />
                 <history-service />
                 <management-service />
                 <identity-service />
                 <task-service />
                
                 <!-- <job-executor threads="1" idle="15000" idle-max="60000" lock-millis="3600000" /> -->
                
                
                 <!-- Here we needed to change the transaction interceptor -->
                 <command-service>
                 <retry-interceptor />
                 <environment-interceptor />
                 <spring-transaction-interceptor />
                 </command-service>
                
                 <!-- Added spring as read-context -->
                 <script-manager default-expression-language="juel"
                 default-script-language="juel"
                 read-contexts="execution, environment, process-engine, spring"
                 write-context="">
                 <script-language name="juel"
                 factory="org.jbpm.pvm.internal.script.JuelScriptEngineFactory" />
                 </script-manager>
                
                 <id-generator />
                 <types resource="jbpm.variable.types.xml" />
                
                 <address-resolver />
                
                 </process-engine-context>
                
                
                 <transaction-context>
                 <!-- Remove transaction tag to force jBPM to lookup transaction from Spring -->
                 <!-- <transaction type="jta" /> -->
                 <repository-session />
                 <db-session />
                
                 <message-session />
                 <timer-session />
                 <history-session />
                 <mail-session>
                 <mail-server>
                 <session-properties resource="jbpm.mail.properties" />
                 </mail-server>
                 </mail-session>
                
                 <!-- Need to set explicitly that we don't want jbpm to create sessions -->
                 <hibernate-session current="true" />
                 </transaction-context>
                </jbpm-configuration>


                Hope that helps.

                • 5. Re: Awesome job with jBPM 4.1
                  lperea

                  thanks for the fast reply, I've modified my configuration files, but i have a problem
                  When I set up the first SessionFactory (for Jbpm) it works fine, but when I set up the second SessionFactory (for the second datasource) it throw this error:

                  exception while executing command org.jbpm.pvm.internal.jobexecutor.AcquireJobsCmd@1f7e273
                  org.jbpm.pvm.internal.wire.WireException: couldn't find hibernate-session-factory by type to open a hibernate-session
                   at org.jbpm.pvm.internal.wire.descriptor.HibernateSessionDescriptor.construct(HibernateSessionDescriptor.java:66)
                   at org.jbpm.pvm.internal.wire.WireContext.construct(WireContext.java:473)
                   at org.jbpm.pvm.internal.wire.WireContext.create(WireContext.java:452)
                   at org.jbpm.pvm.internal.wire.WireContext.create(WireContext.java:441)
                   at org.jbpm.pvm.internal.wire.WireContext.get(WireContext.java:421)
                   at org.jbpm.pvm.internal.wire.WireContext.get(WireContext.java:331)


                  (I'm not using JPA)
                  any idea?

                  • 6. Re: Awesome job with jBPM 4.1
                    unsavory

                    Sorry, I don't.

                    Our second datasource is not being used for jBPM. We are running jBPM and our application code against the same database. We have a 2nd database for accessing some data we get from our partners.

                    So our usage is slightly different than yours. It sounds like you have jBPM in a different database than your application correct?

                    • 7. Re: Awesome job with jBPM 4.1
                      lperea

                      Correct, we have an existing app running in informix and the JBPM in postgress.

                      But seems that finally is working, I've just modify the jbpm.cfg.xml to add the name of the sessionFactory to use. :)

                      this is the line:

                      <hibernate-session current="true" factory="sessionFactory"/>
                      


                      some tricky, but it works :)

                      • 8. Re: Awesome job with jBPM 4.1
                        unsavory

                        Awesome! Glad you got it working.

                        • 9. Re: Awesome job with jBPM 4.1
                          newcomer1

                           

                          "unsavory" wrote:
                          I just wanted to say what a great job you guys did with the jBPM 4.1 release. Not only was it released on time, but the support promised for Tomcat was also delivered. Thank you!

                          As of 3:30AM this morning we now have 2 production application servers running jBPM 4.1 in Tomcat with Spring + JPA + Hibernate + JTA + JOTM.

                          I struggled for a long time trying to get this configuration to work with jBPM 4 and I never quite got it working right. Most of the issues were related to the Job Executor which now starts like it is supposed to in this environment and actually executes jobs correctly (ie: can find the spring transaction manager). But it all worked as soon as I plugged jBPM 4.1 in.

                          There are some JTA transaction issues with JOTM I'm struggling with in regards to rollbacks on exceptions, but I do not believe it is related to jBPM.

                          Thanks again for a great product and a great release!


                          This sounds great! We are running jbpm 4 and had to roll our own transaction interceptor (and/or JtaTransaction implementation) to get the jobexecutor to play along with spring and jta.