Quiero usar el procesador de anotaciones QueryDSL como parte de mi proceso de compilación. ¿Cómo puedo deshacerme de la compilación y ejecución innecesarias del procesador de anotaciones cada vez que cambio una clase? Quiero que QueryDSL genere clases Q- * solo si se cambian algunas clases relacionadas.

Este procesador de anotación siempre en ejecución tiene un impacto negativo en nuestro tiempo de proceso de compilación y parece que la construcción incremental no funciona si el procesador de anotación tiene que ejecutarse.

Gracias.

3
lukyer 14 nov. 2017 a las 18:26

3 respuestas

La mejor respuesta

Gradle no puede saber qué archivos usan los procesadores de anotaciones como entrada , por lo que debe activar la recompilación completa cada vez que algo en el directorio observado cambia (src).

Sin embargo, puede decirle fácilmente a Gradle qué archivos solo deberían activar el procesamiento de anotaciones. Cambiar a otros archivos no activará el uso de procesadores de anotaciones y Gradle puede usar toda su potencia (por ejemplo, compilaciones incrementales).

También agregué la tarea "forzar" buildWithAP llamando a los procesadores de anotaciones independientemente del resultado de la función de pista (heurística).

Mi solución:

ext.isTask = { name -> return project.gradle.startParameter.taskNames.contains(name) }

/**
 * Heuristic function allowing to build process guess if annotation processor run is necessary
 * Annotation processors will not be called during build task if this function returns FALSE
 */
ext.isApInvalidated = { -> return hasAnyFileRelatedToApChanged() }

dependencies {
  if (isTask("buildWithAP") || isApInvalidated()) {
    println "Going to run annotation processors ..."
    apt "com.querydsl:querydsl-apt:$queryDslVersion:jpa"
  ...
  } else {
    // just add generated classes to the classpath
    // must be in else branch or multiple AP calls will collide!
  sourceSets.main.java.srcDirs += projectDir.absolutePath + "/build/generated/apt"
  } 

}

task buildWithAP (dependsOn: build) {}

Puede usar cualquier procesador de anotaciones que desee, por ejemplo, el suyo propio, no solo QueryDSL.

Espero que mi punto sea claro.

4
Snicolas 20 nov. 2017 a las 15:16

AFAIK esto no es posible actualmente: vea esta publicación de blog - sección "Incremental compilar con procesadores de anotaciones ":

... con procesadores de anotaciones, Gradle no sabe qué archivos van a generar. Tampoco sabe dónde y en función de qué condiciones. Por lo tanto, Grade deshabilita el compilador incremental de Java si se utilizan procesadores de anotaciones

Problema relacionado con Gradle: Haga que la compilación incremental sea eficiente en presencia de procesadores de anotación # 1320

La publicación del blog también menciona una posible solución alternativa:

Sin embargo, es posible limitar el impacto de esto al conjunto de clases que realmente usan procesadores de anotación. En resumen, puede declarar un conjunto de origen diferente, con una tarea de compilación diferente, que utilizará el procesador de anotaciones, y dejar las otras tareas de compilación sin ningún tipo de procesamiento de anotaciones

Sin embargo, esto parece ser bastante trabajo, así que aún no lo he usado.

2
TmTron 14 nov. 2017 a las 15:33

¡El problema parece haber sido resuelto! https://issuetracker.google.com/issues/37079915

-1
Rule 17 ene. 2019 a las 05:37