I have created a new project with
lein new jar-clash-test
cd jar-clash-test/
I have put the following in project.clj
(defproject jar-clash-test "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.5.0"]
[io.pedestal/pedestal.service "0.1.2"]
...]
:main ^{:skip-aot true} jar-clash-test.core
)
I have put the following in jar-clash-test/src/jar_clash_test/core.clj
(ns jar-clash-test.core
(:require [io.pedestal.service.http :as bootstrap]))
When I run this with
lein repl
I get the following error:
CompilerException java.lang.RuntimeException: No such var: content-type/content-type-response, compiling:(io/pedestal/service/http/ring_middlewares.clj:46:3)
When I look at:
/.m2/repository/io/pedestal/pedestal/0.1.2/pedestal.service-0.1.2/io/ring_middlewares.clj
On line 46 I see:
(leave-interceptor ::content-type-interceptor content-type/content-type-response opts))
Which is defined in the requirements as:
[ring.middleware.content-type :as content-type]
Which means it is trying to bring in the ring-middleware jar.
My hypothesis is that there is a jar version clash for the ring middleware implementation.
This is based on:
When I look at:
/.m2/repository/ring/ring-core/1.2.0-beta1/ring-core-1.2.0-beta1/ring/middleware/content_type.clj
The function
(defn content-type-response
exists. When I look at:
/.m2/repository/ring/ring-core/1.1.5/ring-core-1.1.5/ring/middleware/content_type.clj
The function doesn't exist.
My question is - how do I know which version lein has picked up? I can 'assume' it has picked up the earlier one - but how I can know for certain?
My second question is - how can I guarantee which one lein will pick?
You can say lein classpath
to get a printout of the computed value of the classpath for your project. Earlier jars win. Another approach: examine the value of (System/getProperty "java.class.path")
at the REPL.
If you want to pick a version of an indirect dependency by hand, make it direct, that is, add it to your project.clj
; this entry will then override the dependencies' choices in the context of this project. Alternatively, you could add :exclusions
to all but one of your dependencies which cause the indirect dependency to be pulled in.