beginners 2026-01-04

Hi.When building my tiny test project I get: $ cd <PROJECT-ROOT> $ clj -T:build uber Namespace could not be found on classpath: build I did everything according to: https://clojure.org/guides/tools_build

Hang on.... I ENTER-ed too early.... Sry!

My dep.edn is:

{:paths ["src"]
 :deps {org/jaudiotagger {:mvn/version "2.0.3"}
        claudio/claudio {:mvn/version "0.1.3"}}
 :aliases
 {;; Run with clj -T:build function-in-build
  :build {:deps {io.github.clojure/tools.build {:git/tag "v0.10.11" :git/sha "c6c670a"}} 
          :ns-default build
          }}}

(It's "deps.edn" actually...)

The build.clj resides directly in src:

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

(def lib 'audio-tagger)
(def version (format "0.1.%s" (b/git-count-revs nil)))
(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" "resources"]
               :target-dir class-dir})
  (b/compile-clj {:basis @basis
                  :ns-compile '[audio-tagger]
                  :class-dir class-dir})
  (b/uber {:class-dir class-dir
           :uber-file uber-file
           :basis @basis
           :main 'audio-tagger.main}))

There is a main in src/audio_tagger.clj:

(defn -main [& args]
  (if (seq args)
    (doseq [arg args]
      (println arg))
    (throw (Exception. "Must have at least one argument!"))))
But I never get to a point to compile this. It already fails to find the build.clj, which is right in <PROJECT-ROOT>/src

I spend all day to compile these 5 lines. In my frustration I finally came here to beg for some pros hints.

Alex Miller (Clojure team) 2026-01-04T20:58:35.745419Z

When using -T the project paths are not on the classpath (but by default “.” Is)

Alex Miller (Clojure team) 2026-01-04T20:59:49.548089Z

So you can put it in the project root or add :paths [“src”] to your :build alias

I understand the second part of your suggestion, and already tried it. Result:

:aliases
 {;; Run with clj -T:build function-in-build
  :build {:deps {io.github.clojure/tools.build {:git/tag "v0.10.11" :git/sha "c6c670a"}}
          :paths ["src"]   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
          :ns-default build
          }}}
$ clj -T:build uber fatal: No Git-Repository (or parent folder ... /) Stoppe bei Dateisystemgrenze (GIT_DISCOVERY_ACROSS_FILESYSTEM nicht gesetzt). Downloading: org/clojure/clojure/1.12.0/clojure-1.12.0.pom from central Downloading: org/clojure/clojure/1.12.0/clojure-1.12.0.jar from central

Sry about the German snippets...

I think I get a clue on your hint "you can put it in the project root". You speak of build.clj? That can be moved from src to <PROJECT-ROOT>? I'll try it. Already MANY THANKS for having a look at this misery.

Unfortunately same result as above.

Okay, I just learned here: https://kozieiev.com/blog/packaging-clojure-into-jar-uberjar-with-tools-build/ that build.clj MUST reside in project root, it seems. The rest is identlical to the official guide. Alas, I still get:

$ cd <PROJECT-ROOT>
$ clj -T:build uber
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

Alex Miller (Clojure team) 2026-01-04T21:36:29.676399Z

going to move to a thread here for less noise in the channel... it's not "must", it's just that the root of the project is the path on the classpath (by default) when using -T. so if you put a build.clj in the root (ns build), then that is available on the classpath. you could leave it in src, but the namespace should then be ns src.build (and referenced as src.build in the alias to find it relative to the classpath (which has a path at "."). Or you can add a :paths with some other path and put it there - all the options are open, but what is commonly done is to put at the project root with ns build

I just init-ed a git repos with my project root and commit that crap. Now it runs. uberjar got created. Honestly...... !!!!???!!! I'missing words.... Shouldn't the fact be mentioned in the official guide that tools.deps ONLY FLIES when GIT is involved and you have at least one commit. And what does a repos system have to to with a build system anayway??? I'm puzzled...

✅ 1
Alex Miller (Clojure team) 2026-01-04T21:37:09.194749Z

you're using b/git-count-revs which calls git commands

I believe you are running into an error when trying to name the artifact you will build. If you look at your build script, it will include the number of commits in the artifact name. If there are no commits, or no notion of commits it throws an error

Alex Miller (Clojure team) 2026-01-04T21:37:58.890539Z

so you could just hard-code that to "0.1.0" or something. I will take a look at the guide and see if it could made clearer though

Hey, you both. for a starter: THANKS!! I see that if you call git stuff from code, git is mandatory. makes sense. What does not make sense to me is that this is not mentioned in the guide

👍 1
Alex Miller (Clojure team) 2026-01-04T21:49:10.348069Z

I have updated the guide to not use this and instead included it as an additional example at the end, will be live in a few minutes

🙌 1

My wife just told me all this is a good thing 'cause it will improve the clojure docs & achievements. But the speed now BLOWS ME AWAY. Kudos!!!!!

🎉 4
Alex Miller (Clojure team) 2026-01-04T21:56:23.987979Z

thanks for falling on that sword for us :)

@andre.kuhn And thanks for asking for help and seeing it through!