使用 lein uberjar 生成的 Jar 在 NoClassDefFoundError 上失败 [英] Jar produced with lein uberjar fails on NoClassDefFoundError
问题描述
我有一个带有这个 project.clj 的简单网络应用程序:
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")
我的主要内容如下:
(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))
使用 REPL 工作得很好.但是,当我使用 lein uberjar
生成一个 jar 并尝试将其执行为:
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?
不确定这是否重要,但我注意到在 jar 中,我的文件、clojure 本身和 Java 库被解压为 .class 文件,而所有 clojure 库仅作为普通的 .clj 文件存在.
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.
推荐答案
这似乎是 leinigen 1.4.0 的错误.您可能想尝试使用 leiningen 1.3.1 创建一个 uberjar.
This seems to be a leinigen 1.4.0 bug. You might want to try creating an uberjar with leiningen 1.3.1.
编辑:
Leiningen 1.4.0 删除非项目 .class
文件以解决 Clojure 错误(请参阅 CLJ-322).显然,这种行为有时会导致问题.
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.
您可以通过将 :keep-non-project-classes
设置为 true
来防止 leiningen 1.4.0 删除非项目 .class
文件> 在您的 project.clj
中.
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
.
有关详细信息,请参阅相关的 leinigen 问题.
See the related leinigen issue for more info.
这篇关于使用 lein uberjar 生成的 Jar 在 NoClassDefFoundError 上失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!