使用 lein uberjar 生成的 Jar 在 NoClassDefFoundError 上失败 [英] Jar produced with lein uberjar fails on NoClassDefFoundError

查看:20
本文介绍了使用 lein uberjar 生成的 Jar 在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆