java 怎么调用clojure_从java调用Clojure

自从发表这一答复以来,一些可用的工具发生了变化。在最初的答案之后,有一个更新,包括有关如何用当前工具构建示例的信息。

它并不像编译JAR和调用内部方法那样简单。不过,似乎确实有一些小窍门可以让这一切发挥作用。下面是一个可以编译到JAR中的简单Clojure文件的示例:(ns com.domain.tiny  (:gen-class

:name com.domain.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))))

如果你运行它,你应该看到这样的东西:(binomial 5 3): 10(binomial 10042 111): 49068389575068144946633777...

下面是一个Java程序,它调用-binomial函数中的tiny.jar.import com.domain.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));

}}

它的输出是:(binomial 5 3): 10.0(binomial 10042, 111): 4.9068389575068143E263

第一个魔法是使用:methods关键字中的gen-class声明。这似乎是允许您访问Clojure函数(类似于Java中的静态方法)所必需的。

第二件事是创建一个可以由Java调用的包装器函数。注意,第二个版本的-binomial前面有个破折号。

当然,Clojure JAR本身必须在类路径上。这个例子使用了Clojure-1.1.0 JAR。

更新使用以下工具重新测试了这个答案:Clojure 1.5.1

莱宁根2.1.3

JDK 1.7.0更新25

克洛尔部分

首先,使用Leiningen创建一个项目和相关目录结构:C:\projects>lein new com.domain.tiny

现在,切换到项目目录。C:\projects>cd com.domain.tiny

在项目目录中,打开project.clj文件并编辑它,以便内容如下所示。(defproject com.domain.tiny "0.1.0-SNAPSHOT"

:description "An example of stand alone Clojure-Java interop"

:url "http://clarkonium.net/2013/06/java-clojure-interop-an-update/"

:license {:name "Eclipse Public License"

:url "http://www.eclipse.org/legal/epl-v10.html"}

:dependencies [[org.clojure/clojure "1.5.1"]]

:aot :all  :main com.domain.tiny)

现在,确保所有依赖项(Clojure)都可用。C:\projects\com.domain.tiny>lein deps

此时您可能会看到一条关于下载Clojure JAR的消息。

现在编辑Clojure文件C:\projects\com.domain.tiny\src\com\domain\tiny.clj这样,它就包含了原来答案中显示的Clojure程序。(此文件是在Leiningen创建项目时创建的。)

这里的许多神奇之处在于名称空间声明。这个:gen-class告诉系统创建一个名为com.domain.tiny使用一个名为binomial一个函数,使用两个整数参数并返回一个Double。有两个类似命名的函数binomial,一个传统的Clojure函数,以及-binomial以及从Java访问的包装器。注意函数名称中的连字符-binomial..默认前缀是连字符,但如果需要,可以更改为其他前缀。这个-main函数只对二项式函数进行几次调用,以确保我们得到了正确的结果。为此,编译类并运行程序。C:\projects\com.domain.tiny>lein run

您应该看到原始答案中显示的输出。

现在把它装在一个罐子里,放在一个方便的地方。在那里也复制Clojure的罐子。C:\projects\com.domain.tiny>lein jarCreated C:\projects\com.domain.tiny\target\com.domain.tiny-0.1.0-SNAPSHOT.jar

C:\projects\com.domain.tiny>mkdir \target\lib

C:\projects\com.domain.tiny>copy target\com.domain.tiny-0.1.0-SNAPSHOT.jar target\lib\

1 file(s) copied.C:\projects\com.domain.tiny>copy "C:\clojure-1.5.1.jar" target\lib\        1 file(s) copied.

Java部分

莱宁根有一个内置的任务,lein-javac,这应该有助于Java编译。不幸的是,它似乎在2.1.3版本中被破坏了。它找不到已安装的JDK,也找不到Maven存储库。两者的路径都在我的系统中嵌入了空间。我想这就是问题所在。任何JavaIDE也可以处理编译和打包。但对于这篇文章,我们是老生常谈,在命令行做这件事。

首先创建文件Main.java内容显示在原来的答案中。

编译java部件javac -g -cp target\com.domain.tiny-0.1.0-SNAPSHOT.jar -d target\src\com\domain\Main.java

现在创建一个文件,其中包含一些要添加到我们要构建的JAR中的元信息。在……里面Manifest.txt,添加以下文本Class-Path: lib\com.domain.tiny-0.1.0-SNAPSHOT.jar lib\clojure-1.5.1.jarMain-Class: Main

现在,将其打包到一个大JAR文件中,包括我们的Clojure程序和Clojure JAR。C:\projects\com.domain.tiny\target>jar cfm Interop.jar Manifest.txt Main.class lib\com.domain.tiny-0.1.0-SNAPSHOT.jar lib\clojure-1.5.1.jar

要运行该程序:C:\projects\com.domain.tiny\target>java -jar Interop.jar(binomial 5 3): 10.0(binomial 10042, 111): 4.9068389575068143E263

输出与Clojure单独生成的输出本质上是相同的,但结果已经转换为Java双重。

如前所述,JavaIDE可能会处理混乱的编译参数和打包。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值