Jul 15, 2010

Maven - Sun JAR Issues (javamail, jms, jmx, jdmk, persistence)

Problem

Compiling fails because of dependencies related to Sun, such as javamail, jms, jmx. These failures have some of the symptoms listed below.

Background. Many of Sun's Java projects do not have licenses that allow for redistribution. Basically, their stuff is somewhat "locked down." To get it, you have to click through a Software License Agreement; meaning, their libraries can, at times, be a pain to download. Historically, their JARs have not been in public Maven Repositories. As such, Maven tends not to automatically download Sun dependencies. Nowadays, they are available in the default repository . . . supposedly. However, over here IN REALITY, that doesn't really work.

If you have "Maven: The Definitive Guide," read page 73 under the section "Adding J2EE Dependencies" for related information.

Symptoms

Some symptoms of this problem I saw while trying to solve it include:

  • Failed to resolve artifact
  • Missing:
    ----------
    1) javax.persistence:ejb:jar:3.0-public_review
  • [INFO] Unable to find resource 'javax.persistence:ejb:jar:3.0-public_review' in repository JBoss Repository (https://repository.jboss.org/nexus/content/groups/public/)
  • error: error reading /Users/keving/.m2/repository/com/sun/jdmk/jmxtools/1.2.1/jmxtools-1.2.1.jar; cannot read zip file
  • error: error reading /Users/keving/.m2/repository/javax/mail/mail/1.4.1/mail-1.4.1.jar; cannot read zip file
  • error: error reading /Users/keving/.m2/repository/com/sun/jmx/jmxri/1.2.1/jmxri-1.2.1.jar; cannot read zip file
  • [INFO] Unable to find resource 'javax.jms:jms:jar:1.1' in repository central (http://repo1.maven.org/maven2)
  • [INFO] Unable to find resource 'javax.persistence:ejb:jar:3.0-public_review' in repository maven.springframework.org (http://maven.springframework.org/snapshot)
  • [INFO] Unable to find resource 'javax.persistence:ejb:jar:3.0-public_review' in repository central (http://repo1.maven.org/maven2)
  • Failed to resolve artifact. com.sun.jmx:jmxri:jar:1.2.1
  • Failed to resolve artifact. com.sun.jdmk:jmxtools:jar:1.2.1
  • Solutions

    I recommend solution 4, below. After an hour or two of Googling, reading and learning, my final course of action (Solution 4) was to first delete all the troubled Sun dependencies, then painstakingly download the right JARs directly from Sun/Oracle and install them in the local repository. Below, I have listed all the useful solutions I found and tried during my journey to finding a complete repair.

    Solution 1 - Fastest, Easiest Fix

    Simplest solution: change just one character in the POM fille... use version 1.2.14 instead of 1.2.15. So the log4j dependency section
    changes FROM:

    <dependency>
    <groupid>log4j</groupid>
    <artifactid>log4j</artifactid>
    <version>1.2.15</version>
    </dependency>

    TO:

    <dependency>
    <groupid>log4j</groupid>
    <artifactid>log4j</artifactid>
    <version>1.2.14</version>
    </dependency>

    Solution 2 - Quick Fix

    Next simplest solution: exclude Sun jars by adding the following exclusions to the Log4j dependency within the pom.xml file:

    Solution 3 - Ideal Fix (didn't work for me)

    Best Solution (but doesn't work...or at least I can't get it to work): Use the special repositories provided by Sun: add to POM.xml

    Supposedly, this repository is provided by Sun and contains the missing jars. Each one has a "Reference Implementation" of the underlying API. Somehow, this allows for a looser license so the code can be redistributed without clicking through an SLA. When I tried this, it only successfully installed 1 of the JARs--javamail.

    Solution 4 - Thorough Repair (my choice)

    This is the longer, yet more complete solution--get the actual jars from Sun/Oracle. I kept track of all the little things I did and listed them below, keeping as many things "cut and pasteable" as possible. These are the steps I took and the commands I happened to run along the way:

    Delete the jars from the local repository:

      rm -rf ~/.m2/repository/javax/persistence/ejb/
      rm -rf ~/.m2/repository/javax/jms
      rm -rf ~/.m2/repository/javax/mail
      rm -rf ~/.m2/repository/com/sun/jdmk
      rm -rf ~/.m2/repository/com/sun/jmx

    run maven again (at least to the compile phase) to see exactly which jars fail.

    cd [top-level project directory with pom.xml]
    mvn assembly:directory -Dmaven.test.failure.ignore=true

    then download any remaining, missing JARs directly from SUN. Here are the detailed steps I took, grouped by each type of jar. The exact links may change over time but the basic steps should be the same. Note that the jdmk and jmx jars both come in one download.

    JMS

    1. click here to download the JMS jar from Sun/Oracle, accept the Software License Agreement and download the jar
    2. unpack the zip archive (automatic on my machine to directory ~/Downloads)
    3. cd to the lib directory
    4. cd ~/Downloads/jms1.1/lib/
    5. install the jms jar into the local maven repository, using the following command

    JDMK - JMX Tools and/or JMXRI

    1. click here to download the JDMK jar from Sun/Oracle, accept the Software License Agreement and download the jar
    2. (Found on Sun's Java SE page for the JDMK/JMX project by choosing Download" under the "BINARY DOWNLOAD" section under "JMX 1.2.1 Reference Implementation")
    3. This zip will include jars for both jmxtools and jmxri. Unpack the archive(automatic on my machine to directory ~/Downloads)
    4. cd to the lib directory
    5. cd ~/Downloads/jmx-1_2_1-bin/lib/
    6. install both jars into the local repository, using the following commands

    Persistence

    1. click here to access the javax.persistence jar from sourceforge
    2. unpack the archive (automatic on my machine to directory ~/Downloads)
    3. cd to the lib directory
    4. cd ~/Downloads/hibernate-annotations-3.1beta5/lib/
    5. install the javax persistence jar into the local maven repository, using the following command

    JavaMail

    Java mail is now open source so you shold be able to pull it from the default Maven repository. If not, try adding Sun's repository (Solution 3) and seeing if that will pull down the javamail jar. Be sure to completely delete the javamail directory (~/.m2/repository/javax/mail) before running this.


    Summary / Tradeoffs

    Each solution I found, I didn't quite like for different reasons. Solution 4 was the first satisfying choice. Each of the previous approaches involved tradeoffs. The first one downgrades to an earlier version of Log4j and, clearly, they moved to 1.2.15 for a reason.. Maybe there are security patches. Maybe the difference is negligable. Either way, I don't want to deal with figuring it out. So, Solution 1 would be the quick and dirty fix I'd use a coworker who needed to get their environment working in a hurry but it's not something I'd choose as a long-term fix. Solution falls into a similar boat. I like that it doesn't downgrade, but it cuts out dependences that are probably there for a reason. Most of what I read indicated that those libraries are virtually unused. Still, to me, there their for a reason so although I'd prefer solution 2 over solution 1, I wouldn't use it long-term, either. Solution 3 didn't work for me. The claim was that this repository had all the magic jars required but it didn't turn out that way. Upon download, two of them failed the checksum--I couldn't figure out why--and the other two jars didn't appear to be in the repository at all. In fact, it seemed that the only thing I could get, error-free, was the javamail jar. Not good enough.

    Finally, the fourth solution allowed Log4j to remain at the latest version and keep all it's dependencies. Admittedly, it was far more tedious and took me about 20 minutes to complete. Hopefully, this detailed post will greatly reduce that time for at least one person out there. If that person is you, I hope you can have your cake (a complete solution) and eat it too (a quick solution)! Celebrate.

    5 comments:

    1. Thanks a lot ! Saves lot of time.

      ReplyDelete
    2. Thanks for the description on how to get to the JMX jars. Used it to download the jmxtools and jmxri libraries I needed for my project. Uploaded them to my Nexus repository so I won't have to fool with this mess again.
      I guess the same thing as your 4th option.

      ReplyDelete
    3. Fantastic post -- the last solution worked like a charm for me and saved me hours of frustrations!
      Many thanks for this!

      ReplyDelete
    4. The easiest way is to download all dependencies from here: http://jar-download.com/index.php

      ReplyDelete