开发者

How to Call Clojure Code From Java

My professor allowed me to practice both Clojure and Java! I'm definitely using the opportunity and want to have my first Java assignment call some Clojure code. Before I go to the actual assignment, I want to create a simple, working example. I need 开发者_StackOverflow社区your help.

I have read a few links on Java/Clojure interoperability. This, and This.

I will use the first link to demonstrate what I have done so far:

1) I have created a Clojure Project, dumped the .cli file from the site in it and use the export function in Eclipse to export it as a .jar to a folder in my Documents directory.

2) I have created a second Java Project, dumped the java file into it and added the clojure.jar as a referenced library.

Clojure ns:

(ns com.tiny
  (:gen-class
   :name com.tiny
   :methods [#^{:static true} [binomial [int int] double]]))

Java import:

import com.tiny;

The Java file does not recognize com.tiny. I don't know why. The sites mentioned something about a class-path. So I found the classpath editor in eclipse and added the required folder with the .jar to the list of paths. This also did not work.

I don't know what I'm doing wrong. I have referenced the jar, added it to the classpath, and did a complete copy-paste of the code in the first link (besides the package name).

Java code:

import com.tiny;

public class Main {

public static void main(String[] args) {
    System.out.println("(binomial 5 3): " + tiny.binomial(5, 3));
    System.out.println("(binomial 10042, 111): " + tiny.binomial(10042, 111));
    }
}

Clojure code:

(ns com.tiny
  (:gen-class
   :name com.tiny
   :methods [#^{:static true} [binomial [int int] double]]))

(defn binomial
  "Calculate the binomial coefficient."
  [n k]
  (let [a (inc n)]
    (loop [b 1
           c 1]
      (if (> b k)
        c
        (recur (inc b) (* (/ (- a b) b) c))))))

(defn -binomial
  "A Java-callable wrapper around the 'binomial' function."
  [n k]
  (binomial n k))

(defn -main []
  (println (str "(binomial 5 3): " (binomial 5 3)))
  (println (str "(binomial 10042 111): " (binomial 10042 111)))
)


To successfully get your example to run, I did the following:

1) Created a Clojure project in Eclipse 2) Added the file tiny.clj in src/com/tiny.clj 3) Exported that project as a .jar file (e.g.: tiny.jar)

4) Created the Java project as you describe, with one Java file - Main.java 5) Add clojure.jar and tiny.jar to the Java project's classpath. (Right-click -> Configure Build Path -> Libraries Tab -> Add External JARs)

When I initially tried this, I didn't put the tiny.clj file in the com/ directory (I had it directly under src/), and I got a RuntimeException when I tried to run the Main class that said the file tiny.clj and tiny__init.class couldn't be found. Moving the tiny.clj file to the com/ subdirectory fixed the issue for me and Main rain successfully.


An extra link that may be of help on this subject:

  • http://clojurefun.wordpress.com/2012/12/24/invoking-clojure-code-from-java/

The clojure-utils library contains the code needed to call Clojure from Java effectively (without the complexity of using the gen-class approach)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜