直接调用`clojure.lang.Compiler.compile`到AOT从Java编译Clojure

时间:2013-05-30 02:19:45

标签: clojure

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

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

到目前为止,我所管理的最好的方法是说服clojure.lang.Compiler.compile生成加载器类文件(“my / domain / lib__init.class”)。但我似乎没有得到随附的.class文件,命名空间中的每个函数一个(“my / domain / lib $ fnname__1234.class”)和每个gen-class的存根类文件。这是在沙箱中使用http://clojure.org/compilation上非常简单的第一个例子。我以为我正确设置编译路径,并将其设置为类路径中的某些内容,但可能还存在问题。

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

编辑:所以我现在已经生成了所有的.class文件,但它需要各种未记录的初始化,这告诉我clojure.lang.Compiler上的方法应该是内部。我必须将* compile-path *和* compile-files *设置为true,例如

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

2 个答案:

答案 0 :(得分:2)

您应该尝试使用clojure.core/compile功能。您还可以查看lein如何处理:aot param做aot compilation

答案 1 :(得分:1)

以下是直接从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。