Thomas Skardal

Hello, computer.

Making an uberjar containing ClojureScript artifacts

January 4, 2015

I’ve been playing around with ClojureScript lately. The other day I wanted to make an uberjar so that I could easily deploy my app as a standalone jar file. It turned out that I had skipped some documentation on this subject.

I’m using lein-cljsbuild to compile my .cljs files into JavaScript. As I’m using a mix of both Clojure (server side) and ClojureScript (client side) I have split my src directory into src/clj and src/cljs. This gave me some headache when trying to run the application using lein run:

java.io.FileNotFoundException: Could not locate battlesnake/server__init.class or battlesnake/server.clj on classpath

The cause of this is of course the new directory layout in src, and the solution is simple. Add :source-paths ["src/clj"] to your project.clj.

Next problem: why doesn’t the uberjar contain any of my compiled ClojureScript? While programming I’ve had lein cljsbuild auto running. This keeps all my .cljs files compiled at all times. When compiling and packaing the uberjar, cljsbuild is not part of the workflow. You can read the details here.

You need this in your project.clj:

:hooks [leiningen.cljsbuild]
:cljsbuild {:builds
            [{;; ...
              :jar true
              ;; ...
              }]}

That’s it. Now the uberjar is both runnable and contains the compiled ClojureScript!