Leiningen erro de compilação com arquivos Java que fazem referência a classes geradas de arquivos Clojure
-
27-10-2019 - |
Pergunta
Tenho um projeto Leiningen que está compilando arquivos Java e Clojure.Os arquivos Java importam algumas das classes que são geradas a partir dos arquivos Clojure (com gen-class).
Quando faço a compilação do lein, obtenho erros de compilação nas importações dos arquivos Java (dizendo que não foi possível encontrar as classes).Se eu remover os arquivos Java do projeto, fazer a compilação do lein, adicionar os arquivos Java de volta e fazer a compilação do lein novamente, tudo funcionará bem.
Então, é como se os arquivos Clojure precisassem ser compilados antes dos arquivos Java.
A propósito, estou incluindo os arquivos Clojure que geram classes na lista: aot.
O que está errado aqui?
Solução
(O código nesta resposta não foi testado, embora deva funcionar com Leiningen 1.x (para valores recentes de x).)
A tarefa compile
de Leiningen executa a tarefa javac
automaticamente se o seu project.clj
especifica um :java-source-path
. Isso é feito antes de compilar as fontes do Clojure, porque suponho que essa seja a direção usual da dependência.
Para contornar isso, você pode usar um gancho:
;;; 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)
Coloque isso em algum lugar no seu classpath de tempo de construção e adicione
:hooks [clj-first-hook]
para o mapa do seu projeto.
Observe que javac
, quando chamado diretamente, ainda não chamará compile
. Você também pode torná-lo equivalente a compile
, por exemplo conectando-o com a seguinte função:
(defn javac-hook [javac-task project]
(if (project ::clj-compiled?)
(javac/javac project)
(leinc/compile project)))
A última forma de compile-clj-first-hook
precisaria ser
(javac/javac (assoc project ::clj-compiled? true))
(Fazer com que compile
não chame javac
provavelmente quebraria jar
/ uberjar
.)