Skip to content

Instantly share code, notes, and snippets.

@robjens
Last active August 29, 2015 14:22
Show Gist options
  • Select an option

  • Save robjens/656462cd701a1164a19f to your computer and use it in GitHub Desktop.

Select an option

Save robjens/656462cd701a1164a19f to your computer and use it in GitHub Desktop.
Clojure notes

Clojure Dependency Hell

Clojure and Java + Maven form a great powerhouse in anyone’s stack. How to spot and resolve conflicting software is something that puzzled me for a bit. There are a few techniques to employ:

Steps

The main 'go-to-guy' is lein deps :tree in the /path/to/project/root (read: where the project.clj file is). This will compile a dependency tree which lists conflicting software e.g.

~/clj/kb/drijfveer λ lein deps :tree                                                                      12:12  susy@simbad
Possibly confusing dependencies found:
[com.cemerick/pomegranate "0.3.0"] -> [org.apache.maven/maven-aether-provider "3.0.4"] -> [org.codehaus.plexus/plexus-utils "2.0.6"]
 overrides
[com.cemerick/pomegranate "0.3.0"] -> [org.apache.maven.wagon/wagon-http "2.2"] -> [org.apache.maven.wagon/wagon-http-shared4 "2.2"] -> [org.apache.maven.wagon/wagon-provider-api "2.2"] -> [org.codehaus.plexus/plexus-utils "3.0"]
 and
[com.cemerick/pomegranate "0.3.0"] -> [org.apache.maven.wagon/wagon-http "2.2"] -> [org.apache.maven.wagon/wagon-provider-api "2.2"] -> [org.codehaus.plexus/plexus-utils "3.0"]
 and
[com.cemerick/pomegranate "0.3.0"] -> [org.apache.maven.wagon/wagon-provider-api "2.2"] -> [org.codehaus.plexus/plexus-utils "3.0"]

Consider using these exclusions:
[com.cemerick/pomegranate "0.3.0" :exclusions [org.codehaus.plexus/plexus-utils]]
[com.cemerick/pomegranate "0.3.0" :exclusions [org.codehaus.plexus/plexus-utils]]
[com.cemerick/pomegranate "0.3.0" :exclusions [org.codehaus.plexus/plexus-utils]]

[com.cemerick/pomegranate "0.3.0"] -> [org.apache.maven.wagon/wagon-http "2.2"] -> [org.apache.httpcomponents/httpcore "4.1.2"]
 overrides
[clj-webdriver "0.6.1-LOCAL" :exclusions [commons-codec commons-io]] -> [com.github.detro/phantomjsdriver "1.2.0"] -> [org.seleniumhq.selenium/selenium-java "2.41.0"] -> [org.seleniumhq.selenium/selenium-htmlunit-driver "2.41.0"] -> [net.sourceforge.htmlunit/htmlunit "2.13"] -> [org.apache.httpcomponents/httpmime "4.3.1"] -> [org.apache.httpcomponents/httpclient "4.3.1"] -> [org.apache.httpcomponents/httpcore "4.3"]
 and

.....
Step 1

Execute lein deps :tree

Step 2

Open project.clj in an editor e.g. LT or Emacs.

Step 3

Look at the output and get info on which packages are having what kind of conflict. In our case, fairly obvious the culprit here is a dependency version mismatch between dependencies of separate packages we depend on.

Step 4

Correct the error by supplementing the package as dependency in YOUR project explicitly first. I usually just take the highest version listed.

Step 5

Save the project.clj and rerun lein deps :tree. See if the errors are gone, or got even worse. MOVE AROUND the position of the dependency, usually it needs to be somewhere above the packages requiring it e.g.:

  :dependencies [[org.clojure/clojure "1.6.0"]
                 [prismatic/plumbing "0.4.3"]
                 [org.codehaus.plexus/plexus-utils "3.0"]
                 [org.apache.httpcomponents/httpcore "4.3.2"]
                 [org.clojure/tools.reader "0.8.3"]
                 [cheshire "5.2.0"]
                 [org.json/json "20090211"]
                 [me.raynes/fs "1.4.6"]
                 [enlive "1.1.5"]
                 [clj-webdriver "0.6.1-LOCAL" :exclusions [ commons-codec commons-io ]]
                 [lein-light-nrepl "0.1.0"]
                 [com.cemerick/url "0.1.1"]
                 ]
Step 6

If all else fails, try moving around the other packages a bit if it makes sense. ONLY THEN start adding :exclusions to try and resolve the conflict. Usually it shouldn’t be needed.

So once I did that, then I ran a lein ancient to see which outdated dependencies were there, and set forth to rid the last :exclusions, the tree now looks like:

:dependencies [[org.clojure/clojure "1.6.0"]
                 [prismatic/plumbing "0.4.4"]
                 [commons-codec "1.9"]
                 [org.codehaus.plexus/plexus-utils "3.0.22"]
                 [org.apache.httpcomponents/httpcore "4.4.1"]
                 [org.clojure/tools.reader "0.9.2"]
                 [cheshire "5.5.0"]
                 [org.json/json "20090211"] ; do NOT change/update or webdriver breaks!
                 [me.raynes/fs "1.4.6"]
                 [enlive "1.1.5"]
                 [clj-webdriver "0.6.1-LOCAL"]
                 [lein-light-nrepl "0.1.0"]
                 [com.cemerick/url "0.1.1"]]

Output is:

 [alembic "0.3.2"]
   [lein-as-resource "2.5.0" :exclusions [[org.clojure/clojure]]]
   [org.flatland/classlojure "0.7.0" :exclusions [[org.clojure/clojure]]]
   [org.tcrawley/dynapath "0.2.3" :exclusions [[org.clojure/clojure]]]
 [backtick "0.3.2"]
 [cheshire "5.5.0"]
   [com.fasterxml.jackson.core/jackson-core "2.5.3"]
   [com.fasterxml.jackson.dataformat/jackson-dataformat-cbor "2.5.3"]
   [com.fasterxml.jackson.dataformat/jackson-dataformat-smile "2.5.3"]
   [tigris "0.1.1"]
 [clj-webdriver "0.6.1-LOCAL"]
   [clj-http "0.3.0" :exclusions [[org.apache.httpcomponents/httpclient] [org.apache.httpcomponents/httpcore] [org.apache.httpcomponents/httpmime]]]
     [slingshot "0.10.1"]
   [com.github.detro/phantomjsdriver "1.2.0"]
   [org.clojure/tools.logging "0.2.3"]
   [org.mortbay.jetty/jetty "6.1.25"]
     [org.mortbay.jetty/jetty-util "6.1.25"]
     [org.mortbay.jetty/servlet-api "2.5-20081211"]
   [org.seleniumhq.selenium/selenium-java "2.43.0"]
     [org.seleniumhq.selenium/selenium-chrome-driver "2.43.0"]
     [org.seleniumhq.selenium/selenium-firefox-driver "2.43.0"]
     [org.seleniumhq.selenium/selenium-htmlunit-driver "2.43.0"]
       [net.sourceforge.htmlunit/htmlunit "2.15"]
         [commons-collections "3.2.1"]
         [net.sourceforge.cssparser/cssparser "0.9.14"]
           [org.w3c.css/sac "1.3"]
         [net.sourceforge.htmlunit/htmlunit-core-js "2.15"]
         [net.sourceforge.nekohtml/nekohtml "1.9.21" :exclusions [[xerces/xercesImpl]]]
         [org.apache.commons/commons-lang3 "3.3.2"]
         [org.apache.httpcomponents/httpmime "4.3.3"]
         [org.eclipse.jetty/jetty-websocket "8.1.15.v20140411"]
           [org.eclipse.jetty/jetty-http "8.1.15.v20140411"]
           [org.eclipse.jetty/jetty-io "8.1.15.v20140411"]
           [org.eclipse.jetty/jetty-util "8.1.15.v20140411"]
         [xalan "2.7.1" :exclusions [[xerces/xercesImpl]]]
           [xalan/serializer "2.7.1"]
         [xerces/xercesImpl "2.11.0"]
           [xml-apis "1.4.01"]
     [org.seleniumhq.selenium/selenium-ie-driver "2.43.0"]
     [org.seleniumhq.selenium/selenium-safari-driver "2.43.0"]
     [org.seleniumhq.selenium/selenium-support "2.43.0"]
     [org.webbitserver/webbit "0.4.15"]
       [io.netty/netty "3.5.5.Final"]
   [org.seleniumhq.selenium/selenium-remote-driver "2.43.0"]
     [cglib/cglib-nodep "2.1_3"]
     [com.google.guava/guava "15.0"]
     [net.java.dev.jna/jna "3.4.0"]
     [net.java.dev.jna/platform "3.4.0"]
     [org.apache.commons/commons-exec "1.1"]
     [org.apache.httpcomponents/httpclient "4.3.4"]
       [commons-logging "1.1.3"]
     [org.seleniumhq.selenium/selenium-api "2.43.0"]
   [org.seleniumhq.selenium/selenium-server "2.43.0"]
     [mx4j/mx4j-tools "3.0.1"]
     [net.jcip/jcip-annotations "1.0"]
     [org.bouncycastle/bcpkix-jdk15on "1.48"]
     [org.bouncycastle/bcprov-jdk15on "1.48"]
     [org.mortbay.jetty/servlet-api-2.5 "6.1.9"]
     [org.seleniumhq.selenium/jetty-rc-repacked "5"]
     [org.seleniumhq.selenium/jetty-repacked "7.6.1"]
     [org.yaml/snakeyaml "1.8"]
 [clojure-complete "0.2.3" :scope "test" :exclusions [[org.clojure/clojure]]]
 [com.cemerick/pomegranate "0.3.0"]
   [org.apache.maven.wagon/wagon-http "2.2"]
     [org.apache.maven.wagon/wagon-http-shared4 "2.2"]
   [org.apache.maven.wagon/wagon-provider-api "2.2"]
   [org.apache.maven/maven-aether-provider "3.0.4"]
     [org.apache.maven/maven-model-builder "3.0.4"]
       [org.codehaus.plexus/plexus-interpolation "1.14"]
     [org.apache.maven/maven-model "3.0.4"]
     [org.apache.maven/maven-repository-metadata "3.0.4"]
     [org.codehaus.plexus/plexus-component-annotations "1.5.5" :exclusions [[junit]]]
   [org.sonatype.aether/aether-api "1.13.1"]
   [org.sonatype.aether/aether-connector-file "1.13.1"]
   [org.sonatype.aether/aether-connector-wagon "1.13.1" :exclusions [[org.codehaus.plexus/plexus-utils]]]
     [org.codehaus.plexus/plexus-classworlds "2.4"]
     [org.sonatype.sisu/sisu-inject-plexus "2.2.3"]
       [org.sonatype.sisu/sisu-inject-bean "2.2.3"]
         [org.sonatype.sisu/sisu-guice "3.0.3" :classifier "no_aop" :exclusions [[javax.inject] [aopalliance]]]
   [org.sonatype.aether/aether-impl "1.13.1"]
     [org.sonatype.aether/aether-spi "1.13.1"]
   [org.sonatype.aether/aether-util "1.13.1"]
 [com.cemerick/url "0.1.1"]
   [pathetic "0.5.0"]
     [com.cemerick/clojurescript.test "0.0.4"]
 [commons-codec "1.9"]
 [enlive "1.1.5"]
   [org.ccil.cowan.tagsoup/tagsoup "1.2.1"]
   [org.jsoup/jsoup "1.7.2"]
 [lein-light-nrepl "0.1.0"]
   [clj-stacktrace "0.2.7"]
   [commons-io "2.4"]
   [fs "1.3.3"]
   [ibdknox/analyzer "0.0.2"]
   [ibdknox/tools.reader "0.8.1"]
   [org.clojure/clojurescript "0.0-2202" :exclusions [[org.apache.ant/ant]]]
     [com.google.javascript/closure-compiler "v20131014"]
       [args4j "2.0.16"]
       [com.google.code.findbugs/jsr305 "1.3.9"]
       [com.google.protobuf/protobuf-java "2.4.1"]
     [org.clojure/data.json "0.2.3"]
     [org.clojure/google-closure-library "0.0-20140226-71326067"]
       [org.clojure/google-closure-library-third-party "0.0-20140226-71326067"]
     [org.mozilla/rhino "1.7R4"]
 [me.raynes/fs "1.4.6"]
   [org.apache.commons/commons-compress "1.8"]
     [org.tukaani/xz "1.5"]
 [org.apache.httpcomponents/httpcore "4.4.1"]
 [org.clojure/clojure "1.6.0"]
 [org.clojure/core.cache "0.6.4"]
   [org.clojure/data.priority-map "0.0.4"]
 [org.clojure/tools.nrepl "0.2.6" :scope "test" :exclusions [[org.clojure/clojure]]]
 [org.clojure/tools.reader "0.9.2"]
 [org.codehaus.plexus/plexus-utils "3.0.22"]
 [org.json/json "20141113"]
 [prismatic/plumbing "0.4.1"]
   [de.kotka/lazymap "3.1.0" :exclusions [[org.clojure/clojure]]]
 [prismatic/schema "0.4.2"]
 [swiss-arrows "1.0.0"]
@robjens
Copy link
Author

robjens commented Jun 7, 2015

So the main idea is, if the compiler is confused about dependencies, make it so that there is no ambiguity/confusion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment