leiningen

N.B. The maintainers are on #leiningen on Libera chat IRC. Go there for direct support/bug reports.
grazfather 2021-04-25T01:31:07.088200Z

Hey guys, I am building an uberjar with lein and later trying to run it, but I am getting an issue with “Could not find or load main class”. How is the main class determined? I have one namespace, and my profile sets it for :main

grazfather 2021-04-25T16:00:18.088500Z

(defproject mal "0.1.0-SNAPSHOT"
  :description "x"
  :dependencies [[org.clojure/clojure "1.10.1"]
                 [net.n01se/clojure-jna "1.0.0"]]
  :repl-options {:init-ns mal.core}
  :profiles {:step0 {:main mal.step0-repl
                     :uberjar-name "step0_repl.jar"
                     :aot [mal.step0-repl]}})

2021-04-26T01:01:14.089700Z

You define your uberjar details in a custom profile

2021-04-26T01:01:31.090300Z

So you’d have to specify that lein with-profile step0 uberjar

2021-04-26T01:01:43.090900Z

Or use the built in automatically included profile :uberjar

grazfather 2021-04-26T13:18:51.091300Z

I did invoke it that way

gklijs 2021-04-26T22:15:14.091700Z

Do you have a '-main' function in that namespace?

grazfather 2021-04-26T22:34:06.091900Z

Yes

grazfather 2021-04-26T22:34:37.092100Z

and it runs as expected with lein with-profile step0 run

grazfather 2021-04-26T22:36:52.092300Z

$ lein with-profile step0 run
OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.
user> test
user>$ lein with-profile step0 uberjar
OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.
Compiling mal.step0-repl
Warning: The Main-Class specified does not exist within the jar. It may not be executable as expected. A gen-class directive may be missing in the namespace which contains the main method, or the namespace has not been AOT-compiled.
Created /Users/g/code/mal/impls/myclj/target/mal-0.0.1-SNAPSHOT.jar
Created /Users/g/code/mal/impls/myclj/target/step0_repl.jar
$ java -jar ./target/step0_repl.jar
Error: Could not find or load main class mal.step0_repl
Caused by: java.lang.ClassNotFoundException: mal.step0_repl

grazfather 2021-04-27T01:01:58.092500Z

It’s because my ns didn’t have (:gen-class) in it.

👍 3
2021-04-27T17:36:31.093Z

consider that you can skip :gen-class or :aot, and use clojure.main as your entry point

grazfather 2021-04-28T16:30:43.093300Z

Sorry, I don’t understand what you mean. Do you mean in my invocation of the jar? What would that look like?

2021-04-28T16:31:42.093500Z

java -cp my.jar clojure.main -m my.ns

2021-04-28T16:32:12.093700Z

an advantage here is that you can also run a repl (leave out the -m arg) and any number of namespaces can have a runnable -main

2021-04-28T16:32:45.093900Z

(and you don't have a language feature that you use in prod but not during dev)

grazfather 2021-04-28T16:33:02.094100Z

cool, I will want that, since each of my profiles have their own main. At work right now, but will try that out later. Thank you!

grazfather 2021-04-28T16:33:48.094300Z

so is it that gen-class means turn a namespace into a java cjass, and i don’t need that if i get the clojure.main class to instead load/invoke the namespace?

💯 1
2021-04-28T16:33:49.094500Z

this also works by having gen-class / -main in multiple namespaces, but I think just using clojure.main is simpler over all

2021-04-28T16:34:00.094700Z

that's exactly it, cheers

grazfather 2021-04-28T16:34:05.094900Z

🙏

2021-04-25T06:17:10.088300Z

Can you post your project.clj