JTA support in Aperte Workflow - bluesoft-rnd/aperte-workflow-core GitHub Wiki

Aperte Workflow at this moment supports Java Transaction API in following configurations:

JTA feature has been tested with PostgreSQL database (9.1 but 8.4 should work too).

The JTA environment is detected automagically by Aperte Workflow, it is also possible to configure JTA behaviour using system properties (-Dproperty.name=property.value args given on JVM startup):

  • org.aperteworkflow.nojta - if true, do not try to autodetect JTA environment and go with per-thread managed connections (current_session_context_class -> thread)

  • org.aperteworkflow.hibernate.transaction.manager_lookup_class - class name of transaction manager lookup class. If empty, Aperte Workflow will try to guess it from the available classes and system properties. Default values are:

  • org.hibernate.transaction.BTMTransactionManagerLookup - when class bitronix.tm.BitronixTransactionManager is in the classpath of Aperte Workflow

  • org.hibernate.transaction.JBossTransactionManagerLookup - when system property jboss.home.dir is not empty

  • org.aperteworkflow.hibernate.transaction.factory_class - maps to hibernate.transaction.factory_class, the default is org.hibernate.transaction.JTATransactionFactory

When JTA is detected, Aperte Workflow will set up Hibernate with current_session_context_class set to jta. With JTA undetected/disabled, this setting is set to thread.

Tomcat configuration instructions

Just follow instructions from http://docs.codehaus.org/display/BTM/Tomcat2x. The sample configuration has been tested on default Liferay 6.0.6 CE bundle.

Sample configuration for PostgreSQL datasource

In conf/context.xml, you should add XA datasource (above <WatchedResource> tag), and Transaction factory, below the <WatchedResource> tag. So the result would look like this:

<Resource name="jdbc/aperte-workflow-ds" 
          auth="Container" 
          type="javax.sql.DataSource"
          factory="bitronix.tm.resource.ResourceObjectFactory" 
          uniqueName="jdbc/aperte-workflow-ds" />

<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>

<Transaction factory="bitronix.tm.BitronixUserTransactionObjectFactory" />

You also have to configure XA datasource in conf/resources.properties:

resource.ds1.className=org.postgresql.xa.PGXADataSource
resource.ds1.uniqueName=jdbc/aperte-workflow-ds
resource.ds1.minPoolSize=5
resource.ds1.maxPoolSize=25
resource.ds1.driverProperties.user=aperteworkflow
resource.ds1.driverProperties.password=*************
resource.ds1.driverProperties.databaseName=aperteworkflow
resource.ds1.driverProperties.serverName=localhost

Add to _conf btm-config.properties:

bitronix.tm.serverId=tomcat-btm-node0
bitronix.tm.journal.disk.logPart1Filename=${btm.root}/work/btm1.tlog
bitronix.tm.journal.disk.logPart2Filename=${btm.root}/work/btm2.tlog
bitronix.tm.resource.configuration=${btm.root}/conf/resources.properties
bitronix.tm.timer.defaultTransactionTimeout=3600

Add to _conf server.xml:

<Listener className="bitronix.tm.integration.tomcat55.BTMLifecycleListener" />

Also set environment variable (i.e. add line to setEnv.bat/sh):

set CATALINA_OPTS=-Dbtm.root=%CATALINA_HOME% -Dbitronix.tm.configuration=%CATALINA_HOME%\conf\btm-config.properties<Listener className="bitronix.tm.integration.tomcat55.BTMLifecycleListener" />

Add some libs to Tomcat:

btm-2.1.0.jar
jta-1.1.jar
slf4j-api-1.6.0.jar
slf4j-jdk14-1.6.0.jar
btm-tomcat55-lifecycle-2.1.0.jar

#JBoss AS 5.1

JBoss comes with default transaction manager, and therefore things should be much easier. But they are not. Liferay bundle comes with Jboss 5.1 without UserTransaction in JNDI scope, so it must be brought back. To do so, you have to restore following files (their contents have been taken from default jBPM 4.4 JBoss installation):

deploy/transaction-service.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- $Id: transaction-service.xml 85945 2009-03-16 19:45:12Z [email protected] $ -->

<!-- ===================================================================== -->
<!--  JBoss Server Configuration                                           -->
<!-- ===================================================================== -->

<server>

   <!-- ==================================================================== -->
   <!-- Transactions                                                         -->
   <!-- ==================================================================== -->

   <!--
      | UserTransaction support. Will be replaced by the DTM once
      | the DTM is made to play nice with JBossTS.
   -->
   <mbean code="org.jboss.tm.usertx.server.ClientUserTransactionService"
      name="jboss:service=ClientUserTransaction"
      xmbean-dd="resource:xmdesc/ClientUserTransaction-xmbean.xml">
      <depends>
         <mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory"
            name="jboss:service=proxyFactory,target=ClientUserTransactionFactory">
            <attribute name="InvokerName">jboss:service=invoker,type=unified</attribute>
            <attribute name="TargetName">jboss:service=ClientUserTransaction</attribute>
            <attribute name="JndiName">UserTransactionSessionFactory</attribute>
            <attribute name="ExportedInterface">org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory</attribute>
            <attribute name="ClientInterceptors">
               <interceptors>
                  <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
                  <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
               </interceptors>
            </attribute>
            <depends>jboss:service=invoker,type=unified</depends>
         </mbean>
      </depends>
      <depends optional-attribute-name="TxProxyName">
         <mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory"
            name="jboss:service=proxyFactory,target=ClientUserTransaction">
            <attribute name="InvokerName">jboss:service=invoker,type=unified</attribute>
            <attribute name="TargetName">jboss:service=ClientUserTransaction</attribute>
            <attribute name="JndiName"></attribute>
            <attribute name="ExportedInterface">org.jboss.tm.usertx.interfaces.UserTransactionSession</attribute>
            <attribute name="ClientInterceptors">
               <interceptors>
                  <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
                  <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
               </interceptors>
            </attribute>
            <depends>jboss:service=invoker,type=unified</depends>
         </mbean>
      </depends>
   </mbean>

</server>

and deploy/remoting-jboss-beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">


   <!-- ==================================================================== -->
   <!-- Remoting services                                                    -->
   <!-- ==================================================================== -->
   
   <!-- For detailed description of all these configuration attributes, please see the       -->
   <!-- JBoss Remoting User's Guide (http://www.jboss.org/jbossremoting/docs/index.html) or  -->
   <!-- the Remoting wiki (http://www.jboss.org/community/docs/DOC-11782).                   -->
            
   <!-- Unified invoker.  Registers itself as an invocation handler with UnifiedInvokerConnector. -->
   <!-- Can find more details on unified invoker configuration at                                 -->
   <!-- http://docs.jboss.org/jbossas/unified_invoker/UnifiedInvoker_guide.html.                  -->
   <bean name="UnifiedInvoker" class="org.jboss.invocation.unified.server.UnifiedInvoker">
      <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss:service=invoker,type=unified",exposedInterface=org.jboss.invocation.unified.server.UnifiedInvokerMBean.class,registerDirectly=true)</annotation>
      <property name="connector"><inject bean="UnifiedInvokerConnector"/></property>
      <depends>TransactionManager</depends>
   </bean>
   
   
   <!-- The Connector is the core component of the remoting server service.        -->
   <!-- It binds the remoting invoker (transport protocol, callback configuration, -->
   <!-- data marshalling, etc.) with the invocation handlers.                      -->
   <bean name="UnifiedInvokerConnector" class="org.jboss.remoting.transport.Connector">
      <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.remoting:service=Connector,transport=socket",exposedInterface=org.jboss.remoting.transport.ConnectorMBean.class,registerDirectly=true)</annotation>
      <property name="serverConfiguration"><inject bean="UnifiedInvokerConfiguration"/></property>
   </bean>
   
   
   <!-- Remoting server configuration -->
   <bean name="UnifiedInvokerConfiguration" class="org.jboss.remoting.ServerConfiguration">
      <constructor>
         <!-- transport: Others include sslsocket, bisocket, sslbisocket, http, https, rmi, sslrmi, servlet, sslservlet. -->
         <parameter>socket</parameter>
      </constructor>
   
      <!-- Parameters visible to both client and server -->
      <property name="invokerLocatorParameters">
         <map keyClass="java.lang.String" valueClass="java.lang.String">
            <entry>
               <key>serverBindAddress</key>
               <value>
                  <value-factory bean="ServiceBindingManager" method="getStringBinding">
                     <parameter>UnifiedInvokerConnector</parameter>
                     <parameter>${host}</parameter>
                  </value-factory>
               </value>
            </entry>
            <entry>
               <key>serverBindPort</key>
               <value>
                  <value-factory bean="ServiceBindingManager" method="getStringBinding">
                     <parameter>UnifiedInvokerConnector</parameter>
                     <parameter>${port}</parameter>
                  </value-factory>
               </value>
            </entry>
            
            <!-- Multihome configuration with ServiceBindingManager.  The string will   -->
            <!-- have the form "192.168.2.2:7777!10.11.12.238:8888", which results in   -->
            <!-- a Remoting server listening on 192.168.2.2:7777 and 10.11.12.238:8888. -->
            <!-- See the beans "homes1" and "homes2" at the bottom of this file and     -->
            <!-- the conf/bindings.xml file.                                            -->
            <!--entry>
               <key>homes</key>
               <value><value-factory bean="homes2" method="toString"/></value>
            </entry-->

            <entry><key>dataType</key>     <value>invocation</value></entry>
            <entry><key>marshaller</key>   <value>org.jboss.invocation.unified.marshall.InvocationMarshaller</value></entry>
            <entry><key>unmarshaller</key> <value>org.jboss.invocation.unified.marshall.InvocationUnMarshaller</value></entry>
           
            <!-- A socket transport parameter -->
            <entry><key>enableTcpNoDelay</key> <value>true</value></entry>

            
            <!-- Selected optional parameters: -->
         
            <!-- Parameters for connecting from outside of a firewall. -->
            <!--entry><key>clientConnectAddress</key> <value>a.b.c.d</value></entry-->
            <!--entry><key>clientConnectPort</key>    <value>7777</value></entry-->
            
            <!-- Parameter for expressing a set of addresses to which a client can try to connect. -->
            <!-- The server could be, for example, a multihome server behind a firewall.  The      -->
            <!-- "homes4" bean could be defined the same way the "homes2" bean is defined below.   -->
            <!--entry>
               <key>connecthomes</key>
               <value><value-factory bean="homes4" method="toString"/></value>
            </entry-->
            
            <!-- Socket read timeout.  Defaults to 60000 ms (1 minute) -->
            <!-- on the server, 1800000 ms (30 minutes) on the client. -->
            <!--entry><key>timeout</key> <value>120000</value></entry-->
         
            <!-- Maximum number of connections in client invoker's    -->
            <!-- connection pool (socket transport).  Defaults to 50. -->
            <!--entry><key>clientMaxPoolSize</key> <value>20</value></entry-->
         
            <!-- Configures traffic class on underlying sockets (socket transport). -->
            <!-- Default value determined by socket implementation.                 -->
            <!--entry><key>trafficClass</key> <value>2</value></entry-->
         </map>
      </property>
     
      <!-- Parameters visible only to server -->
      <property name="serverParameters">
         <map keyClass="java.lang.String" valueClass="java.lang.String">
       
            <!-- Selected optional parameters: -->
         
            <!-- Maximum number of worker threads on the      -->
            <!-- server (socket transport).  Defaults to 300. -->
            <!--entry><key>maxPoolSize</key> <value>500</value></entry-->
            
            <!-- Number of seconds after which an idle worker thread will be    -->
            <!-- purged (socket transport).  By default purging is not enabled. -->
            <!--entry><key>idleTimeout</key> <value>60</value></entry-->
         </map>
      </property>
                                
      <property name="invocationHandlers">
         <map keyClass="java.lang.String" valueClass="java.lang.String">
            <!-- The JSR88 deployment service StreamingTarget handler -->
            <entry><key>JSR88</key> <value>org.jboss.deployment.remoting.DeployHandler</value></entry>
         </map>
      </property>
   </bean>
   
   <!-- Beans homes1 and homes2 are used to construct a multihome Remoting server. -->
   <!--bean name="homes1" class="java.lang.StringBuffer">
      <constructor>
         <parameter class="java.lang.String">
            <value-factory bean="ServiceBindingManager" method="getStringBinding">
               <parameter>UnifiedInvokerConnector:bindingHome1</parameter>
               <parameter>${host}:${port}</parameter>
            </value-factory>
         </parameter>
      </constructor>
   </bean-->
   
   <!--bean name="homes2" class="java.lang.StringBuffer">
      <constructor factoryMethod="append">
         <factory bean="homes1"/>
         <parameter>
            <value-factory bean="ServiceBindingManager" method="getStringBinding">
               <parameter>UnifiedInvokerConnector:bindingHome2</parameter>
               <parameter>!${host}:${port}</parameter>
            </value-factory>
         </parameter>
      </constructor>
   </bean--> 
 
</deployment>
⚠️ **GitHub.com Fallback** ⚠️