[英]How can I export a Java class (.jar) from Clojure?
我是Clojure和Java的新手。 我有一个现有的Clojure项目,其他人写道我试图使用node-java嵌入NodeJS。
Clojure的
该项目定义了一个提供某些公共函数的命名空间,如下所示:
(ns my.namespace
(:require ...etc...))
(defn dosomething ...)
(defn dosomethingelse ...)
我用leiningen( lein jar
和lein uberjar
)建造了这个项目。
问题
node-java上的#import()文档说我需要像这样导入一个java类:
const java = require('java');
var Test = java.import('Test');
更新
感谢Magos(以下回答),我取得了一些进展。 事实证明,我可以在(ns ...)
范围内使用(:gen-class :name my.name)
来告诉它生成一个类。 如果我向project.clj添加一个配置文件,如下所示:
...
:profiles {
...
:uberjar {:aot :all}
}
...
它将编译,我现在可以看到Node中的类。 不过,我仍然没有想出如何导出这些方法。 现在正在努力工作。
由于其他人写了Clojure,我会假设你无法控制它。 从另一种JVM语言使用Clojure代码的推荐方法是从类clojure.java.api.Clojure
引导。 此类允许您从Clojure解析Vars,通过解析和调用其他核心Clojure函数,您可以加载自己的代码。 根据您的示例,它可能看起来像这样:
const java = require('java');
var clojure = java.import('clojure.java.api.Clojure');
IFn require = clojure.var("clojure.core", "require");
require.invoke(clojure.read("my.namespace"));
IFn doSomething = clojure.var("my.namespace","dosomething");
//doSomething.invoke(....
如果你确实控制了Clojure,那么:gen-class
允许你将函数导出为命名空间生成的类的方法 。
注意:我通过结合Magos的回答和clartaq对该问题的评论来达到这个目的。
以下是如何操作的简单说明。 假设你有这个(简单的)clojure代码:
(ns my.namespace
"a trivial library"
(:require [something.else :as other]))
(defn excite
"make things more exciting"
[mystr]
(print-str mystr "!"))
使用这些步骤来公开excite
方法。
使用相同的签名创建方法的公开版本,方法是在其前面加上-
。 它应该只是调用你想要公开的函数。
(defn -excite [mystr] (excite mystr))
在(ns ...)
中声明要生成类和导出方法。
(ns my.namespace "a trivial library" (:require [something.else :as other]) (:gen-class :name my.classname :methods [ ; metadata mtd.name signature returns #^{:static true} [excite [String] void] ]))
请注意,如果您不希望将此作为静态方法提供,则可以选择删除#^{:static true}
。
在您的project.clj中(假设您正在使用leiningen),将以前的编译说明添加到您的:profiles
条目:
:profiles {:uberjar {:aot :all}}
编译你的uberjar:
lein uberjar
生成的.jar
文件将有一个类my.classname
其中包含静态方法excite
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.