Monday, March 14, 2011

Clojure & Leiningen in a Java Project

These days I've been busy with other stuff to do (including but not limited to some logistics and fixing a couple of papers); however, these morning, I picked up my good old mixed java/clojure project to port it with leiningen.I'm pretty happy with IntelliJ build system, but I needed some more flexibility.

There are some interesting issues with the project:

  1. it has both Java and Clojure files
  2. it has both aot and regular Clojure files
  3. it depends from lots of different Jars
  4. it depends from a "private library" which has not been (and cannot be) placed under publicly available repositories right now

The idea is that: Java code does not explicitly depend on clojure anymore. It is safe to compile Java before clojure; this is a major upgrade from (this and this and made things easier). On the other hand I have some "utility" clojure files which have not to explicitly aot compiled, but are required by the aot compiled sources. And I have some wrapper clojure scripts which depend on everything and is also compiled but it does not give any trouble, apparently.

To give an idea, this is the project:

I also installed lein-javac, even though I'm not sure it is needed. However, I can compile the Java code and that is fine. That was the easy part. And using "official" jar files was also easy Moreover, since interactions from aot compiled and regular clojure code did not give me any issues that is the state:

  1. it has both Java and Clojure files
  2. it has both aot and regular Clojure files
  3. it depends from lots of different Jars
  4. it depends from a "private library" which has not been (and cannot be) placed under publicly available repositories right now

Unfortunately, it seems to me that lein does not detect dependencies among aot compiled sources. That is to say, I have to manually order the files in the correct order. I hope that I just missed some lein feature, because this is just crazy. My first idea was that I could compile all the namespaces that contained all aot compiled code (I structured the project because of that). Apparently, it works; however if the compilation does not take place in the correct order, it does not work. Please, someone tell me I'm wrong. Someone told me and today with a simpler regular expression everything worked. Basically I'm not excluding files which are not required to be aot compiled from aot compilation. I just compile everything and that's it.

The only "problem" was dependency from a proprietary jar file we are developing. I found out that simply placing it in the deps was not enough as the directory is often removed and recreated. I put up a kludge:

Now everything kind of works. I'm not sure it's an improvement over the IntelliJ variant. I can use Emacs+swank (which is good), but I have a tricky "manual" step if I want to add aot compiled files. Besides, since there is a lot of setup to run the project, I'm not even sure that swank is a huge advantage, as I could only use it to run snippets "outside" the core.

So essentially it boils down to whether I prefer Emacs or IntelliJ for this project. Being heavily framework based, exploratory programming is rather hard to do, which removes some appeal from slime, as LaClojure REPL is adequate. Moreover, I prefer IntelliJ on pure Java (and I have some) and it seems to better autocomplete Java stuff (e.g., in the :import sections). So perhaps the trick is IntelliJ+LaClojure+Leiningen.

Technorati Tags:,, ,

Post a Comment