Leiningen使用引用Clojure文件生成的类的Java文件编译错误

时间:2012-02-17 22:14:31

标签: java compilation clojure interop leiningen

我有一个正在编译Java和Clojure文件的Leiningen项目。 Java文件导入从Clojure文件生成的一些类(使用gen-class)。

当我编译lein时,我在Java文件中导入编译错误(说它找不到类)。如果我从项目中删除Java文件,请进行lein编译,重新添加Java文件,再次编译lein,一切正常。

因此,就像在Java文件之前需要编译Clojure文件一样。

顺便说一下,我在以下列表中包含了gen类的Clojure文件。

这里出了什么问题?

1 个答案:

答案 0 :(得分:4)

(这个答案中的代码未经测试,尽管它应该与Leiningen 1.x一起使用(最近的x值)。)

如果您的compile指定javac,则Leiningen的project.clj任务会自动运行:java-source-path任务。它在编译Clojure源之前就这样做了,因为我认为这是依赖的通常方向。

要解决这个问题,你可以使用一个钩子:

;;; in leiningen.hooks.clj_first.clj

(ns leiningen.hooks.clj-first
  (:require [leiningen.compile :as leinc]
            [leiningen.javac :as javac]))

(defn compile-clj-first-hook [compile-task project & args]
  (apply compile-task
         (dissoc project :java-source-path)
         args))
  (javac/javac project))

(add-hook #'leiningen.compile/compile compile-clj-first-hook)

将它放在构建时类路径上并添加

:hooks [clj-first-hook]

到您的项目地图。

请注意,javac在直接调用时仍然不会调用compile。您也可以将其等同于compile,例如通过以下功能挂钩:

(defn javac-hook [javac-task project]
  (if (project ::clj-compiled?)
    (javac/javac project)
    (leinc/compile project)))

compile-clj-first-hook的最后一种形式需要

(javac/javac (assoc project ::clj-compiled? true))

(根据compile 而不是调用javac可能会导致jar / uberjar中断。)