莱因没有给uberjar添加罐子

时间:2018-01-14 14:13:09

标签: java jar clojure leiningen uberjar

我正在构建一个简单的Web应用程序,它依赖于几个预编译的jar,我想在Heroku上部署。我将这些罐放入resources文件夹,并将以下行添加到project.clj

:resource-paths ["resources/jsesh-6.5.5.jar"
                 "resources/jseshGlyphs-6.5.5.jar"
                 "resources/java-cup-11b-runtime.jar"
                 "resources/java-cup-11b.jar"
                 "resources/qenherkhopeshefUtils-6.5.5.jar"]

现在我可以使用lein run -m hieroglyphs.web运行项目了。但是,当我使用lein uberjar编译所有内容并尝试

java -cp ./target/hieroglyphs-standalone.jar clojure.main -m hieroglyphs.web

程序启动,但在尝试访问这些jar中定义的类之一时,会以java.lang.NoClassDefFoundError崩溃:

java.lang.NoClassDefFoundError: jsesh/mdcDisplayer/preferences/DrawingSpecification

我应该做些额外的事情,以便在编译后可以访问jar中定义的类吗?

所有代码都可以在这里找到:https://github.com/macleginn/jsesh-web

2 个答案:

答案 0 :(得分:4)

拥有资源目录无济于事。您将需要一个适当的本地Maven存储库。幸运的是,制作一个并不是那么难。

步骤:

    如果需要,
  1. Install Maven
  2. 在源存储库中创建一个lib文件夹
  3. :repositories {"local" "file:lib"}添加到您的project.clj
  4. 对于每个依赖项运行类似mvn deploy:deploy-file -Dfile=resources/jsesh-6.5.5.jar -DartifactId=jsesh -Dversion=6.5.5 -DgroupId=jsesh -Dpackaging=jar -Durl=file:lib的东西(适用于jsesh jar)。请特别注意artifactIdgroupIdversion
  5. 为每个jar添加适当的:dependencies项。例如对于我在步骤4中所做的那个,[jsesh/jsesh "6.5.5"]
  6. 为每个依赖项重复步骤4和5
  7. 您需要将lib文件夹提交给源代码管理,但现在可以从resources

    删除:resource-paths文件夹和project.clj

    (严重基于https://gist.github.com/stuartsierra/3062743的说明)

答案 1 :(得分:2)

您应该更改java次调用以使用-jar选项,如下所示:

~/expr/rundir > java -jar ./calc-0.1.0-SNAPSHOT-standalone.jar 
main - enter
  (ac/add2 3 5) => 8
main - leave

代码如下:

calc
├── project.clj
├── resources
│   └── adder.jar
└── src
    ├── calc
    │   └── core.clj

~/expr/calc > cat src/calc/core.clj 
(ns calc.core
  "Contains the core functions for namespace `calc.core`."
  (:require [adder.core :as ac] )
  (:gen-class))

(defn -main []
  (println "main - enter")
  (println (ac/add2 3 5))
  (println "main - leave"))

文件adder.jar是使用lein jar从另一个项目使用单个函数创建的:

(ns adder.core)
(defn add2 [x y]
  (+ x y))

生成的文件已重命名为" adder.jar"并填入resources项目的calc目录。查看project.clj

(defproject calc  "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.9.0"]
    [org.clojure/test.check "0.9.0"]
    [prismatic/schema "1.1.7"]
    [tupelo "0.9.71"]
  ]
  :profiles {:dev {:dependencies []
                   :plugins [
                     [com.jakemccrary/lein-test-refresh "0.22.0"] ] }
             :uberjar {:aot :all}}
  :global-vars {*warn-on-reflection* false}
  :main ^:skip-aot calc.core

  :source-paths       ["src"]
  :test-paths         ["src"]
  :resource-paths     ["resources/adder.jar"]
  :target-path        "target/%s"
  :jvm-opts           ["-Xms500m" "-Xmx2g"]
)

诀窍就在:resource-paths的行中,如下所示:

:resource-paths     [ "resources/adder.jar" ]

您需要在向量中单独列出每个*.jar文件 作为字符串 。请注意,以下 无效

:resource-paths     [ "resources" ]            ; does not find *.jar files
:resource-paths     [ "resources/*.jar" ]      ; wildcards do not work
:resource-paths     [  resources/adder.jar ]   ; without quotes fails

然后我们可以为calc项目创建一个uberjar,其中包含来自adder.jar的内容:

~/expr/calc > lein uberjar
Compiling _bootstrap
Compiling calc.core
Compiling tst.calc.core
Created /home/alan/expr/calc/target/uberjar/calc-0.1.0-SNAPSHOT.jar
Created /home/alan/expr/calc/target/uberjar/calc-0.1.0-SNAPSHOT-standalone.jar

您想为您的uberjar使用*-standalone.jar版本。我们将其复制到空目录以验证其是否有效:

~/expr/calc > mkdir -p ../rundir
~/expr/calc > cp target/uberjar/calc-0.1.0-SNAPSHOT-standalone.jar ../rundir

~/expr/calc > cd ../rundir
~/expr/rundir > ls -al
total 11744
drwxrwxr-x 2 alan alan     4096 Jan 14 19:22 .
drwxrwxr-x 5 alan alan     4096 Jan 14 19:22 ..
-rw-rw-r-- 1 alan alan 12016027 Jan 14 19:30 calc-0.1.0-SNAPSHOT-standalone.jar

~/expr/rundir > java -jar calc-0.1.0-SNAPSHOT-standalone.jar 
main - enter
  (ac/add2 3 5) => 8
main - leave
相关问题