我正在构建一个简单的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
答案 0 :(得分:4)
拥有资源目录无济于事。您将需要一个适当的本地Maven存储库。幸运的是,制作一个并不是那么难。
步骤:
lib
文件夹:repositories {"local" "file:lib"}
添加到您的project.clj
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)。请特别注意artifactId
,groupId
和version
:dependencies
项。例如对于我在步骤4中所做的那个,[jsesh/jsesh "6.5.5"]
您需要将lib
文件夹提交给源代码管理,但现在可以从resources
:resource-paths
文件夹和project.clj
位
答案 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