4

我是一个初出茅庐的 Clojure 程序员,在 Eclipse 中使用过直接的 Java。我正在尝试让我的 Java 程序调用从http://dev.clojure.org/display/doc/Getting+Started+with+Eclipse+and+逆时针文章创建的简单“hello”函数。hello 函数在通过逆时针插件启动的 Clojure REPL 中运行良好。当我尝试从 Java 类执行 hello 函数时出现问题。

谷歌搜索发现基本上有两种方法可以做到这一点: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

如何配置我的逆时针项目以将 core.clj 的 .class 表示放入 classes 目录,以便可以直接从 Java 引用它?

这必须在不使用 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 回答
0

我认为用户 clartaq 在这里回答了您的问题:Calling clojure from java

总结一下 - 如果您想将 Clojure 函数导出到 Java,请按照以下步骤操作:

  1. 使用完全限定名称创建项目;例如,lein new com.example.stuff而不仅仅是 of lein new stuff
  2. 编写一个“包装函数”;例如-foo,如果您的函数被调用foo
  3. 扩展(ns ...)文件顶部的表单以导出函数
  4. 编辑您的project.clj文件以触发 AOT 编译
  5. 构建一个 uberjar 文件。

如果您想了解我是如何应用这种方法的,请查看我的GitHub 页面。

于 2020-06-20T22:54:23.490 回答