Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Thursday, January 12, 2006

Maven and missing Java Transaction API JAR

I'm starting to work on a new demo for Tapestry 4.0 that will be based on Hibernate3, and I want to build on Maven. Of course, the first thing that happened is that I tried to have Maven resolve the dependencies and it tripped over the JAR for the Java Transaction API.

Now, a little background. The JTA is under some Sun license that keeps it from being distributed; so Maven has the POM for it in the central repository, but doesn't store the JAR file itself. So what do you do?

You have to get the JAR file yourself, and convince Maven to load it into your local repository.

Not that Sun makes it easy for you ... oh no. You have to click through a license agreement, then you get the class files, packaged as a ZIP file. This is insane! You'd think they would know what a JAR file is! Why not package the JAR inside the ZIP, maybe with a license and some documentation? Because that would make sense.

I suppose you could just rename the jta-1.0.1B.zip to jta-1.0.1B.jar and go from there. I chose to build a proper JAR first. I started by unpacking into a local directory, then used the jar command as normal:

bash-3.00$ ls -lag
total 0
drwx------+  3 None 0 Jan 12 18:27 ./
drwx------+ 22 None 0 Jan 12 18:27 ../
drwx------+  3 None 0 Jan 12 18:27 javax/
bash-3.00$ jar cf ../jta-1.0.1B.jar *
bash-3.00$ cd ..
bash-3.00$ jar tf jta-1.0.1B.jar
META-INF/
META-INF/MANIFEST.MF
javax/
javax/transaction/
javax/transaction/HeuristicCommitException.class
javax/transaction/HeuristicMixedException.class
javax/transaction/HeuristicRollbackException.class
javax/transaction/InvalidTransactionException.class
javax/transaction/NotSupportedException.class
javax/transaction/RollbackException.class
javax/transaction/Status.class
javax/transaction/Synchronization.class
javax/transaction/SystemException.class
javax/transaction/Transaction.class
javax/transaction/TransactionManager.class
javax/transaction/TransactionRequiredException.class
javax/transaction/TransactionRolledbackException.class
javax/transaction/UserTransaction.class
javax/transaction/xa/
javax/transaction/xa/XAException.class
javax/transaction/xa/XAResource.class
javax/transaction/xa/Xid.class

Next up, convincing Maven to put it into the repository in the correct place:

bash-3.00$ mvn install:install-file -Dfile=jta-1.0.1B.jar -DgroupId=javax.transaction -DartifactId=jta -Dversion=1.0.1B -Dpackaging=jar
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'install'.
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [install:install-file] (aggregator-style)
[INFO] ----------------------------------------------------------------------------
[INFO] [install:install-file]
[INFO] Installing c:\temp\jta-1.0.1B.jar to C:\Documents and Settings\Howard\.m2\repository\javax\transaction\jta\1.0.1B\jta-1.0.1B.jar
[INFO] ----------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ----------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Thu Jan 12 18:29:55 PST 2006
[INFO] Final Memory: 2M/3M
[INFO] ----------------------------------------------------------------------------
bash-3.00$

And, with that, you have the JTA jar, in place, ready to use in your projects.

9 comments:

Matt Raible said...

There's an easier way:

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.1</version>
<exclusions>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>geronimo-spec</groupId>
<artifactId>geronimo-spec-jta</artifactId>
<version>1.0.1B-rc4</version>
</dependency>

Of course, isn't it somewhat strange that you can just download jta.jar from the following link...

http://cvs.sourceforge.net/viewcvs.py/*checkout*/hibernate/Hibernate3/lib/jta.jar

jesse said...

I saw something somewhere where the maven dev's were complaining to a sun engineer about the very same thing. No idea what the ultimate resolution will be, but of course it's super lame that they're causing everyone so much f-ing problems with this one little thing. (It's a licensing issue from what I remember)

We got our jta.jar from hibernate as well :)

Massimo said...

Even if maven2 has been released and works very well for main porpouses, i find by myself it has a lot of raw corner that will have to be rounded.

Anyway I'm eager to see (as always) your result Howard.

Howard said...

Turns out, it is very important to add -DgeneratePom=true to the command line as well!

Malin said...

Was this the first jar you needed to download? I am myself building a Tapestry4-Hibernate3 application and the JTA is the third jar I'm downloading now... it started with dom4j, then the ehcache and now jta...

robottaway said...

The best solution is to download Hibernate 3.1 to get the jta jar. Once you have downloaded this jar upload it to your companies 'external free' jar repository. This way all Maven2 developers will be able to check out your project from source control and get the dependency.

To install:
From the directory in which the jta.jar file exists (in ${hibernate-3.1_install}/lib) type the following to make Maven2 install the jar:

mvn deploy:deploy-file -DgroupId=javax.transaction -DartifactId=jta -Dversion=1.0.1B -DgeneratePom=true -Dpackaging=jar -Dfile=jta.jar -DrepositoryId=external_free -Durl=${location of external free repository on repository server}

The value I use for -Durl is: scp://bsddev/var/www/html/maven2_repositories/external_free.

This is because we use Apache web server to host our dependencies/repositories at work.

NOTE: if you use the jta.jar from the hibernate-3.1 distro you should have version 1.0.1B. Let me know if I am wrong though.

Once jta.jar is in your repository Maven2 will be able to check it out, and better yet everyone else you work with can get it too! Use this strategy to get other 'external free' jars into your repository.

By the way, using mvn install only puts the dependency in your local repository on your machine. This does no good if you check out your code on another machine and try to compile - Maven2 will not be able to find the dependency (jta.jar)! To solve this create a Maven2 repository (or a few) on a server that all developers have access to. Then when you check out a project from source control you can run Maven2 and it will get all the dependencies and compile in style.

Anonymous said...

Maybe the best way to get the jar file is to download the zip file from the sun file, and then execute the command as indicated by maven :
mvn install:install-file -DgroupId=javax.transaction -DartifactId=jta -Dversion=1.0.1B -Dpackaging=jar -Dfile="C:\downloadRepository\jta-1_0_1B-classes.zip"

This command creates automatically the jar file in your local repository.

Travis said...

Hibernate has moved to svn...here's an updated direct link to jta.jar:

http://anonhibernate.labs.jboss.com/trunk/Hibernate3/lib/jta.jar

mustaghattack said...

If you are using a repository proxy like Nexus, you can add the Sun maven repository : http://download.java.net/maven/2/

The file will be downloaded transparently.

Bruno