newBieDev
newBieDev

Reputation: 504

Clojure How To Find and Manage Dependency conflicts.

I recently ran into an issue where including a new dependency in my project broke the functionality of another, unrelated one.

The two in question:

[amazonica "0.3.132"]
[abengoa/clj-stripe "1.0.4"]

Including the above stripe breaks the amazon one, and throws the following error for s3 operations

ERROR org/apache/http/conn/SchemePortResolver
java.lang.NoClassDefFoundError: org/apache/http/conn/SchemePortResolver
    at com.amazonaws.http.apache.client.impl.ApacheHttpClientFactory.<init>(ApacheHttpClientFactory.java:41)

Removing the stripe library fixes the Amazon one, so I've come to suspect there's some sort of conflict there. My question, is how do I figure out what is causing the issue, and fix it.

I found a similar issue on the repo: https://github.com/mcohen01/amazonica/issues/294

Which was fixed with

[clj-facebook-graph "0.4.0" :exclusions [clj-http]]

But I'd like to know how I'd be able to find out what is in the Stripe library that is causing the issue, and how I can go in and fix it without breaking the library. I'm also interested in more general ideas on how to do this so should I encounter it again I can fix the issue.

Upvotes: 2

Views: 1609

Answers (2)

cfrick
cfrick

Reputation: 37073

As it is with problems like that, there is no real silver bullet. The best start to find problems in a leiningen project is to run the deps task. E.g.:

lein deps :tree

Which e.g. in a random project results in the following:

Possibly confusing dependencies found:
[org.clojure/clojurescript "1.9.293"] -> [org.clojure/tools.reader "1.0.0-beta3"]
 overrides
[cljfmt "0.6.0" :exclusions [org.clojure/clojure]] -> [rewrite-cljs "0.4.4"] -> [org.clojure/tools.reader "1.0.5"]
 and
[cljfmt "0.6.0" :exclusions [org.clojure/clojure]] -> [org.clojure/tools.reader "1.2.2"]

Consider using these exclusions:
[cljfmt "0.6.0" :exclusions [org.clojure/clojure org.clojure/tools.reader]]

Those are hints to start from. After that initial block you will see the whole tree of transitive deps. E.g.:

[cljfmt "0.6.0" :exclusions [[org.clojure/clojure]]]
  [com.googlecode.java-diff-utils/diffutils "1.3.0"]
  [org.clojure/tools.cli "0.3.7"]
  [rewrite-clj "0.6.0"]
  [rewrite-cljs "0.4.4"]

And you can try to investigate more from there.

Upvotes: 1

Taylor Wood
Taylor Wood

Reputation: 16194

If you're using Leiningen, you can use lein deps :tree to print helpful debugging information, and before it prints the dependency tree it will print suggested exclusions to avoid these types of issues:

$ lein deps :tree
...
[com.taoensso/faraday "1.9.0"] -> [com.taoensso/encore "2.67.2"] -> [com.taoensso/truss "1.3.3"]
overrides
[amazonica "0.3.112" :exclusions [com.amazonaws/amazon-kinesis-client com.amazonaws/aws-java-sdk com.amazonaws/dynamodb-streams-kinesis-adapter]] -> [com.taoensso/nippy "2.12.2"] -> [com.taoensso/encore "2.68.0"] -> [com.taoensso/truss "1.3.4"]

Consider using these exclusions:
[amazonica "0.3.112" :exclusions [com.amazonaws/amazon-kinesis-client com.taoensso/truss com.amazonaws/dynamodb-streams-kinesis-adapter com.amazonaws/aws-java-sdk]]
...

In my experience there's still some trial and error involved in excluding the precise transitive conflicts. I've had similar issues with AWS SDK, Jackson, etc.

Upvotes: 1

Related Questions