[jboss-user] [jBPM] - Re: In memory TaskClient without Mina or JMS

Franklin Antony do-not-reply at jboss.com
Sat Jul 23 10:45:40 EDT 2011


Franklin Antony [http://community.jboss.org/people/frankee787] created the discussion

"Re: In memory TaskClient without Mina or JMS"

To view the discussion, visit: http://community.jboss.org/message/617173#617173

--------------------------------------------------------------
First of all, thanks a lot for all the help especially Daniele Ulrich for the patched files. After 10-12 hours night out slogging, following are my findings.

Only the patched files(jbpm-human-task-jpa-5.0.0-patched.jar) work with JTA and the default (jbpm-human-task-5.0.0.jar) doesnt work saying *java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()*
*
*
Hence I would humbly as the authors of jBPM5 to reconsider the option of making the TaskServiceSession support JTA transactions as well.

I have been able to support the following usecase with the *Bitronix JTA implementation.*
*
*
The main serivce class is MainService

import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class MainService implements IMainService {
                
                IBusinessProcessService jbpmService;
IBusinessProcessService ourService;
                
 
                public IBusinessProcessService getJbpmService() {
                                return jbpmService;
                }
 
 
                public void setJbpmService(IBusinessProcessService jbpmService) {
                                this.jbpmService = jbpmService;
                }
 
 
                public IBusinessProcessService getOurService() {
                                return ourService;
                }
 
 
                public void setOurService(IBusinessProcessService ourService) {
                                this.ourService = ourService;
                }
 
 
                public static void main(String[] args) 
                {
                                
                ClassPathXmlApplicationContext cp = new ClassPathXmlApplicationContext(new String[]{"jBPM-layer.xml","dao-layer.xml"});
                IMainService mainService = (IMainService)cp.getBean("mainService");
                mainService.doThis();
                
                
                }
                
                
 
                public void doThis() 
                {
                                
                                getOurService().createTask(null);
                                getJbpmService().createTask(null);
                                getOurService().createTask(null);
                                getJbpmService().createTask(null);
                                if(1==1)
                                {
                                                throw new RuntimeException();
                                }
 
                }
 
}
 






As can be seen the MainService is something like a façade which calls two other service. One creates a record in the application database(getOurService()) and the other (getJbpmService()) creates a task/user inside the jBPM database. I have been trying to transactionalize this for quite sometime but in vain. However now its possible , but again only with the patched files.

This is ourService TXNJBPMServiceImp. Although the class name says JBPM, it has nothing to do with jBPM . Just a copy paste of a class …was so  tired to give even a proper name. So, basically this is our application service which inserts a dummy testUser record in our application database.


import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.apache.log4j.Logger;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class TXNJBPMServiceImp implements IBusinessProcessService{

                private static Logger log = Logger.getLogger(TXNJBPMServiceImp.class); 

                private EntityManagerFactory entityManagerFactory;




                public EntityManagerFactory getEntityManagerFactory() {
                                return entityManagerFactory;
                }


                public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
                                this.entityManagerFactory = entityManagerFactory;
                }




    public static void main(String[] args) 
    {


}

                @Override
                public BPMTaskResponse createTask(Task task) {


                                System.out.println("Creating...Task!!");
                                EntityManager em = getEntityManagerFactory().createEntityManager();
                                TestUser testUser = new TestUser();
                                testUser.setName("TXNJBPMServiceImp");


                                //em.getTransaction().begin();
                                em.persist(testUser);

                                //em.getTransaction().commit();


                                System.out.println("Creating...Task DONE!!");

                                return null;
                }



}


Next comes the actual jBPM service which now just creates a user in the jBPM database. As can be seen, it does nothing great. It just hacks into jBPM and gets a taskSession and creates a user. You can use the same taskSession and create Tasks, claim them, complete them etc.


import java.util.List;

import javax.persistence.EntityManagerFactory;

import org.apache.log4j.Logger;
import org.drools.SystemEventListenerFactory;
import org.jbpm.task.service.TaskService;
import org.jbpm.task.service.TaskServiceSession;


public class FinalTXNJBPMServiceImp implements IBusinessProcessService{

                private static Logger log = Logger.getLogger(FinalTXNJBPMServiceImp.class); 


    public TaskServiceSession getTaskSession()
    {
                                return getTaskService().createSession();
                }


                public TaskService getTaskService() {

                return new TaskService(getEntityManagerFactory(), SystemEventListenerFactory.getSystemEventListener());

                }



                private EntityManagerFactory entityManagerFactory;



                public EntityManagerFactory getEntityManagerFactory() {
                                return entityManagerFactory;
                }


                public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
                                this.entityManagerFactory = entityManagerFactory;
                }




    public static void main(String[] args) 
    {



                }

                @Override
                public BPMTaskResponse createTask(Task task) {



                    TaskService taskService = new TaskService(getEntityManagerFactory(), SystemEventListenerFactory.getSystemEventListener());
                    TaskServiceSession taskSession = taskService.createSession();

                    org.jbpm.task.User aUser = new org.jbpm.task.User();
                    aUser.setId("DELNOW2");

                    taskSession.addUser(aUser);




                                System.out.println("Creating...Task DONE!!");

                                return null;
                }


}

Almost there. Now the spring configuration file.

<?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:context=+"http://www.springframework.org/schema/context"+
      xsi:schemaLocation=+"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd+
+             http://www.springframework.org/schema/context http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/context/spring-context.xsd"+>

 

<context:property-placeholder location=+"classpath:jdbc.properties"+/>

<bean id=+"mainServiceRef"+ class=+"ae.emaratech.em.bpm.jbpm.MainService"+ >
<property name=+"jbpmService"+ ref=+"finalbusinessProcessServiceRef"+></property>
<property name=+"ourService"+ ref=+"businessProcessServiceRef"+></property>
</bean>
 
<bean id=+"mainService"+ class=+"org.springframework.transaction.interceptor.TransactionProxyFactoryBean"+>
<property name=+"transactionManager"+ ref=+"JtaTransactionManager"+ />
<property name=+"transactionAttributes"+>
<props>
<prop key=+"*"+>PROPAGATION_REQUIRED, -Exception</prop>
</props>
</property>
<property name=+"target"+ ref=+"mainServiceRef"+ />
</bean>
 
 
 
 


<context:annotation-config/>

 
 
 


<bean id=+"JtaTransactionManager"+ class=+"org.springframework.transaction.jta.JtaTransactionManager"+ >
<property name=+"transactionManager"+ ref=+"BitronixTransactionManager"+ />
<property name=+"userTransaction"+ ref=+"BitronixTransactionManager"+ />
</bean>

<bean id=+"btmConfig"+ factory-method=+"getConfiguration"+ class=+"bitronix.tm.TransactionManagerServices"+>
<property name=+"serverId"+ value=+"spring-btm"+ />
</bean>
 
<!-- create BTM transaction manager -->
<bean id=+"BitronixTransactionManager"+  factory-method=+"getTransactionManager"+ class=+"bitronix.tm.TransactionManagerServices"+ depends-on=+"btmConfig"+ destroy-method=+"shutdown"+ />









 

<bean id=+"finalbusinessProcessService"+ class=+"org.springframework.transaction.interceptor.TransactionProxyFactoryBean"+>
<property name=+"transactionManager"+ ref=+"JtaTransactionManager"+ />
<property name=+"transactionAttributes"+>
<props>
<prop key=+"*"+>PROPAGATION_REQUIRED, -Exception</prop>
</props>
</property>
<property name=+"target"+ ref=+"finalbusinessProcessServiceRef"+ />
</bean>

<bean id=+"finalbusinessProcessServiceRef"+ class=+"ae.emaratech.em.bpm.jbpm.FinalTXNJBPMServiceImp"+ >
<property name=+"entityManagerFactory"+ ref=+"entityManagerFactory"+/>
</bean>




<bean id=+"businessProcessService"+ class=+"org.springframework.transaction.interceptor.TransactionProxyFactoryBean"+>
<property name=+"transactionManager"+ ref=+"JtaTransactionManager"+ />
<property name=+"transactionAttributes"+>
<props>
<prop key=+"*"+>PROPAGATION_REQUIRED, -Exception</prop>
</props>
</property>
<property name=+"target"+ ref=+"businessProcessServiceRef"+ />
</bean>


<bean id=+"businessProcessServiceRef"+ class=+"ae.emaratech.em.bpm.jbpm.TXNJBPMServiceImp"+ >
<property name=+"entityManagerFactory"+ ref=+"ourEntityManagerFactory"+/>
</bean>




<bean id=+"userInfoImp"+ class=+"ae.emaratech.em.bpm.jbpm.DBUserInfoImp"+>
<property name=+"userDAO"+ ref=+"userDAO"+ />
</bean>




<bean id=+"entityManagerFactory"+  class=+"org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"+ depends-on=+"btmConfig"+>
<property name=+"persistenceUnitName"+ value=+"org.jbpm.task"+></property>
<property name=+"dataSource"+ ref=+"jBPMDataSource"+/>
<property name=+"persistenceXmlLocation"+ value=+"classpath:META-INF/persistence.xml"+ />
<property name=+"jpaVendorAdapter"+>
<bean class=+"org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"+>
<property name=+"database"+ value=+"MYSQL"+ />
<property name=+"showSql"+ value=+"true"+ />
<property name=+"databasePlatform"+ value=+"org.hibernate.dialect.MySQL5InnoDBDialect"+/>
</bean>

</property>
</bean> 


<bean id=+"ourEntityManagerFactory"+  class=+"org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"+ depends-on=+"btmConfig"+>
<property name=+"persistenceUnitName"+ value=+"ourUnit"+></property>
<property name=+"dataSource"+ ref=+"ourDataSource"+/>
<property name=+"persistenceXmlLocation"+ value=+"classpath:META-INF/persistence.xml"+ />
<property name=+"jpaVendorAdapter"+>
<bean class=+"org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"+>
<property name=+"database"+ value=+"MYSQL"+ />
<property name=+"showSql"+ value=+"true"+ />
<property name=+"databasePlatform"+ value=+"org.hibernate.dialect.MySQL5InnoDBDialect"+/>
<property name=+"generateDdl"+ value=+"true"+/>

</bean>

</property>
</bean> 

 
<!--  Bitronix Transaction Manager embedded configuration -->
<bean id=+"jBPMDataSource"+ class=+"bitronix.tm.resource.jdbc.PoolingDataSource"+
              init-method=+"init"+ destroy-method=+"close"+>
<property name=+"uniqueName"+ value=+"java/jbpmdb"+ />
<property name=+"maxPoolSize"+ value=+"5"+ />
<property name=+"minPoolSize"+ value=+"0"+ />
<property name=+"driverProperties"+>
<props>
<prop key=+"user"+>${jdbc.jbpm.username}</prop>
<prop key=+"password"+>${jdbc.jbpm.password}</prop>
<prop key=+"url"+>${jdbc.jbpm.url}</prop>
</props>
</property>
<property name=+"className"+ value=+"com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"+ />
<property name=+"allowLocalTransactions"+ value=+"false"+ />
<property name=+"enableJdbc4ConnectionTest"+ value=+"true"+/>        
</bean>
 

<!--  Bitronix Transaction Manager embedded configuration -->
<bean id=+"ourDataSource"+ class=+"bitronix.tm.resource.jdbc.PoolingDataSource"+  init-method=+"init"+ destroy-method=+"close"+>
<property name=+"uniqueName"+ value=+"java/emdb"+ />
<property name=+"minPoolSize"+ value=+"0"+ />
<property name=+"maxPoolSize"+ value=+"5"+ />
<property name=+"driverProperties"+>
<props>
<prop key=+"user"+>${jdbc.emdb.username}</prop>
<prop key=+"password"+>${jdbc.emdb.password}</prop>
<prop key=+"url"+>${jdbc.emdb.url}</prop>
</props>
</property>
<property name=+"className"+ value=+"com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"+ />
<property name=+"allowLocalTransactions"+ value=+"false"+ />
<property name=+"enableJdbc4ConnectionTest"+ value=+"true"+/>
</bean>

</beans>
 
 
And finally the persistence.xml file.

<?xml version=+"1.0"+ encoding=+"UTF-8"+ standalone=+"yes"+?>
<persistence version=+"1.0"+ 
xsi:schemaLocation=+" http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence  http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd+
 +http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm  http://java.sun.com/xml/ns/persistence/orm_1_0.xsd http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"+ 
xmlns:orm=+" http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm"+ 
xmlns:xsi=+" http://www.w3.org/2001/XMLSchema-instance http://www.w3.org/2001/XMLSchema-instance"+ 
xmlns=+" http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence"+>
 
<persistence-unit name=+"org.jbpm.task"+ transaction-type=+"JTA"+>

<provider>org.hibernate.ejb.HibernatePersistence</provider>

<mapping-file>META-INF/orm.xml</mapping-file>



<class>org.jbpm.task.Attachment</class>
<class>org.jbpm.task.Content</class>
<class>org.jbpm.task.BooleanExpression</class>
<class>org.jbpm.task.Comment</class>
<class>org.jbpm.task.Deadline</class>
<class>org.jbpm.task.Comment</class>
<class>org.jbpm.task.Deadline</class>
<class>org.jbpm.task.Delegation</class>
<class>org.jbpm.task.Escalation</class>
<class>org.jbpm.task.Group</class>
<class>org.jbpm.task.I18NText</class>
<class>org.jbpm.task.Notification</class>
<class>org.jbpm.task.EmailNotification</class>
<class>org.jbpm.task.EmailNotificationHeader</class>
<class>org.jbpm.task.PeopleAssignments</class>
<class>org.jbpm.task.Reassignment</class>
<class>org.jbpm.task.Status</class>
<class>org.jbpm.task.Task</class>
<class>org.jbpm.task.TaskData</class>
<class>org.jbpm.task.SubTasksStrategy</class>
<class>org.jbpm.task.OnParentAbortAllSubTasksEndStrategy</class>
<class>org.jbpm.task.OnAllSubTasksEndParentEndStrategy</class>
 
<class>org.jbpm.task.User</class>
 
<class>org.drools.persistence.info.SessionInfo</class>
<class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
<class>org.jbpm.persistence.processinstance.ProcessInstanceEventInfo</class>
<class>org.drools.persistence.info.WorkItemInfo</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>

 
<properties>

<property name=+"hibernate.connection.autocommit"+ value=+"false"+ />
<property name=+"hibernate.hbm2ddl.auto"+ value=+"validate"+ />
<property name=+"hibernate.max_fetch_depth"+ value=+"3"+/>
<property name=+"hibernate.show_sql"+ value=+""+ />
<property name=+"hibernate.transaction.manager_lookup_class"+ value=+"org.hibernate.transaction.BTMTransactionManagerLookup"+/>            
</properties>
</persistence-unit>


 <persistence-unit name=+"ourUnit"+ transaction-type=+"JTA"+>
<provider>org.hibernate.ejb.HibernatePersistence</provider>



<class>ae.emaratech.em.bpm.jbpm.TestUser</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>

<properties>
<property name=+"hibernate.connection.autocommit"+ value=+"false"+ />
<property name=+"hibernate.hbm2ddl.auto"+ value=+"validate"+ />
<property name=+"hibernate.max_fetch_depth"+ value=+"3"+/>
<property name=+"hibernate.show_sql"+ value=+""+ />
<property name=+"hibernate.transaction.manager_lookup_class"+ value=+"org.hibernate.transaction.BTMTransactionManagerLookup"+/> 
</properties>

</persistence-unit>
</persistence>


Few notes. After changing to the patched jBPM files, the orm.xml throws error while trying to be passed. You will have to change references to “Task” in queries to “org.jbpm.task.Task”. Likewise all other objects such as I18NText, OrganizationalEntity etc.
--------------------------------------------------------------

Reply to this message by going to Community
[http://community.jboss.org/message/617173#617173]

Start a new discussion in jBPM at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2034]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jboss-user/attachments/20110723/50624d93/attachment-0001.html 


More information about the jboss-user mailing list