Resolving log4j 1.2.15 dependency problems in Maven using exclusions

maven

If you’re using Maven to manage your project’s build and dependencies, you may have encountered some problems when trying to include the latest version of log4j as a dependency. Specifically, log4j 1.2.15 depends on some artifacts that are not available in the central Maven repository due to licensing issues, and thus when you try to build a project that depends on this version of log4j, you may not be able to download the artifacts and your build will fail.

We could download and install these artifacts to the local repository, if we really needed them. But in most cases, they’re not needed and thus you won’t want your project relying on these artifacts just because some parts of log4j do. Thus, we need to exclude them.

The problem: Not really needed

The issue is going from log4j 1.2.14 to 1.2.15, the developers added some features which required some dependencies on various sun and javax packages. However in most cases, you won’t be using this extra functionality, but if you just include log4j 1.2.15, this will cause your project to require those extra artifacts as per the transitive dependency rule.

Because some of these artifacts are not available from the central Maven repository, due to licensing issues, they will not be automatically installed to your local repository. So, if you attempt to run mvn install, you’re likely to encounter this sort of error:

[INFO] Unable to find resource 'com.sun.jdmk:jmxtools:jar:1.2.1' in repository central (http://repo1.maven.org/maven2)
[INFO] Unable to find resource 'javax.jms:jms:jar:1.1' in repository central (http://repo1.maven.org/maven2)
[INFO] Unable to find resource 'com.sun.jmx:jmxri:jar:1.2.1' in repository central (http://repo1.maven.org/maven2)
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.

Missing:
----------
1) com.sun.jdmk:jmxtools:jar:1.2.1
...
2) javax.jms:jms:jar:1.1
...
3) com.sun.jmx:jmxri:jar:1.2.1
...
----------
3 required artifacts are missing.

And if you’re using Eclipse, and have used the Maven Eclipse plugin command (mvn eclipse:eclipse) to generate the project settings, you’ll have the problem of Eclipse not being able to find the artifacts references on the build path, resulting in an error like so:

maven-log4j-1

This causes a big problem as it essentially prevents you from building your project. You could download and install these artifacts to your local repository, but since they’re not really needed, we should exclude them from the dependency list for log4j.

Excluding dependencies

Thankfully, Maven make it easy to exclude dependencies from a certain project. Looking at the log4j 1.2.15 POM file (you may have to select “View Source”), we can see several dependencies that weren’t there in the previous release. These are likely to support new features, and aren’t needed for the most common uses of log4j. Here are the actual dependencies for log4j 1.2.15:

<dependencies>
  <dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4</version>
  </dependency>
  <dependency>
    <groupId>javax.jms</groupId>
    <artifactId>jms</artifactId>
    <version>1.1</version>
  </dependency>
 <dependency>
    <groupId>com.sun.jdmk</groupId>
    <artifactId>jmxtools</artifactId>
    <version>1.2.1</version>
  </dependency>
 <dependency>
    <groupId>com.sun.jmx</groupId>
    <artifactId>jmxri</artifactId>
    <version>1.2.1</version>
  </dependency>
 <dependency>
    <groupId>oro</groupId>
    <artifactId>oro</artifactId>
    <version>2.0.8</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
  </dependency>
</dependencies>

We only need to exclude the first four, and not the last two, since they have a scope of test, and won’t be included anyways. To exclude these dependencies, add the log4j 1.2.15 dependency as show below.

<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.15</version>
  <scope>provided</scope>
  <exclusions>
    <exclusion>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
    </exclusion>
    <exclusion>
      <groupId>javax.jms</groupId>
      <artifactId>jms</artifactId>
    </exclusion>
    <exclusion>
      <groupId>com.sun.jdmk</groupId>
      <artifactId>jmxtools</artifactId>
    </exclusion>
    <exclusion>
      <groupId>com.sun.jmx</groupId>
      <artifactId>jmxri</artifactId>
    </exclusion>
  </exclusions>
</dependency>

This tells Maven not to add those artifacts to the classpath and so they won’t be needed to build your project anymore. Note that you have to explicitly exclude each one, there is no way to exclude all of the dependencies for a project, but there is a feature request for such an ability.

If you’re using Eclipse, after running mvn eclipse:clean/mvn eclipse:eclipse, you should have the build path properly setup without any missing artifacts:

maven-log4j-2

Everything should now work!

Transitive Dependencies and Exclusions

The issue here is that the log4j 1.2.15 POM file probably should have marked these dependencies as optional, which would have had the same effect as having to exclude them on every project that referenced that version of log4j. What does an optional dependency mean? The Maven website has a pretty good explanation.

Basically, if you have a large project that requires a lot of dependencies, but the “core” features only require a subset of those dependencies, you may want to mark the others as “optional” so as not to burden any projects that reference yours. Your project will still need all of the dependencies to build, but other projects that reference yours will only need the optional dependencies if they are using the additional features. In this case, they’ll have to explicitly add those dependencies, as the transitive dependency rule won’t kick in for “optional” ones.

Also worthy to note: exclusions are done on a per-dependency basis. This means that the dependencies that we excluded from log4j are only excluded from the log4j scope. This has the effect of not globally excluding those dependencies. So, for example, if we added another dependency that did really require the javax.jms/jms artifact, it would not be prevented from being added. Furthermore, if we wanted, we could manually add a dependency to our own list for that JMS artifact, and it would show up as normal.

References

  1. Exclude Transitive Dependencies
  2. Maven and Excluding Transitive Dependencies

34 Comments »

  1. Thanks! Exactly the information I needed!

    I didn’t knew that the missing jar files where absent because of licencing issues.

    I’m astonished that such a problem is not addressed by maven, or at least the m2eclipse plugin.
    Something minimal, like adding a licensing text inside the pom, and request the user to accept the licence by clicking a button (inside the eclipse plugin), or setting some flag in the local repository directory structure (like adding an empty file “licence-ok.txt”)

    Anyway…Great post!

  2. Thanks, it was very helpful!

    … and maven/sun licencing problem very annoing – and for years not resolved πŸ™

  3. If you just use the log4j 1.2.14 instead of 1.2.15, things will be much easier.

  4. I tried doing this, and for some strange reason, the maven eclipse:eclipse insisted on treating the log4j as an Eclipse “project” instead if just referring to jar in my local .m2 repository. This of course made my project using log4j fail to build, because I don’t have log4j as an Eclipse project in my workspace.

    Using 1.2.14 without the excludes – worked fine.

    Any ideas why eclipse:eclipse is acting up on this one? (I’m using version 2.7 of the maven eclipse plugin)

  5. Thanks. This helped me out enormously.

  6. Thanks very much for the detailed explanations. I’m only doing my first steps with Maven so this helped me a lot.

  7. a much needed post. thanks

  8. I have a problem setting up a log4j.xml config file (for commons logging) in my maven project.

    This is what I did.
    1) Added a commons-logging dependency into pom.xml
    2) Added a resource log4j.xml in pom.xml
    3) Added log statements in the class

    But I saw that the pattern of log messages in not what I set in my log4j.xml. It seemed it picked some other config file.

    To overcome that,
    1) I added commons-logging.properties in the classpath, which set log4j.configuration=wcp-log4j.xml (I renamed the log4j.xml file to my custom one).

    Still no luck.
    So I searched for log4j jars in my local maven repository and found that there were some four log4j jars. So in my pom.xml I excluded all these jars against my dependency of commons-logging.

    Still no luck. It still prints the messages with the default pattern.

    So can you please help me with regards to this?

  9. Thanks for posting this – solution with explanation!

  10. Cheers, you made my day πŸ™‚

  11. Thanks a lot for this info! It explained everything I needed to know very thoroughly!! πŸ™‚

  12. Thanks for this tip; I keep using 1.2.15 and I keep forgetting it has this problem! πŸ™‚

  13. Thanks!

  14. THAAAAAANKS!!!!!!

  15. Thanks! πŸ™‚

  16. Thanks. Worked for me.

  17. Saved me a lot of hassle. Thank you!!

  18. Thanx a lot…….:)

  19. Thanks!

  20. It’s fair to say that while version 1.2.15 has this problem with its maven dependencies, in version 1.2.16 they have fixed this issue by declaring those dependencies as true.
    Just update the dependency to 1.2.16 and the problem is solved!

  21. I love you for this !

  22. Thanks for the detailed explaination

  23. […] Resolving log4j 1.2.15 dependency problems in Maven using exclusions <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.15</version> <scope>provided</scope> <exclusions> <exclusion> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> </exclusion> <exclusion> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> </exclusion> <exclusion> <groupId>com.sun.jdmk</groupId> <artifactId>jmxtools</artifactId> </exclusion> <exclusion> <groupId>com.sun.jmx</groupId> <artifactId>jmxri</artifactId> </exclusion> </exclusions> </dependency> This entry was posted in Professional by patrick. Bookmark the permalink. […]

  24. Thank you very much!

  25. Thank you very very much!!! Exactly the information I needed! It’s all been said. Just thank you.

  26. Thx alot. Save me a ton of time figuring it out πŸ™‚

  27. Crisp and just the needed info. Thanks.

  28. Succinct, accurate and saved me a lot of mindless digging. Thank you!

  29. Exactly What I was looking for…Cheers πŸ™‚

  30. Thank a lot for the solutions with good explanation.

  31. […] that are not available in the central maven repository because of licensing issues. This post (http://unitstep.net/blog/2009/05/18/resolving-log4j-1215-dependency-problems-in-maven-using-exclusio…) has more information in […]

  32. Perfect!

    The information I need, well redacted.

    Brilliant!

    Thank you very much.

  33. Perfect…we were struggling with it for more than 3 hours.
    Thanks a lot!!!

  34. Thank you! A lucid explanation of the problem and solution. Much appreciated.

Comments are now closed for this entry.