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.

8 comments:

  1. 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

    ReplyDelete
  2. 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.

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

    ReplyDelete
  4. Anonymous4:47 AM

    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...

    ReplyDelete
  5. 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.

    ReplyDelete
  6. Anonymous12:59 AM

    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.

    ReplyDelete
  7. Anonymous11:54 AM

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

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

    ReplyDelete
  8. 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

    ReplyDelete

Please note that this is not a support forum for Tapestry. Requests for help will be deleted. Please subscribe to the Tapestry user mailing list if you are in need of support, or contact me directly for professional (for pay) support.

Spammers: Don't bother. I delete your comments and it's a waste of time for both of us. 垃圾邮件发送者:不要打扰。我删除您的评论和它的时间对我们双方的浪费