Error de compilación de Leiningen con archivos Java que hacen referencia a clases generadas a partir de archivos Clojure

StackOverflow https://stackoverflow.com/questions/9336202

Pregunta

Tengo un proyecto de Leiningen que está compilando archivos Java y Clojure.Los archivos Java importan algunas de las clases que se generan a partir de los archivos Clojure (con gen-class).

Cuando hago la compilación de lein, obtengo errores de compilación en las importaciones en los archivos de Java (diciendo que no puede encontrar las clases).Si elimino los archivos Java del proyecto, hago la compilación de lein, vuelvo a agregar los archivos de Java y vuelvo a compilar lein, todo funciona bien.

Entonces, es como si los archivos de Clojure tuvieran que compilarse antes que los archivos de Java.

Por cierto, estoy incluyendo los archivos Clojure que generan clases en la lista: aot.

¿Qué va mal aquí?

¿Fue útil?

Solución

(El código de esta respuesta no está probado, aunque es de esperar que funcione con Leiningen 1.x (para valores recientes de x).)

La tarea compile de Leiningen ejecuta la tarea javac automáticamente si su project.clj especifica un :java-source-path. Lo hace antes de compilar las fuentes de Clojure, porque supongo que esa es la dirección habitual de la dependencia.

Para evitar esto, puede usar un 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 esto en algún lugar de su ruta de clases en tiempo de compilación y agregue

:hooks [clj-first-hook]

al mapa de su proyecto.

Tenga en cuenta que javac, cuando se llama directamente, todavía no llamará compile. También puede hacerlo equivalente a compile, p. Ej. enganchándolo con la siguiente función:

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

La última forma de compile-clj-first-hook debería ser

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

(Hacer compile no llamar a javac en absoluto probablemente rompería jar / uberjar.)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top