I am trying tools.build for the first time. I have my build.clj (uberjar) from the tools.build guide and it builds the standalone jar but when I try to run the jar I get "no main manifest attribute, in C:\_Dev\atom\buildtools\target\lib1-1.1.2-standalone.jar". Do I need to modify my main program?
(ns hello
(:require [java-time :as t]))
(defn time-str
"Returns a string representation of a datetime in the local time zone."
[instant]
(t/format
(t/with-zone (t/formatter "hh:mm a") (t/zone-id))
instant))
(defn run [opts]
(println "Hello world, the time is" (time-str (t/instant))))The opening paren is missing, but this is likely only a copy-paste mistake?
Also you need a (:gen-class) and a -main function for a jar to be invokable
Yep, just a copy-paste mistake.
See here: https://clojure.org/reference/compilation#_gen_class_examples
Great... that makes sense thank you!
Still getting "no manifest" use tool.build to build an uberjar. I see a "Hello" class now in my target/classes directory
I had the same question not long ago. Two issues: :main and the symbol. I wonder in the case of specifying :main perhaps the program can take both string and symbol without much trouble and there's not gonna be much ambiguity here.
I had the same issue and fixed by adding :main to uber
It was a bit confusing follow the https://clojure.org/guides/tools_build bc itβs not clear how do we specify the entry point of the program.
Should this be included in the tutorial?
@enkidu36 Are you specifying :main to the uber task in tools.build?
Perhaps share your build.clj so we can see what you're actually running?
(ns build
(:require [clojure.tools.build.api :as b]))
(def lib 'my/lib1)
(def version "1.2.4")
(def class-dir "target/classes")
(def basis (b/create-basis {:project "deps.edn"}))
(def uber-file (format "target/%s-%s-standalone.jar" (name lib) version))
(defn clean [_]
(b/delete {:path "target"}))
(defn uber [_]
(clean nil)
(b/copy-dir {:src-dirs ["src" "resources"]
:target-dir class-dir})
(b/compile-clj {:basis basis
:src-dirs ["src"]
:class-dir class-dir})
(b/uber {:class-dir class-dir
:uber-file uber-file
:basis basis}))
You're missing :main in the uber call.
So it won't know what the main ns is.
??
(b/uber {:class-dir class-dir
:uber-file uber-file
:basis basis :main "hello"}You need to tell it which namespace contains your -main function.
OK, but it will need to be a symbol per the docs, not a string.
https://clojure.github.io/tools.build/clojure.tools.build.api.html#var-uber
:main 'hello should work (although your hello ns as posted did not have -main in it)
Yep, the original did not. trying again
Yay! That was it. thx