I have a simple web app with this project.clj:
(defproject squirrel-money "1.0.0-SNAPSHOT"
:description "Squirrel Money"
:dependencies [[org.clojure/clojure "1.2.0"]
[org.clojure/clojure-contrib "1.2.0"]
[compojure "0.5.3"]
[ring/ring-jetty-adapter "0.3.5"]
[hiccup "0.3.1"]
[postgresql "8.4-701.jdbc4"]
[clj-time "0.2.0-SNAPSHOT"]]
:dev-dependencies [[lein-eclipse "1.0.0"]]
:main squirrel-money.main
:repl-init-script "src/squirrel_money/init_repl.clj")
My main looks like this:
(ns squirrel-money.main
(:gen-class)
(:use
[compojure.core]
[ring.adapter.jetty])
(:require
[compojure.route :as route]
[squirrel-money.savings :as savings]))
(defn launch [routedef]
(run-jetty routedef {:port 17080}))
(defroutes money-routes
(GET "/savings" [] (savings/render))
(route/not-found "Page not found"))
(defn -main [& args] (launch money-routes))
With REPL works just fine. However, when I generate a jar with lein uberjar
and try to execute it as:
java -jar squirrel-money-1.0.0-SNAPSHOT-standalone.jar
It dies with this exception:
Exception in thread "main" java.lang.NoClassDefFoundError: compojure/response/Renderable
at squirrel_money.main$fn__1067.invoke(main.clj:18)
at squirrel_money.main__init.load(Unknown Source)
at squirrel_money.main__init.<clinit>(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at clojure.lang.RT.loadClassForName(RT.java:1578)
at clojure.lang.RT.load(RT.java:399)
at clojure.lang.RT.load(RT.java:381)
at clojure.core$load$fn__4511.invoke(core.clj:4905)
at clojure.core$load.doInvoke(core.clj:4904)
at clojure.lang.RestFn.invoke(RestFn.java:409)
at clojure.lang.Var.invoke(Var.java:365)
at squirrel_money.main.<clinit>(Unknown Source)
Caused by: java.lang.ClassNotFoundException: compojure.response.Renderable
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
... 13 more
What am I doing wrong? How to get it to work?
Not sure if that matters, but I noticed that inside the jar my files, clojure itself and Java libs are unpacked as .class files, while all clojure libs are present only as plain .clj files.
This seems to be a leinigen 1.4.0 bug. You might want to try creating an uberjar with leiningen 1.3.1.
Edit:
Leiningen 1.4.0 deletes non-project .class
files to work around a Clojure bug (see CLJ-322). Apparently this behavior can sometimes cause problems.
You can keep leiningen 1.4.0 from deleting non-project .class
files by setting :keep-non-project-classes
to true
in your project.clj
.
See the related leinigen issue for more info.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With