Как настроить инкрементную сборку Gradle с процессором аннотации

Я хочу использовать процессор аннотаций QueryDSL как часть моего процесса сборки. Как я могу избавиться от ненужных аннотаций процессора компиляции и запуска каждый раз, когда я изменяю любой класс? Я хочу, чтобы QueryDSL генерировал классы Q-*, только если некоторые связанные классы изменены.

Этот постоянно работающий процессор аннотаций отрицательно влияет на время нашего процесса сборки, и похоже, что добавочное построение не работает, если процессор аннотаций должен работать.

Спасибо.

2 ответа

Решение

Gradle не может знать, какие файлы процессоры аннотаций используют в качестве входных данных, поэтому он должен запускать полную перекомпиляцию каждый раз, когда что-то в наблюдаемых каталогах изменяется (src).

Однако вы можете легко указать Gradle, какие файлы должны запускать только обработку аннотаций. Изменение в другие файлы не приведет к использованию процессоров аннотаций, и Gradle может использовать всю свою мощь (например, инкрементные сборки).

Я также добавил "принудительную" задачу buildWithAP, вызывающую процессоры аннотаций независимо от результата подсказки (эвристической) функции.

Мое решение:

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) {}

Вы можете использовать любой процессор аннотаций, например, свой собственный, а не только QueryDSL.

Надеюсь, моя точка зрения ясна.

AFAIK это в настоящее время невозможно: см. Этот пост в блоге - раздел "Инкрементная компиляция с обработчиками аннотаций":

... с процессорами аннотации Gradle не знает, какие файлы они собираются сгенерировать. Он также не знает, где и на каких условиях. Поэтому Grade отключает инкрементный компилятор Java, если используются процессоры аннотаций

Связанная проблема для Gradle: сделать инкрементную компиляцию эффективной в присутствии процессоров аннотации #1320

В блоге также упоминается возможный обходной путь:

Однако возможно ограничить влияние этого на набор классов, которые действительно используют процессоры аннотаций. Короче говоря, вы можете объявить другой исходный набор с другой задачей компиляции, который будет использовать процессор аннотаций, и оставить другие задачи компиляции без какой-либо обработки аннотаций.

Тем не менее, это, кажется, довольно трудоемкая работа, поэтому я еще не использовал это.

Кажется, проблема решена! https://issuetracker.google.com/issues/37079915

Другие вопросы по тегам