[解決済み] javaからclojureを呼び出す
質問
Googleで検索すると、quot;calling clojure from java"のトップヒットのほとんどは古く、次のものを使うことを推奨しています。
clojure.lang.RT
を使用してソースコードをコンパイルしてください。Clojureプロジェクトからjarをビルドし、クラスパスに含めたと仮定して、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...
そして、以下はその
-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
ステートメントを使用します。これは、Javaの静的メソッドのようにClojure関数にアクセスできるようにするために必要なようです。
2つ目は、Javaから呼び出せるラッパー関数を作ることです。第二のバージョンは
-binomial
は、前にダッシュを付けています。
そしてもちろん、Clojureのjar自体がクラスのパス上になければなりません。この例ではClojure-1.1.0 jarを使用しています。
更新情報 : この回答は、以下のツールを使用して再テストされました。
- Clojure 1.5.1
- ライニンゲン 2.1.3
- JDK 1.7.0 Update 25
Clojureの部分
まず、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プログラムを含むようにします。(このファイルはライニンゲンがプロジェクトを作成したときに作成されたものです。)
ここでのマジックの多くは、名前空間宣言にある。この宣言は
:gen-class
という名前のクラスを作成するようにシステムに指示します。
com.domain.tiny
という静的メソッドを1つ持ち
binomial
この関数は、2つの整数の引数を取り、doubleを返す。同じような名前の関数が2つある
binomial
従来のClojureの関数である
-binomial
とJavaからアクセスできるラッパーです。関数名のハイフンに注意
-binomial
. デフォルトの接頭辞はハイフンですが、必要に応じて他のものに変更することができます。その場合
-main
関数は、正しい結果を得るために二項関数を何回か呼び出すだけです。そのためには、クラスをコンパイルして、プログラムを実行します。
C:\projects\com.domain.tiny>lein run
元の答えにあるような出力が表示されるはずです。
今度はこれをjarにパッケージして、どこか便利な場所に置いてください。Clojureのjarもそこにコピーしてください。
C:\projects\com.domain.tiny>lein jar
Created 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:<path to clojure jar>\clojure-1.5.1.jar" target\lib\
1 file(s) copied.
Javaパート
ライニンゲンにはタスクが組み込まれています。
lein-javac
これは、Javaのコンパイルを助けることができるはずです。残念ながら、バージョン2.1.3では壊れているようです。インストールされたJDKが見つからず、Mavenのリポジトリも見つかりません。私のシステムでは、両方へのパスにはスペースが埋め込まれています。私はそれが問題であると仮定します。どんなJava IDEでも、コンパイルとパッケージングを処理することができます。しかし、この記事では、古い学校に行って、コマンドラインでそれを行うことにします。
まず、ファイルを作成します。
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.jar
Main-Class: Main
さて、ClojureプログラムとClojure jarを含めて、すべてを1つの大きな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のdoubleに変換されています。
前述したように、面倒なコンパイル引数やパッケージングは、おそらくJava IDEがやってくれるでしょう。
関連
-
Spring BootのテストメソッドFailed to load ApplicationContextの問題を解決する
-
アイデア Springboot Web プロジェクトを jar にパッケージ化する場合、Error: 無効または破損した jarfile x.jar 解決策
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] 配列からArrayListを作成する
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] Java で、あるコンストラクタを別のコンストラクタから呼び出すにはどうすればよいですか?
-
[解決済み】Javaの「ダブルブレース初期化」の効率化?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
エラー java.util.NoSuchElementException
-
スタイルが読み込まれず、ブラウザコンソールでエラーが報告される。リソースはスタイルシートとして解釈されますが、MIMEタイプtext/htmlで転送されます。
-
スタイルが読み込まれず、ブラウザのコンソールでエラーが報告される。リソースはスタイルシートとして解釈されますが、MIMEタイプtext/htmlで転送されます。
-
Java Exceptionが発生しました エラー解決
-
java Mail send email smtp is not authenticated by TLS encryption solution.
-
マスキング このリソースにアクセスするには、完全な認証が必要です。
-
アイデア Springboot Web プロジェクトを jar にパッケージ化する場合、Error: 無効または破損した jarfile x.jar 解決策
-
JSPで「リストが型解決できない!」の解決方法
-
IDEA パッケージステートメントの欠落
-
java -serverコマンドで「Error: no `server' JVM at ... jvm.dll」を解決する方法です。