tools-build 2023-06-20

i’m able to build an uberjar but when i try to run the jar i’m getting this error

clj -T:build uberjar

java -jar target/gamebox-standalone.jar
Error: Could not find or load main class gamebox.core.main
Caused by: java.lang.ClassNotFoundException: gamebox.core.main
i have gen-class in my gamebox.core namespace and the entry point is -main my src path is not src but rather src/clj as i also have src/cljs in the same repo for my frontend code. target/classes appears to have a class generated as well
ls -lah target/classes/gamebox

api
config$config$fn__418.class
config$config.class
config$fn__416.class
config$loading__6789__auto____156.class
config.clj
config__init.class
core$_main.class
core$fn__9453.class
core$fn__9455.class
core$loading__6789__auto____3358.class
core$restart_server.class
core$stop_server.class
core.class
core.clj
core__init.class
mock-file.txt
router$fn__9447.class
router$fn__9449.class
router$fn__9451.class
router$loading__6789__auto____4162.class
router.clj
router__init.class
scratch$fn__142.class
scratch$loading__6789__auto____140.class
scratch.clj
scratch__init.class
not quite sure what i’m missing / doing wrong. i tried reading other related threads in slack but am stuck. open to any help or advice here; thank you.

deps.edn

{:aliases {:ancient  {:extra-deps #:com.github.liquidz{antq #:mvn{:version
                                                                  "RELEASE"}}
                      :main-opts  ["-m" "antq.core"]}
           :run      {:main-opts ["-m" "gamebox.core"]}
           ;; build tools
           :build    {:deps       #:io.github.clojure{tools.build
                                                      #:git{:sha "76b78fe"
                                                       :tag "v0.9.4"}}
                      :ns-default build}
           :uberdeps {:main-opts     ["-m" "uberdeps.uberjar"]
                      :replace-deps  #:uberdeps{uberdeps #:mvn{:version
                                                               "1.3.0"}}
                      :replace-paths []}
           ;; testing and debugging tools:
           :test     {:exec-fn     cognitect.test-runner.api/test
                      :extra-deps  #:io.github.cognitect-labs{test-runner
                                                              #:git{:sha
                                                                    "dfb30dd"
                                                               :tag
                                                                    "v0.5.1"}}
                      :extra-paths ["test/clj"]
                      :main-opts   ["-m" "cognitect.test-runner"]}}
 :deps    {aero/aero                   #:mvn{:version "1.1.6"}
           clj-http/clj-http           #:mvn{:version "3.12.3"}
           http-kit/http-kit           #:mvn{:version "2.5.3"}
           metosin/reitit              #:mvn{:version "0.5.18"}
           org.clojure/clojure         #:mvn{:version "1.11.1"}
           org.clojure/tools.namespace #:mvn{:version "1.4.4"}}
 :paths   ["src/clj" "resources"]}

build.clj

(ns build
  (:require [clojure.tools.build.api :as build-api]))

;; Build configuration
(def project-config
  "Project configuration to support all tasks"
  {:main-namespace  'gamebox.core/main
   :class-directory "target/classes"
   :project-basis   (build-api/create-basis {:project "deps.edn"})
   :uberjar-file    "target/gamebox-standalone.jar"})

;; Build tasks
(defn clean [_] (build-api/delete {:path "target"}))

(defn uberjar
  [_]
  (let [{:keys [class-directory main-namespace project-basis uberjar-file]}
        project-config]
    (clean nil)
    (build-api/copy-dir {:src-dirs   ["src/clj" "resources"]
                         :target-dir class-directory})
    (build-api/compile-clj
     {:basis project-basis :src-dirs ["src/clj"] :class-dir class-directory})
    (build-api/uber {:class-dir class-directory
                     :uber-file uberjar-file
                     :basis     project-basis
                     :main      main-namespace})))

core.clj

(ns gamebox.core
  (:require [org.httpkit.server :refer [run-server]]
            [clojure.tools.namespace.repl :as ns-tools])
  (:require [gamebox.config :as config]
            [gamebox.router :as router])
  (:gen-class))

(def app-config (config/config))

(def app router/app-router)

(defonce server (atom nil))

(defn stop-server
  []
  (when-not (nil? @server)
    ;; graceful shutdown: wait 100ms for existing requests to be finished
    ;; :timeout is optional, when no timeout, stop immediately
    (@server :timeout 100)
    (reset! server nil)))

(defn -main
  [& args]
  ;; The #' is useful when you want to hot-reload code
  ;; You may want to take a look: 
  ;; and 
  (println "server started on:" (:port app-config))
  (reset! server (run-server #'app app-config)))

(defn restart-server
  []
  (when @server (@server))
  (ns-tools/refresh :after 'gamebox.core/-main))

(comment (restart-server) (stop-server))

Alex Miller (Clojure team) 2023-06-20T16:31:18.937959Z

The main namespace should just be gamebox.core - you don’t say the method name (because it’s always main)

-  {:main-namespace  'gamebox.core/main
+  {:main-namespace  'gamebox.core

that worked! thank you!