lein-ring
lein-ring copied to clipboard
uberwar fails in very non-obvious way when a system path is in classpath
With the following project.clj:
(defproject thing "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.5.1"]
[ring/ring-json "0.3.1"]
[ring/ring-jetty-adapter "1.3.0"]]
:plugins [[lein-ring "0.8.10"]
[lein-javadoc "0.1.1"]]
:ring {:handler thing.core/handler})
the command lein ring uberwar fails with the message:
$ lein ring uberwar
java.util.zip.ZipException: duplicate entry: WEB-INF/classes/
at java.util.zip.ZipOutputStream.putNextEntry(ZipOutputStream.java:215)
at java.util.jar.JarOutputStream.putNextEntry(JarOutputStream.java:109)
at sun.reflect.GeneratedMethodAccessor31.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)
at leiningen.ring.war$write_entry.invoke(war.clj:162)
at leiningen.ring.war$file_entry.invoke(war.clj:178)
at leiningen.ring.war$dir_entry.invoke(war.clj:183)
at leiningen.ring.uberwar$write_uberwar.invoke(uberwar.clj:48)
at leiningen.ring.uberwar$uberwar.invoke(uberwar.clj:74)
at leiningen.ring.uberwar$uberwar.invoke(uberwar.clj:62)
at clojure.lang.AFn.applyToHelper(AFn.java:161)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.core$apply.invoke(core.clj:619)
at leiningen.ring$ring.doInvoke(ring.clj:28)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.core$apply.invoke(core.clj:619)
at leiningen.core.main$resolve_task$fn__2160.doInvoke(main.clj:148)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:619)
at leiningen.core.main$apply_task.invoke(main.clj:188)
at leiningen.core.main$resolve_and_apply.invoke(main.clj:192)
at leiningen.core.main$_main$fn__2223.invoke(main.clj:256)
at leiningen.core.main$_main.doInvoke(main.clj:246)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.core$apply.invoke(core.clj:617)
at clojure.main$main_opt.invoke(main.clj:335)
at clojure.main$main.doInvoke(main.clj:440)
at clojure.lang.RestFn.invoke(RestFn.java:457)
at clojure.lang.Var.invoke(Var.java:427)
at clojure.lang.AFn.applyToHelper(AFn.java:172)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
and it's due to the lein-javadoc plugin depending on these two jars:
/usr/lib/jvm/java-7-openjdk-amd64/lib/tools.jar
/usr/lib/jvm/java-7-openjdk-amd64/lib/sa-jdi.jar
I think what happens is that in in-war-path, the jar can't be relativize'd and so in-war-path returns "WEB-INF/classes/". As a result, the .putNextEntry function is called twice with "WEB-INF/classes" as the war-path and so the duplicate entry exception is thrown.
To fix this within my project I've just gone ahead and moved the lein-javadoc plugin into a separate profile so that it does not add to the classpath. It would be nice if at the least, some better messaging were printed to the screen.