Reputation:
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)
Upvotes: 14
Views: 4930
Reputation: 106351
My recommended approach is the following:
.jar
filerequire
a namespace to do this, grab a reference to whatever IFn
you want to call and call the function via IFn.invoke
I recommend this approach because it is generally simpler to add Clojure to a Java project instead of the other way round: this is especially true if you have other developers to consider or are using tools that assume a regular Java project. It's also less scary to managers: all you are doing is using an extra little Java library :-)
I made a small utility library that does a lot of the work required for calling into Clojure from Java that you may find useful:
Upvotes: 2
Reputation: 91534
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 ;)
Upvotes: 11
Reputation: 10662
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).
Upvotes: 2