【问题标题】:Directly calling `clojure.lang.Compiler.compile` to AOT compile Clojure from Java直接调用`clojure.lang.Compiler.compile`从Java AOT编译Clojure
【发布时间】:2013-05-30 02:19:45
【问题描述】:

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

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

到目前为止,我所做的最好的事情是说服 clojure.lang.Compiler.compile 为我生成加载器类文件(“my/domain/lib__init.class”)。但我似乎没有获得随附的 .class 文件,命名空间中的每个函数(“my/domain/lib$fnname__1234.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);

【问题讨论】:

    标签: clojure


    【解决方案1】:

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

    【讨论】:

    • 我相信 Ankur 的建议是直接从 Java 中调用clojure.core/compileRT.var("clojure.core", "compile").invoke(...)。与尝试使用 clojure 的 Java 内部结构相比,从 Java 中获取 var 并执行它们更不容易出错,也更不容易混淆。如果我没记错的话,这就是 Datomic Java API 的实现方式。
    • @DaveRay:是的,这就是我从 java 调用它的意思
    【解决方案2】:

    这是一个直接从 Java 驱动 Clojure 编译器的示例。

            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();
    

    我已经用 Clojure 1.4.0 对此进行了测试...您的里程可能会因其他版本而异。

    就 API 而言,您需要提供一个“名义”文件名。这似乎只用于生成 .class 文件名。它生成的类文件被写入到 outputDirectory 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-01
      • 2018-03-08
      • 2011-05-03
      • 2015-05-14
      • 2017-04-15
      • 1970-01-01
      • 2016-04-15
      • 1970-01-01
      相关资源
      最近更新 更多