4

私は駆け出しの Clojure プログラマーであり、Eclipse で Java を真っ直ぐ使った経験があります。http://dev.clojure.org/display/doc/Getting+Started+with+Eclipse+and+Counterclockwiseの記事から作成された単純な「hello」関数を Java プログラムに呼び出させようとしています。hello 関数は、反時計回りのプラグインを介して起動された Clojure REPL から正常に機能します。Java クラスから hello 関数を実行しようとすると問題が発生します。

グーグルで調べてみると、これには基本的に 2 つの方法があることがわかります。clojure.lang.RT は Clojure ソースをロードしてスクリプトとして実行するか、Clojure ソースが JAR にコンパイルされたときに直接実行できます。

clojure.lang.RT バリアントは問題なく動作していますが、直接呼び出しバリアントを動作させる方法について完全に途方に暮れています。Java ファイルでは、コンパイラは「myproject.core」を解決できません。

Clojure のソースは core.clj で、次のとおりであり、REPL を通じてチャンピオンのように機能します。

(ns myproject.core
  (:gen-class
    :name myproject.core
    :methods [#^{:static true} [hello [String] String]]))

(defn -main
  "I don't do a whole lot."
  [& args]
  (println "Hello, World!"))

(defn hello [who] (str "Hello " who " !"))

ただし、Java ソースはコンパイルされません。

import java.io.*;
import clojure.lang.*;
public class HelloJava {
    public static void main( String[] args ) {
        loadResourceVariant();
        directVariant();
    }

    public static void directVariant() {
        myproject.core.hello( "Bob" );
    }

    public static void loadResourceVariant() {
        try {
            RT.loadResourceScript( "myproject/core.clj" );
            // Get a reference to the hello function.
            Var hello = RT.var( "myproject.core", "hello" );
            // Invoke the hello function
            Object result = hello.invoke( "Robert" );
            System.out.println( result );
        } catch ( IOException e ) {
            e.printStackTrace();
        }
    }
}

コンパイルエラーは...

myproject.core cannot be resolved to a type HelloJava.java  /myproject/src  line 11 Java Problem

Java から直接参照できるように、core.clj の .class 表現を classes ディレクトリに配置するように反時計回りのプロジェクトを構成するにはどうすればよいですか?

これは、完全な Maven などに移行しなくても可能でなければなりません。いいえ?

4

2 に答える 2

0

Java から clojure を呼び出す方法は、API 名前空間を作成することです。これは通常、実装する名前空間から分離されています。

(ns test.api
  (:use [test.impl :only [f1 f2]])
  (:gen-class
    :methods [#^{:static true} [exportedF1 [String] int]
              #^{:static true} [exportedF2 [String String] void]]))

(defn -exportedF1 [^String query ^String file] (f1 query file))
(defn -exportedF2 [^String query] (f2 query))

次に、その名前空間をAOTし、それをuberjarするようにします。

その jar を Java クラスパスに含めるだけで、準備完了です。

于 2013-05-29T13:46:24.170 に答える