使用deps.edn和build.clj构建uberjar失败,启动报错找不到主类
问题
使用deps.edn和build.clj构建uberjar时,编译过程正常,但运行生成的jar包时出现以下错误:
Error: Could not find or load main class _main
Caused by: java.lang.ClassNotFoundException: _main
已将问题简化为以下文件,请问遗漏了什么配置或步骤?
helloearth.clj
(ns helloearth (:gen-class)) (defn -main [& args] (println "Hello Earth"))
deps.edn
{; project paths :paths ["src"] :deps { org.clojure/clojure {:mvn/version "1.12.0"} } :aliases { ;; Run with clj -T:build function-in-build :build {:deps {io.github.clojure/tools.build {:git/tag "v0.10.6" :git/sha "52cf7d6"}} :ns-default build} }}
build.clj
(ns build (:require [clojure.tools.build.api :as b])) (def lib 'helloearth/helloearth) (def version (format "1.2.70")) (def class-dir "target/classes") (def uber-file (format "target/%s-%s-standalone.jar" (name lib) version)) ;; delay to defer side effects (artifact downloads) (def basis (delay (b/create-basis {:project "deps.edn"}))) (defn clean [_] (b/delete {:path "target"})) (defn uber [_] (clean nil) (b/copy-dir {:src-dirs ["src"] :target-dir class-dir}) (b/write-pom {:class-dir class-dir :lib lib :version "1.0.0" :basis basis :src-dirs (:paths basis)}) (b/compile-clj {:basis @basis ;:ns-compile '[clock2.main] :src-dirs (:paths basis) :class-dir class-dir}) (b/uber {:class-dir class-dir :uber-file uber-file :basis basis :main '-main}))
解决方法
问题出在build.clj的uber任务配置里,:main参数设置错误:
- 当前你指定的是
:main '-main,但tools.build要求这里填写的是包含-main函数的命名空间,而非函数名本身。你的-main函数在helloearth命名空间下,所以应该改为:main 'helloearth。
修改后的uber函数片段:
(b/uber {:class-dir class-dir :uber-file uber-file :basis basis :main 'helloearth})
另外还有两个可优化的细节:
write-pom中的version参数可以用已定义的version变量替代硬编码的"1.0.0",保证版本统一::version versioncompile-clj里可以显式指定编译的命名空间:ns-compile '[helloearth],避免编译所有代码,提升构建效率。
修改完成后,重新执行clj -T:build uber构建uberjar,再用java -jar target/helloearth-1.2.70-standalone.jar运行,就能正常输出Hello Earth了。
内容的提问来源于stack exchange,提问作者Kingfranz
相关产品推荐
相关产品推荐

