Maven 3: Как исключить сгенерированные источники из проверки Xlint?


Мы разрешаем только исходный код java без ошибок Xlint. Однако, когда источники генерируются сторонними инструментами, это непрактично. Примерами генерируемых источников в нашем примере использования являются: jflex, JavaCC, JAXB и процессоры аннотаций.

Итак, вопрос: как исключить сгенерированные источники из проверок Xlint? (см. текущую конфигурацию ниже)

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.5.1</version>
    <configuration combine.self="override">
        <source>${java.version}</source>
        <target>${java.version}</target>
        <showDeprecation>true</showDeprecation>
        <showWarnings>true</showWarnings>
        <!-- Since JDK1.3 javac ignores any optimization flags -->
        <optimize>true</optimize>
        <debug>false</debug>
    </configuration>
    <executions>
      <execution>
        <id>default-compile</id>
        <phase>compile</phase>
        <goals>
          <goal>compile</goal>
        </goals>
        <configuration>
          <!-- everything in target/generated-sources/** should be excluded from this check -->
          <compilerArgs>
            <arg>-Xlint:all,-rawtypes</arg>
          </compilerArgs>                     
        </configuration>
      </execution>
    </executions>
</plugin>
1 4

1 ответ:

Нет никакой прямой конфигурации в maven-compiler-plugin чтобы сделать это. Передаваемые параметры предназначены для всего выполнения, поэтому передача -Xlint:all будет применяться ко всем источникам для компиляции.

Решение здесь состоит в том, чтобы скомпилировать его в два прохода: первый проход будет компилировать сгенерированные источники без какой-либо проверки Линта, а второй проход будет компилировать ваши источники проекта (что может зависеть от сгенерированных классов). Опять же, плагин компилятора не предлагает способа указать путь к источникам, чтобы компиляция: он компилирует все источники текущего проекта Maven.

У вас есть 2 решения: использовать 2 исполнения плагина компилятора с включениями/исключениями или разбить его на 2 модуля.

Включить / Исключить

Идея состоит в том, чтобы иметь 2 исполнения: одно, которое было бы exclude ваши основные классы (и компилировать сгенерированные), в то время как другое выполнение будет include они. Обратите внимание, что механизм включения/исключения работает на полном имени объекта. классы, не структура каталогов; поэтому вы не можете исключить src/main/java.

Предполагая, что все ваши основные исходные файлы java находятся под пакетом my.package, Вы можете иметь:

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.5.1</version>
  <configuration>
    <source>${java.version}</source>
    <target>${java.version}</target>
  </configuration>
  <executions>
    <execution> <!-- this execution excludes my main sources under my.package -->
      <id>default-compile</id>
      <phase>compile</phase>
      <goals>
        <goal>compile</goal>
      </goals>
      <configuration> <!-- no lint check -->
        <excludes>
          <exclude>my/package/**/*.java</exclude>
        </excludes>
      </configuration>
    </execution>
    <execution> <!-- this execution includes my main sources under my.package -->
      <id>compile-main</id>
      <phase>compile</phase>
      <goals>
        <goal>compile</goal>
      </goals>
      <configuration> <!-- adds lint check -->
        <includes>
          <include>my/package/**/*.java</include>
        </includes>
        <showDeprecation>true</showDeprecation>
        <showWarnings>true</showWarnings>
        <compilerArgs>
          <arg>-Xlint:all,-rawtypes</arg>
        </compilerArgs>
      </configuration>
    </execution>
  </executions>
</plugin>

Это работает, потому что первое выполнение переопределяет выполнение default-compile, которое Maven запускает автоматически на этапе compile, поэтому он гарантирует, что сгенерированные классы будут скомпилированы первыми.

Использование двух модулей

Таким образом, вам нужно разделить это на 2 модуля, где первый модуль будет генерировать исходные тексты и компилировать их, в то время как второй модуль будет зависеть от первого. Создайте многомодульный проект Maven и создайте Родительский проектmy-parent с 2 модулями :

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>my.groupId</groupId>
  <artifactId>my-parent</artifactId>
  <version>1.0</version>
  <packaging>pom</packaging>
  <modules>
    <module>my-generating-module</module>
    <module>my-module</module>
  </modules>
</project>

Можно добавить a <pluginManagement> блок здесь, чтобы определить конфигурацию по умолчанию для всех модулей, использующих его, как <source> и <target>.

Первый модуль, my-generating-module, отвечает за генерацию и компиляцию исходных текстов без какой-либо проверки Линта. По умолчанию, showWarnings is false, так что вы можете сохранить конфигурацию по умолчанию.

Затем, во втором модуле, вы можете иметь зависимость от этого первого, добавив проверку корпии. Поскольку при этом будут компилироваться только исходные тексты проекта (созданные классы уже были скомпилированы и упакованы в другом модуле), у вас не будет никаких предупреждений для них.