Lein构建uberjar后无法加载外部JAR类的问题求助
解决Clojure Uberjar打包后本地JAR依赖无法加载的问题
这个问题的核心原因是:你把本地JAR放在resources目录并通过:resource-paths引用时,lein run会直接把这些JAR加到JVM的类路径里,所以能正常运行;但lein uberjar默认只会把resources里的文件原样复制到打包后的JAR中,不会提取这些JAR内部的类文件合并进去。当你用java -cp ...启动时,JVM只会从指定的standalone JAR里加载类,不会自动去读取里面嵌套的JAR文件,所以就抛出了NoClassDefFoundError。
下面给你两种可行的解决方案,推荐第一种,更符合Leiningen的依赖管理规范:
方案一:将本地JAR安装到本地Maven仓库(推荐)
这种方法把本地JAR当作标准的Maven依赖来处理,Leiningen会自动处理打包逻辑:
- 先给每个JAR执行Maven安装命令(打开终端,进入项目根目录):
# 安装jsesh核心包 mvn install:install-file -Dfile=resources/jsesh-6.5.5.jar -DgroupId=org.jsesh -DartifactId=jsesh -Dversion=6.5.5 -Dpackaging=jar # 安装jsesh字形包 mvn install:install-file -Dfile=resources/jseshGlyphs-6.5.5.jar -DgroupId=org.jsesh -DartifactId=jseshGlyphs -Dversion=6.5.5 -Dpackaging=jar # 安装java-cup编译包 mvn install:install-file -Dfile=resources/java-cup-11b.jar -DgroupId=edu.princeton.cup -DartifactId=java-cup -Dversion=11b -Dpackaging=jar # 安装java-cup运行时包 mvn install:install-file -Dfile=resources/java-cup-11b-runtime.jar -DgroupId=edu.princeton.cup -DartifactId=java-cup-runtime -Dversion=11b -Dpackaging=jar # 安装工具类包 mvn install:install-file -Dfile=resources/qenherkhopeshefUtils-6.5.5.jar -DgroupId=org.jsesh -DartifactId=qenherkhopeshefUtils -Dversion=6.5.5 -Dpackaging=jar - 修改你的
project.clj:- 移除原来的
:resource-paths配置 - 在
:dependencies里添加这些本地依赖::dependencies [ ;; 保留你原来的其他依赖,比如org.clojure/clojure等 [org.jsesh/jsesh "6.5.5"] [org.jsesh/jseshGlyphs "6.5.5"] [edu.princeton.cup/java-cup "11b"] [edu.princeton.cup/java-cup-runtime "11b"] [org.jsesh/qenherkhopeshefUtils "6.5.5"] ]
- 移除原来的
- 重新打包并启动:
lein clean && lein uberjar # 启动应用,用-jar更简洁 java -jar target/hieroglyphs-standalone.jar
方案二:使用本地依赖目录(无需Maven)
如果不想用Maven,可以直接用Leiningen的本地依赖特性:
- 在项目根目录创建
lib文件夹,把所有JAR从resources移到lib里 - 修改
project.clj:- 移除原来的
:resource-paths配置 - 在
:dependencies里添加本地路径依赖::dependencies [ ;; 保留原有依赖 [jsesh "6.5.5" :local/root "lib/jsesh-6.5.5.jar"] [jseshGlyphs "6.5.5" :local/root "lib/jseshGlyphs-6.5.5.jar"] [java-cup "11b" :local/root "lib/java-cup-11b.jar"] [java-cup-runtime "11b" :local/root "lib/java-cup-11b-runtime.jar"] [qenherkhopeshefUtils "6.5.5" :local/root "lib/qenherkhopeshefUtils-6.5.5.jar"] ]
- 移除原来的
- 同样执行
lein clean && lein uberjar后启动即可
两种方案的核心都是让Leiningen把这些本地JAR当作真正的依赖处理,而不是普通的资源文件,这样打包uberjar时就会把JAR里的类提取出来合并到最终的可执行JAR中,解决类找不到的问题。
内容的提问来源于stack exchange,提问作者macleginn
相关产品推荐
相关产品推荐

