tags:

views:

274

answers:

2

How can I take a large existing Java project and start to add Clojure modules? For example, in the code below, I'd like to make the following functions available in Java: state?, zip?, state-list, zipcode-list. The two predicates will return a boolean, but the "getters" will return arrays.

(def *states* (list "NJ" "NY" "CA"))
(def *zipcodes*  (list 12345 54343 98765))

(defn member [x sq]
  (if (seq sq)
    (if (= x (first sq))
      sq
      (recur x (rest sq)))))

(defn state? [aState]
  (not (= (member aState *states*) nil)))

(defn zip? [aZip]
  (not (= (member aZip *zipcodes*) nil)))

(defn state-list []
  *states*)

(defn zipcode-list []
  *zipcodes*)
;; ---------------
(state? "AA")
(state? "CA")
(zip? 11111)
(zip? 12345)
+4  A: 

I would compile it using leiningen then add the jar file to my java project as a build dep. Here is a great video on using leiningen. then you would call it directly from java. Leiningen has an uberjar option that bulds in clojure and all your clojure dependencies so you only have to worry about one file. I like this because its less work.

A more java friendly approach would be to add an ant task to build it along with the java project its just a little more work

for the functions that need to return proper java arrays call to-array on them

contrary to many of the top "calling clojure from java" hits you should not need to call the clojure runtime RT.

PS: my favorite tag line "I would like to use a java library called clojure" I asked Rich he said this was cool ;)

Arthur Ulfeldt
I looked at the leiningen README but I didn't see anything that explains this. Know of any blogs, etc. that can explain this in some detail? How will my lists be returned to Java, for example?
you convert the clojure vector to a java list with <code>to-list</code> and return it from the function. more here: http://clojure.org/java_interop#toc27
Arthur Ulfeldt
I do think the nets are lacking in explanations on this.
Arthur Ulfeldt
this is decent: http://blog.objectmentor.com/articles/2009/08/07/java-calling-clojure
Arthur Ulfeldt
I think the question How do I call clojure from java" is different from "how to i integrate clojure with my java project.
Arthur Ulfeldt
I tried to ask the general question that I think many people are going to face. Imagine a large Java project (eg. >100k lines) and someone wants to start using Clojure in it. I want the answer to this question to be found here. Let's save everyone else from hours of Google'ing, testing, and scratching their heads.
Still googling and scratching my head here. Looks like it can be forcibly used with a Java project, but nothing that yet resembles clean integration to me.
Brian Knoblauch
A: 

It is easier to take an existing Java application and wrap it in Clojure than the other way around, because Java interop from Clojure is very simple.

As you are asking how to access Clojure from Java, the answer is that you either need to bootstrap load Clojure code, or you need to generate Java class files that can be used from your Java project. Bootstrapping involves linking to the clojure jar and accessing the load function to load clojure source. To generate Java classes look into AOT (see example on the website).

Timothy Pratley
I doubt if many people have the option of turning a legacy Java project into a "Clojure" project. The only realistic solution is to be able to let the team continue in Java and allow for part of the project to be done in Clojure, making that fact that you are using Clojure somewhat transparent.
Actually I have the exact opposite opinion :) Think of it in terms of Python/C++, people have plenty of legacy C++ wrapped up in Python... not so much C++ legacy apps calling out to Python.
Timothy Pratley
Lisp is a much harder sell than Python.