[英]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.