5

使用 Java 从 Java 编译 Clojure 是否合法clojure.lang.Compiler.compile

我们的 Java 应用程序过去通过使用clojure.lang.Compiler.load具有proxy宏的 .clj 源来创建 Clojure 对象的实例。现在我们要使用 AOT 编译这些对象,gen-class而不是proxy. 这样就可以移动 .class 文件,然后我们再实例化对象。

到目前为止,我所做的最好的事情就是说服clojure.lang.Compiler.compile我生成加载器类文件(“my/domain/lib__init.class”)。但我似乎没有获得随附的 .class 文件,命名空间中的每个函数一个(“my/domain/lib$fnname__1234.class”)和每个 .class 的存根类文件gen-class。这是使用http://clojure.org/compilation上非常简单的第一个示例的沙箱。我以为我已经正确设置了compile-path,并将其设置为类路径中的某个内容,但也许那里仍然存在问题。

无论如何,我们的实际应用程序是基于 RCP (Eclipse) 的,这可能意味着它们将更多地根据 OSGI 类加载器类路径来计算。与此同时,我只是想知道clojure.lang.Compiler.compile直接使用是否是一种有效的方法?

编辑:所以我现在已经让它产生了所有的 .class 文件,但它需要各种未记录的初始化,这向我表明方法clojure.lang.Compiler是内部的。我必须适当地设置 *compile-path* 并将 *compile-files* 设置为 true,例如

RT.var("clojure.core", "*compile-files*").bindRoot(true);
4

2 回答 2

2

你应该尝试使用clojure.core/compile函数。您还可以查看 lein 如何处理:aot参数以进行aot 编译

于 2013-05-30T04:39:44.617 回答
1

Here is an example of driving the Clojure compiler directly from Java.

        String clojureScript = "(ns user) (def hello (fn [] \"Hello world\"))";
        String notionalScriptFileName="hello.clj";
        String outputDirectory="/my/output/dir";

        Var compilePath = RT.var("clojure.core", "*compile-path*");            
        Var compileFiles = RT.var("clojure.core", "*compile-files*");

        Var.pushThreadBindings(RT.map(compilePath, outputDirectory, compileFiles, Boolean.TRUE));                        
        Compiler.compile(new StringReader(clojureScript), notionalScriptFileName, notionalScriptFileName);
        Var.popThreadBindings();

I've tested this with Clojure 1.4.0... your mileage may vary with other versions.

As the API stands you need to provide a "notional" file name. This only seems to be used to generate the .class file names. The class files it generates are written to the outputDirectory.

于 2013-09-27T14:43:38.153 回答