1 2 3 Previous Next 38 Replies Latest reply on Aug 3, 2011 2:44 PM by daniele.ulrich Go to original post
      • 15. In memory TaskClient without Mina or JMS
        mariemm

        Hi,

         

        I finally found solution. See http://community.jboss.org/message/604133#604133

        • 16. Re: In memory TaskClient without Mina or JMS
          suadalshamsi

          Hi Mauricio,

           

          Any update on Module 6? When are expecting to complele?

          • 17. Re: In memory TaskClient without Mina or JMS
            daniele.ulrich

            I implemented a InJVMConnector (see attachment) - although it is possible to work directly with the locally instantiated TaskService, see at the end.

            This has, however, some drawbacks: all events from the task service can only be recevied by a client that registers locally (in jvm) to the task service. And I'm working on a good solution for a proper JTA integration (injected EntityManager)  to support an integration within an appserver.

             

            Get user task locally:

             

            public

            List<TaskSummary> getOpenTasks() {

            TaskServiceSession session =

            null

            ;

             

            try

            {

            session =

            knowledgeBaseBean

            .getTaskServiceSession();

             

            return session.getTasksAssignedAsPotentialOwner("mary", "en-UK"

            );

            }

            finally

            {

             

            if (session != null

            ) {

            session.dispose();

            }

            }

             

            }

             

            • 18. Re: In memory TaskClient without Mina or JMS
              frankee787

              Hi Gergely Dombi,

                 Have you been able to successfully talk to the server in a transactional scope. Assume you communicated with the TaskServer and claimed a task. However, when you updated your application with the claim status, if an exception occurs...how would you rollback jBPM?

               

              PS: I have been asking this same question all over the forum but in vain!!

               

              Regards,

              Franklin

              • 19. Re: In memory TaskClient without Mina or JMS
                frankee787

                Hi Maruricio,

                     Thanks for the insight.

                 

                I can now  use

                 

                taskSession.addTask(task, contentData)  

                instead of 

                client.addTask(task, content, responseHandler)

                 

                However what do I do instead of

                 

                client.complete(taskId, userId, outputData, responseHandler)

                client.claim(taskId, userId, responseHandler)

                 

                Regards,

                Franklin

                • 20. Re: In memory TaskClient without Mina or JMS
                  mariemm

                  There is taskSession.taskOperation(). Eg.

                  taskSession.taskOperation(Operation.Claim, taskToComplete.getId(), user.getId(), null, null, null);
                  • 21. Re: In memory TaskClient without Mina or JMS
                    frankee787

                    Hi Marie,

                       Excellent.  Thanks for the info.

                     

                      Now I need to try and put the taskSession into my transacitional scope. 

                     

                    Any hints on that ?

                     

                    Regards,

                    Franklin

                    • 22. Re: In memory TaskClient without Mina or JMS
                      daniele.ulrich

                      Hi Franklin

                       

                      To my mind is not possible to have the Tasks in a transactional scope. Neither if you are using the Mina Server nor if your using the TaskSession directly. The libraries are written for J2SE with local (manual) transactions, we could integrate it successfully in an app server by the use of <no-tx-datasources>. And: they are not transactional... please refer to the findings of a collegue of mine. If you are using the Mina Server you will be responsible to do a rollback manually

                       

                      If you find a solution to that problem, I would be grateful if you could post it here...

                       

                      Regards

                       

                      Daniele

                      • 23. Re: In memory TaskClient without Mina or JMS
                        salaboy21

                        Hi Everyone, I'm now working on this matter, I'm trying to provide a better access to the services and I will be tackling all these issues and improving the docs about them. About the transaction stuff I would like to understand a little bit more your use cases and which are the main problems that you are finding so I can address that inmediately. Cheers

                        • 24. Re: In memory TaskClient without Mina or JMS
                          frankee787

                          Hi Mauricio,

                             I have tried to put together as much information as possible , but its really hard to express all the possible use cases. Anyways, following are what I am facing right now.

                           

                          I think one of the major pains everyone is suffering is the Transaction Management aspect.

                           

                          As mentioned, the HumanTask Service is completely emebedabble and is one of the STRONGEST points of jBPM. However that is also one of the biggest problems now. Let me explain

                           

                           

                          USE CASE 1

                           

                          My application uses the the following to create a client and interact with a task. No process is associated with this.

                           

                           

                          client  = new TaskClient(new MinaTaskClientConnector("client", new MinaTaskClientHandler(SystemEventListenerFactory.getSystemEventListener())));

                           

                           

                          In a situation like the following

                           

                          1)I insert/update into my database(Flight ticket Task / User Approval Task / Backoffice Data Auditing etc: business specific data)

                          2)I call client.addTask(task, null, addTaskResponseHandler) (to create a task in jBPM)

                          3)I update my database saying the task has been created sucessfully in jBPM

                            

                           

                          NOTE: Reason for step 1 is as follows : Putting all business related data inside the TaskData doesnt seem to be good idea(Getting serialized and persisted, looses the ability to search). Also there is no task history being mainted in the jBPM

                           

                            

                          QUESTIONS:

                          How can I ensure steps 1 - 3 are in one transaction?

                           

                           

                          This should be achieveable outside an appserver since HumanTask Service is completely emebedabble. 

                           

                           

                          USE CASE 2

                           

                           

                          My application uses a Kession to start of a process(which comprises of mutiple human tasks)

                           

                          In a situation like the following

                           

                          1)I insert/update into my database saying process has been started(Flight ticket booking Process/ User Enrollment Process etc: business specific processes)

                          2)I call ksession.startProcess("com.sample.evaluation", params) (to start the process in jBPM)

                          3)I update my database saying the process has been started sucessfully in jBPM

                            

                           

                          QUESTIONS:

                           

                          How can I ensure steps 1 - 3 are in one transaction?

                          How can my business application be notified when a Task is being created as part of a process execution?

                           

                           

                          This should also be achieveable outside an appserver since HumanTask Service is completely emebedabble.

                           

                             

                           

                          USE CASE 3

                           

                          Putting all business related data inside the TaskData doesnt seem to be good idea(Getting serialized and persisted, looses the ability to search). It would be better just to keep a reference of your business data inside TaskData and look it up when interacting with a Task.

                           

                           

                          QUESTIONS:

                          Which brings us to the last question. How can my business application be notified when a Task is being created as part of a process so that this reference can be made in my application.

                            

                           

                          I hope my USER CASESes are clear now ?

                           

                           

                          Thanks a lot Mauricio for hearing out for the community.

                          Regards,

                          Franklin

                          • 25. Re: In memory TaskClient without Mina or JMS
                            daniele.ulrich

                            Hi Mauricio

                             

                            I don't even try to break it down to single use cases, I'd rather raise some questions:

                             

                            a) if we are using an appserver, why should we rely on a socked based mini server that does not implement only minimal security?

                            b) wouldn't it be nice, if the libraries could be integrated in JTA? Even if the hornetq integration would be used, you cannot guarantee transactions.

                            c) have a look at the user and roles implementation; is this good enough?

                            d) how could real life situations (timer exceeded for a user task, send a reminder or similar things) be implemented with JBoss as the base?

                            c) what about task categories? meta data? queries for these criterias?

                             

                            I think there is really a lot of work left to before I can really recommend to use the human task service in a productive environment.

                             

                            All the best and thanks a lot for your work.

                             

                            Cheers

                             

                            Daniele

                            • 26. Re: In memory TaskClient without Mina or JMS
                              frankee787

                              At least one thing is for sure. The major pain point is TRANSACTION Management and defintely having a MinaConnector or HornetQConnector is not helping much.

                               

                              Regards,

                              Franklin

                              • 27. Re: In memory TaskClient without Mina or JMS
                                daniele.ulrich

                                Hi Franklin

                                 

                                I had already started to do some changes to the classes that are managing persistence. If you like, you can try if it works this way...

                                 

                                You can start the same way as the original version:

                                 

                                TaskService taskService = new TaskService(emf,

                                     SystemEventListenerFactory.getSystemEventListener());

                                   TaskServiceSession taskSession = taskService.createSession();

                                 

                                If you are in a container managed transaction environment, the persistence should work now within the JTA scope without further effort.

                                In a non managed environment you will have to use UserTransactions and XA Datasources to ensure transactions over multiple databases.There are a lot of implementations available, maybe you try this one http://docs.codehaus.org/display/BTM/Hibernate13. You will have to manually start transactions

                                 

                                TransactionManagerServices.getConfiguration().setResourceConfigurationFilename("./datasources.properties");

                                userTransaction = TransactionManagerServices.getTransactionManager();

                                userTransaction.setTransactionTimeout(60);

                                  userTransaction.begin();

                                  

                                   try {

                                   System.out.println("*** DB1 ***");

                                  persistUser(sf1, "user");

                                  listUsers(sf1);

                                  

                                   System.out.println("*** DB2 ***");

                                  persistUser(sf2, "user");

                                  listUsers(sf2);

                                  

                                  userTransaction.commit();

                                  }

                                   catch (Exception ex) {

                                  ex.printStackTrace();

                                  userTransaction.rollback();

                                  }

                                 

                                this way you can keep multiple databases transactional.... Drawback: it definitely will have impact to all the other code you have already implemented that is not using JTA. Try it first without changing your own code, but I'm quite sure, you'll have to use the userTransactions in every situation where you want to guarantee transactions over more than one database.

                                 

                                I did not have the time to test the patch properly, so please take care!

                                 

                                The implementation uses threadLocalStorage and heavily depends on calling the session.dispose() method to perform clean up of the resources of a thread. Make sure it will be called even if an exception occurs ( catch/finally block ).

                                 

                                Cheers

                                 

                                Daniele

                                 

                                PS: after shutting down my computer I had another idea: you can save some effort changing your existing code by driving the transactions manually... just call taskServiceSession.getEntityManager().getTransaction().begin(); and do a commit or rollback in the same way. I don't like this approach because conceptionally you won't have proper transaction demarcation this way, but maybe it helps to save some time to try it out without the need to use JTA and XA datasources. The method

                                taskService.executeEscalatedDeadline

                                 

                                cannot be treated that way, but as it is a read only operation it should work anyway.

                                 

                                by the way: getEntityManager() is a public method in the original implementation, but as in the original implementation a commit is performed inside you will not have the necessary control over the transaction. I did not realize this before otherwise I would have set this method to private

                                • 28. Re: In memory TaskClient without Mina or JMS
                                  frankee787

                                  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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                                              http://www.springframework.org/schema/contexthttp://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/persistencehttp://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_1_0.xsd"
                                  xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
                                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                  xmlns="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.

                                   

                                   

                                  Final note to "Daniele Ulrich " : Could you please tell us what changes you have made in the class so that I can maintain the same in my project.

                                  • 29. Re: In memory TaskClient without Mina or JMS
                                    daniele.ulrich

                                    Hi Franklin

                                     

                                    Thanks for posting your (very detailled) findings back to the community. As you were able to use the human task service within JTA transaction boundaries maybe we will try the same within a JEE application (and not with Spring).

                                     

                                    1. persistence unit: we had to change the file name for the orm.xml file to something like orm-human-task-service.xml; orm.xml is the default file name and it seems that it will be taken from ANY persistence unit that has access to it. So it could save you some headache if you are using
                                      <mapping-file>META-INF/orm-human-task-service.xml</mapping-file>
                                    2. you can get the source for jbpm here https://github.com/droolsjbpm/jbpm.git (JBoss Tools provides a GIT Client for eclipse, or you can use TortoiseGIT). I started with my patch from Tag 5.0.0, now already 5.1.0-Final is available. I already attached the sources of my patch in my last post. You just have to concentrate at org.jbpm.task.service.TaskService and org.jbpm.task.service.TaskServiceSession where I had to change the handling of the EntityManager (transaction begin, commit, rollback, entityManager.close).
                                    3. As in org.jbpm.task.service.TaskServiceSession a rather strange transaction handling was implemented and I had not enough time to inspect all call stacks in detail, I decided to use some kind of a hack to create the EnttityManager with the help of threadLocalStorage. If you can guarantee that your taskServiceSession is always created and disposed within the same thread and exclusively used by this one and only thread you could make the implementation somewhat simpler by using a simple instance variable for the entityManager. As far as I know the taskServiceSession is not thread safe anyway. My hack ensures that every thread will have an entityManager of its own and that it is only one time created even if a call causes multiple actions on the entityManager - but you have to make sure that threadLocalStorage is freed after closing the session.

                                     

                                    Please keep us up to date; I will try to get in contact with the responsible developers for this sub project if we really decide to use this library in our project. Currently we are discussing to write it completely from scratch because it has not so many features implemented or is this mature that we could not do the same in a couple of days. I think the whole architecture should be reconsidered, with a pure business core and several providers for the different contexts this service could be running in.

                                     

                                    Regards

                                     

                                    Daniele