{"id":906,"date":"2009-05-18T10:44:35","date_gmt":"2009-05-18T15:44:35","guid":{"rendered":"http:\/\/unitstep.net\/?p=906"},"modified":"2009-05-18T10:44:35","modified_gmt":"2009-05-18T15:44:35","slug":"resolving-log4j-1215-dependency-problems-in-maven-using-exclusions","status":"publish","type":"post","link":"https:\/\/unitstep.net\/blog\/2009\/05\/18\/resolving-log4j-1215-dependency-problems-in-maven-using-exclusions\/","title":{"rendered":"Resolving log4j 1.2.15 dependency problems in Maven using exclusions"},"content":{"rendered":"

\"maven\"<\/p>\n

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<\/a> depends on some artifacts that are not available in the central Maven repository<\/a> due to licensing issues<\/a>, 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.<\/p>\n

We could download and install these artifacts to the local repository<\/a>, 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.<\/p>\n

<\/p>\n

The problem: Not really needed<\/h2>\n

The issue is going from log4j 1.2.14<\/a> to 1.2.15<\/a>, the developers added some features which required some dependencies on various sun<\/code> and javax<\/code> 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<\/em> rule.<\/p>\n

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<\/code>, you’re likely to encounter this sort of error:<\/p>\n

[INFO] Unable to find resource 'com.sun.jdmk:jmxtools:jar:1.2.1' in repository central (http:\/\/repo1.maven.org\/maven2)\r\n[INFO] Unable to find resource 'javax.jms:jms:jar:1.1' in repository central (http:\/\/repo1.maven.org\/maven2)\r\n[INFO] Unable to find resource 'com.sun.jmx:jmxri:jar:1.2.1' in repository central (http:\/\/repo1.maven.org\/maven2)\r\n[INFO] ------------------------------------------------------------------------\r\n[ERROR] BUILD ERROR\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] Failed to resolve artifact.\r\n\r\nMissing:\r\n----------\r\n1) com.sun.jdmk:jmxtools:jar:1.2.1\r\n...\r\n2) javax.jms:jms:jar:1.1\r\n...\r\n3) com.sun.jmx:jmxri:jar:1.2.1\r\n...\r\n----------\r\n3 required artifacts are missing.<\/code><\/pre>\n

And if you’re using Eclipse, and have used the Maven Eclipse plugin command (mvn eclipse:eclipse<\/code>) 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:<\/p>\n

\n\"maven-log4j-1\"<\/a>\n<\/p>\n

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

Excluding dependencies<\/h2>\n

Thankfully, Maven make it easy to exclude dependencies<\/a> from a certain project. Looking at the log4j 1.2.15 POM file<\/a> (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:<\/p>\n

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

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.<\/strong><\/p>\n

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

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<\/strong> of the dependencies for a project, but there is a feature request<\/a> for such an ability. <\/p>\n

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

\n\"maven-log4j-2\"<\/a>\n<\/p>\n

Everything should now work!<\/p>\n

Transitive Dependencies and Exclusions<\/h2>\n

The issue here is that the log4j 1.2.15 POM file probably should have marked these dependencies as optional<\/strong>, 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<\/strong> dependency mean? The Maven website has a pretty good explanation<\/a>.<\/p>\n

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.<\/p>\n

Also worthy to note: exclusions are done on a per-dependency basis<\/strong>. This means that the dependencies that we excluded from log4j are only excluded from the log4j scope<\/strong>. This has the effect of not<\/strong> globally excluding those dependencies. So, for example, if we added another dependency that did really require the javax.jms\/jms<\/code> 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.<\/p>\n

References<\/h4>\n
    \n
  1. Exclude Transitive Dependencies<\/a><\/li>\n
  2. Maven and Excluding Transitive Dependencies<\/a><\/li>\n<\/ol>","protected":false},"excerpt":{"rendered":"

    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 […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[354,208,197,350],"tags":[351,353,352,490],"_links":{"self":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts\/906"}],"collection":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/comments?post=906"}],"version-history":[{"count":10,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts\/906\/revisions"}],"predecessor-version":[{"id":919,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts\/906\/revisions\/919"}],"wp:attachment":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/media?parent=906"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/categories?post=906"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/tags?post=906"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}