Dashboard > Jetty > ... > Jetty Documentation > JOTM
JOTM Log In | Sign Up   View a printable version of the current page.

Added by Jan Bartel , last edited by Dexter Ang on Mar 11, 2008  (view change) show comment
Labels: 
(None)

Contact the core Jetty developers at www.webtide.com
private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ... scalability guidance for your apps and Ajax/Comet projects ... development services from 1 day to full product delivery

How To Use JOTM as the XA Transaction Manager in Jetty6

These instructions have been tested with JOTM 2.0.10.

Step 1: Copy the jars

Assuming you have successfully downloaded JOTM, copy the following jars to jetty6's lib/ext directory:

  • connector-1_5.jar
  • howl.jar
  • jotm.jar
  • jotm_jrmp_stubs.jar
  • jta-spec1_0_1.jar
  • jts1_0.jar
  • ow_carol.jar
  • xapool.jar
    Logging

    Depending on how you want your logging configured, you may need to also copy jcl104-over-slf4j.jar and an slf4j log implementation such as slf4j-simple.jar into the lib/ directory. You should find both of these files in lib/jsp-2.0. You would need to do this if you are using jdk-1.5 and you want to use slf4j logging. Alternatively, if you are using jdk1.4 and/or you want to use commons-logging, you will need to copy the commons-logging jar and a commons logging impl into the lib/ directory.

    Step 2: Configure CAROL

In your jetty6 installation, create the file resources/carol.properties and edit it's contents to contain these lines:

carol.start.ns=false
carol.start.jndi=false
carol.protocols=jrmp
carol.start.rmi=false
carol.jvm.rmi.local.call=true
carol.jndi.java.naming.factory.url.pkgs=org.mortbay.naming

Without this step, CAROL will assume control of JNDI from jetty6 and java:comp/env will not be set up correctly.

Step 3: Configure the transaction manager and datasources in jetty6

You need to register an XA transaction manager and XA aware DataSources. There is more information about jetty6's JNDI facilities that you may find useful. Here are the snippets for your jetty config file. In this example, we will configure a Derby JDBC driver, but of course you can substitute your own.

<!-------------------------------------------------------------------------------------- -->
<!-- Configure a Jotm instance which provides a javax.transaction.TransactionManager     -->
<!-- and a javax.transaction.UserTransaction implementation.                             -->
<!-------------------------------------------------------------------------------------- -->
<New id="jotm" class="org.objectweb.jotm.Jotm">
  <Arg type="boolean">True</Arg>
  <Arg type="boolean">False</Arg>
  <Call id="tm" name="getTransactionManager"/>
  <Call id="ut" name="getUserTransaction"/>
</New>


<!-------------------------------------------------------------------------------------- -->
<!-- Set up the UserTransaction impl from JOTM as the transaction manager for jetty6     -->
<!-------------------------------------------------------------------------------------- -->
<New id="tx" class="org.mortbay.jetty.plus.naming.Transaction">
  <Arg>
    <Ref id="ut"/>
  </Arg>
</New>



<!-------------------------------------------------------------------------------------- -->
<!-- Set up a DataSource that is XA aware. JOTM uses XAPool for this.                    -->
<!-------------------------------------------------------------------------------------- -->
<New id="myds" class="org.mortbay.jetty.plus.naming.Resource">
  <Arg>jdbc/mydatasource</Arg>
  <Arg>
   <New class="org.enhydra.jdbc.pool.StandardXAPoolDataSource">
     <Arg>
       <New class="org.enhydra.jdbc.standard.StandardXADataSource">
         <Set name="DriverName">org.apache.derby.jdbc.EmbeddedDriver</Set>
         <Set name="Url">jdbc:derby:myderbyDB1;create=true</Set>
         <Set name="User"></Set>
         <Set name="Password"></Set>
         <Set name="transactionManager"><Ref id="tm"/></Set>
       </New>
      </Arg>
    </New>
  </Arg>
</New>
Using XAPool
You MUST wrap the StandardXADataSource in a StandardXAPoolDataSource because StandardXADataSource does not use the XAConnection if you call getConnection(), thus connections won't be involved in the XA transaction.

The description on this page should work, but it seems because of an issue with xapool it doesn't.  Basically the StandardXAPoolDataSource will always try and lookup the StandardXADataSource from JNDI.  Because the StandardXADataSource is not bound in JNDI and we haven't set the name for the pool datasource to look for, it fails and gives a gnarly, non-descriptive NPE:

java.lang.NullPointerException
        at javax.naming.InitialContext.getURLScheme(InitialContext.java:224)
        at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:273)
        at javax.naming.InitialContext.lookup(InitialContext.java:347)

So, based on this hack, I came up with the following configuration which seemed to solve the problem.

<New id="jotm" class="org.objectweb.jotm.Jotm">
    <Arg type="boolean">True</Arg>
    <Arg type="boolean">False</Arg>
    <Call id="ut" name="getUserTransaction"/>
    <Call id="tm" name="getTransactionManager"/>
  </New>
<!-- bind the transaction manager so the StandardXADataSource can find it -->
<!-- Note: we also need to set the name of the transaction manager on the data source itself so it knows what to look for -->
<!-- Alternatively, Stephen Winall says you can bind the UserTransaction, "ut", to javax.naming.TransactionManager which the StandardXAPoolDataSource seems to always look for -->
  <New class="org.mortbay.jetty.plus.naming.Resource">
    <Arg>TransactionManager</Arg>
    <Arg><Ref id="tm" /></Arg>
  </New>
  <New id="tx" class="org.mortbay.jetty.plus.naming.Transaction">
   <Arg>
     <Ref id="ut"/>
   </Arg>
  </New>
<!-- here is where we bind the StandardXADataSource with the name jdbc/ds, we'll also need to tell the StandardXAPoolDataSource this name to lookup -->
<!-- Note: don't bother putting user and password attributes here, the StandardXAPoolDataSource calls the datasource with create(user,password), so the user/password on xads is the only one that will be used -->
  <New class="org.mortbay.jetty.plus.naming.Resource">
    <Arg>jdbc/ds</Arg>
    <Arg>
      <New id="ds" class="org.enhydra.jdbc.standard.StandardXADataSource">
        <Set name="driverName">com.mysql.jdbc.Driver</Set>
        <Set name="url">jdbc:mysql://localhost/jira?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=UTF8</Set>
        <Set name="transactionManager"><Ref id="tm"/></Set>
        <!-- set the transactionManagerName or the StandardXAPoolDataSource won't be able to create Transactions and will -->
        <!-- log errors saying "StandardXAPoolDataSource:connectionClosed should not be used outside an EJBServer" -->
        <Set name="transactionManagerName">TransactionManager</Set>
      </New>
    </Arg>
  </New>
  <!-- We set both the dataSourceName and the dataSource to overcome the issue in xapool/jotm that has been causing the NPE -->
  <New id="xads" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource">
    <Set name="dataSourceName">jdbc/ds</Set>
    <Set name="dataSource"><Ref id="ds" /></Set>
    <Set name="user">jira</Set>
    <Set name="password">jira</Set>
    <Set name="transactionManager"><Ref id="tm"/></Set>
  </New>
  <New id="jirads" class="org.mortbay.jetty.plus.naming.Resource">
    <Arg>jdbc/JiraDS</Arg>
    <Arg><Ref id="xads" /></Arg>
  </New>

That's it. Hopefully this comes in handy for others!

Rich

Note that the comment from Richard Wallace on Aug 11, 2007 11:20 seems to apply if you are using the version of xapool after v1.5.0 (like v1.6 beta) because org.enhydra.jdbc.standard.StandardXADataSource does not have the "transactionManagerName" setter method in v1.5.0 or older. And for JOTM 2.0.10, the xapool version that comes with it appears to be v1.5.0 or older.

If you are not going to use a version of xapool after v1.5.0 (like v1.6 beta), then you can skip setting "transactionManagerName" on org.enhydra.jdbc.standard.StandardXADataSource and replace the JNDI name "TransactionManager" with "javax.transaction.TransactionManager" since Richard Wallace's config comment:

Alternatively, Stephen Winall says you can bind the UserTransaction, "ut", to javax.naming.TransactionManager which the StandardXAPoolDataSource seems to always look for

should have been written as:

Alternatively, Stephen Winall says you can bind the TransactionManager, "tm", to javax.transaction.TransactionManager which the StandardXAPoolDataSource seems to always look for

Contact the core Jetty developers at www.webtide.com
private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ... scalability guidance for your apps and Ajax/Comet projects ... development services from 1 day to full product delivery
Site running on a free Atlassian Confluence Open Source Project License granted to The Codehaus. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.6.2 Build:#919 Nov 26, 2007) - Bug/feature request - Contact Administrators