Leiningen编译Java文件时出错,这些文件引用了从Clojure文件生成的类。

3
我有一个Leiningen项目,它同时编译Java和Clojure文件。 Java文件导入一些从Clojure文件生成的类(使用gen-class)。
当我运行lein compile时,Java文件中的导入会出现编译错误(说找不到这些类)。如果我从项目中删除Java文件,然后运行lein compile,再将Java文件添加回来并重新运行lein compile,一切都正常工作。
所以,似乎需要在编译Java文件之前编译Clojure文件。
顺便说一下,我在:aot列表中包含了生成类的Clojure文件。
这里出了什么问题?

1
可能现在对你没有帮助,但我发现通常更容易让Clojure依赖于Java,避免反过来的依赖。并且请注意,在多语言项目中出现循环依赖会特别棘手… - mikera
你最终解决了这个问题吗?我也遇到了基本相同的问题,正在尝试在这里解决它。 - kwenholz
我不记得说实话。 - Paul Reiners
1个回答

4

(这个答案中的代码未经测试,不过它应该可以与Leiningen 1.x(x的最新值)一起使用。)

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

为了解决这个问题,你可以使用一个hook:

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

你能否帮忙审查一下我尝试将你的解决方案作为插件实现在这个问题中的代码?我不太清楚你建议的代码应该放在哪里。(我对构建工具非常陌生)。谢谢! - kwenholz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接