2
votes

When you create a Clojure project with leiningen all the *.clj-files are compiled AOT. Normally the AOT compilation is not necessary and I would like to minimize it.

This is necessary for me to raise acceptance of Clojure as a complement in a Java-dominated environment. It is easier to "sell" a single class-file as the glue together with a couple of kB clj-files against the alternative of having 250+ kB class-files with strange names and hidden amongst them a little clj-file (which isn't even read any more during execution).

Ideally the result of "lein compile" would be only a single small class file which (together with the clj-files and the clojure-library) implements the needed class-instance.

What is the easiest way to achieve this? I would prefer not to write a single line of Java (of course).

Update after feedback from technomancy

I do not suspect this being a leiningen problem. Let me explain what I am after with an example. Please forgive the length of the example. I am using leiningen 1.3.1 but I think 1.4.0-SNAPSHOOT behaves the same way.

$ lein new dummy
Created new project in: dummy
$ cd dummy

Now change project.clj to (added ":main dummy.core"):

(defproject dummy "1.0.0-SNAPSHOT"
  :description "FIXME: write"
  :dependencies [[org.clojure/clojure "1.2.0"]
                 [org.clojure/clojure-contrib "1.2.0"]]
  :main dummy.core)

and src/dummy/core.clj to:

(ns dummy.core
  (:gen-class))
(defn -main [& args]
  (println "This is Clojure code, args=" args))

Now compile it:

$ lein compile
Compiling dummy.core

This generates the following files in classes/dummy:

core.class
core__init.class
core$loading__4410__auto__.class
core$_main.class

This is all correct, I can execute the result:

$ java -cp lib/*:classes dummy.core Hello
This is Clojure code, args= (Hello)

Now comes what I want to have instead, but I do it manually: I can delete all class-files except core.class and copy the core.clj into classes/dummy which now looks very empty:

$ ls classes/dummy/
core.class
core.clj

The core.class contains code to load the core.clj at runtime and the result is still the same, I still can do:

$ java -cp lib/*:classes dummy.core Hello
This is Clojure code, args= (Hello)

I can also modify core.clj (note: in classes/dummy!) and of course changes do not need to be recompiled.

Now my question boils down to this: Is there an easier way to get just this core.class?

1

1 Answers

4
votes

Leiningen has done no AOT by default for quite some time now; perhaps you have an older version? But there is a new feature (in 1.4.0-SNAPSHOT) that ensures .class files created due to transitive AOT get deleted before jar creation, (see Clojure assembla #322) which may also interest you.