This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-01-05
Channels
- # announcements (1)
- # babashka (61)
- # babashka-sci-dev (1)
- # beginners (54)
- # biff (17)
- # cider (4)
- # circleci (1)
- # clj-commons (39)
- # clj-kondo (26)
- # cljdoc (40)
- # clojure (41)
- # clojure-europe (32)
- # clojure-norway (4)
- # clojure-portugal (1)
- # clojure-uk (2)
- # clojurescript (59)
- # clr (69)
- # conjure (7)
- # cursive (22)
- # data-science (16)
- # datalevin (1)
- # datomic (19)
- # docker (31)
- # funcool (1)
- # honeysql (6)
- # hoplon (1)
- # hyperfiddle (41)
- # introduce-yourself (1)
- # juxt (2)
- # leiningen (5)
- # nbb (14)
- # nextjournal (38)
- # off-topic (47)
- # polylith (2)
- # rdf (5)
- # re-frame (4)
- # reitit (27)
- # releases (6)
- # scittle (10)
- # shadow-cljs (24)
- # sql (11)
- # squint (1)
- # tools-build (33)
- # tree-sitter (4)
- # vim (39)
So I have tried moving from depstar to tools.build how ever the resulting uberjar returns "Error: Could not find or load main class" I have opened the jar file and checked the src exists I have also checked the manifest has the correct entrypoint. what's my next step to diagnosing why it can't find the class ?
also worth noting I have (gen-class) in dpestar I had :aot true but I have not seen an equivalent in tools.build
You need to include the compile-clj task
Example at https://clojure.org/guides/tools_build#_compiled_uberjar_application_build
Are there classes in the jar?
The build is almost identical to that base example, and the resulting jar file looks good I can see my classes and the libraries.
So I have this in the manifest Main-Class: com.atomjuice.car_cli.core and i can find core.clj at com/atomjuice/car_cli/core.clj
The clj doesn’t matter, only the class (for the main)
So is there a core.class?
Ok, so that’s the cause of the error
next question is why you’re not seeing compile-clj make the class
Is :src-dirs correct there?
(b/compile-clj {:basis basis ; compile clojure code
:src-dirs ["src"]
:class-dir jar-content})
So I do have a question regarding src-dirs is is this relative to where the build.clj runs as the project is a polylith projectIt’s relative to the directory you run the build from by default
so there are src folder all over the place, so my build is in workspace/project/car-cli/build.clj but the the srcs are in workspace/bases/car-cli and worspace/components/foo styles paths
You can change your project context using set-project-root! or (in latest) with-project-root
You need to set :srcs to include any directory where you want everything compiled (there are other options in compile-clj) but the paths are actually defined via the basis, which might already be covering this via :local/root deps
I’ve lost track of what polylith is doing these days so not sure if that covers it
/workspace/component/foo/src/
/workspace/component/bar/src/
/workspace/bases/project/src/
/workspace/project/build.clj
So this is the structure, and as you say the project deps.edn includes all the :local/roots to the componentsI suspect @U04V70XH6 probably has some good advice about this but he won’t be online for a couple hrs
okay, thanks for the awesome help @U064X3EF3 at least I have a better idea of whats going on, I suspected the src-dir folder then dismissed it because it looked like everything was in the jar. before depstar just worked and I did not need to worry about this part so I don't know enough about the construction of jars.
Actually if you omit :src-dirs in compile-clj it will use the paths in the basis and everything else should get compiled transitively so you can probably do that
Assuming you set the project root context
The build task should run in the projects/* folders effectively and just use the basis computed there. I can't provide more details when I get back from vacation (Hawaii) but check my blog posts about Polylith - I may have discussed this in one of them http://corfield.org
I managed to get around it by adding the bases of the project to the build.clj. I have my build in projects/project-name are you saying I would be better of having the build a level up, ie a shared build for all projects ? Hope you enjoyed Hawaii got a working solution but more info would be great, I did look over some of your blog and have used it in the past for other polylith help, not sure it helped with this specific issue.
FWIW we have one build.clj at root of the repo and we bind the tools.build project root to the projects/* folder for each project as we build it. I thought I'd shared that code in one of my blog posts but maybe not...
@UU67HFS2X Here's our uberjar creation code at work:
(doseq [p projects]
(println "\nRunning: uber on" p)
(let [project-dir (str "projects/" p)
aliases (with-dir (io/file project-dir) (get-project-aliases))]
;; ignore any projects that don't build as uberjars:
(when-let [uberjar-opts (:uberjar aliases)]
(binding [b/*project-root* project-dir]
(bb/clean {})
(bb/uber (assoc uberjar-opts :compile-opts {:direct-linking true}))))))
projects
is the sequence of (Polylith) projects to build. Each projects/*/deps.edn
contains an alias called :uberjars
that has :uber-file
and :main
-- so the uber
task knows the JAR file to produce and the main ns to compile. bb
is my build-clj
wrapper for tools.build
but you could easily use tools.build
directly here with maybe some additional default options.
Our build.clj
lives in the workspace root, next to workspace.edn
, and we run builds from that folder:
clojure -T:build uberjars :projects '[api login]'
which would build the api
and login
projects. The key here is the binding
of clojure.tools.build/*project-root*
to the actually project directory. Here's the get-project-aliases
function:
(defn- get-project-aliases []
(let [edn-fn (juxt :root-edn :project-edn)]
(-> (t/find-edn-maps)
(edn-fn)
(t/merge-edns)
:aliases)))
and this is from the :require
in our build
ns:
[clojure.tools.build.api :as b]
[clojure.tools.deps :as t]
[clojure.tools.deps.util.dir :refer [with-dir]]
[org.corfield.build :as bb]
Hopefully, that is everything you need to replicate how we're using tools.build
with Polylith to build uberjars. If not, let's take this discussion to the #C013B7MQHJQ channel.@U04V70XH6 Thanks for taking the time for getting that for me, I will apply the same to mind, may help resolve some of my other issues I have been seeing