You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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})

另外还有两个可优化的细节:

  1. write-pom中的version参数可以用已定义的version变量替代硬编码的"1.0.0",保证版本统一::version version
  2. compile-clj里可以显式指定编译的命名空间:ns-compile '[helloearth],避免编译所有代码,提升构建效率。

修改完成后,重新执行clj -T:build uber构建uberjar,再用java -jar target/helloearth-1.2.70-standalone.jar运行,就能正常输出Hello Earth了。

内容的提问来源于stack exchange,提问作者Kingfranz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 17:03:12