I'm having difficulty referencing classes generated via :gen-class
.
The smallest example I can show that demonstrates the problem is:
(defproject test-proj
:dependencies [[org.clojure/clojure "1.8.0"]]
:aot [test-proj.test])
(ns test-proj.test
(:gen-class))
(defn -main []
(println test_proj.test)) ; Error here
The problem is, this yields a ClassNotFoundException
on the marked line.
(I tried all different combinations of -
and _
in the above file and the project.clj
. I still don't fully understand what requires an underscore and what tolerates a dash. Some things seem to roll with dashes and convert them as needed, whereas I know from messing around that in the -main
, I need underscores to reference test_proj.test
.)
If I go into the project root file, there's no target
folder, so it's not generating the class. If I go into the terminal and run lein compile
, it generates the needed classes under target
, and the above code runs without error. This is a poor workaround though. What if I modify the file and forget to manually recompile it? It's also a pain to have to manually compile it after any time I do a clean
.
As a shot in the dark, I tried using compile
right underneath the ns
macro:
(compile 'test-proj.test)
If I uses dashes, compile
seems to do literally nothing. I may be misinterpreting its use, but it doesn't generate class files under target
. If I use underscores, it gives an exception saying that the namespace isn't found.
Is there a way to have the classes generated automatically so I don't need to run lein compile
everytime? I thought that that's what the :aot
in the project.clj
did.
With Leiningen, specify :aot settings. :all is the easiest.
project.clj
If you want, you can specify the exact namespaces in an array as seen below:
project.clj
Then the following lein command:
Will generate the byte code and .class files as specified in the :aot settings above.
core.clj
You want to see something like the below:
Once this is done, check the target folder, contains the proper class file, here test_proj/core.class.
The following will run the :main namespace, so test-proj.core.
Will output
Note, that the class is calling itself. Note also that if you do not run lein compile beforehand , it will run by itself.