Maven 3:如何从Xlint检查中排除生成的源?

时间:2016-10-12 09:05:19

标签: java maven javac maven-compiler-plugin

我们只允许没有Xlint错误的java源代码。但是,当源由第三方工具生成时,这是不切实际的。我们的用例中生成的源的示例包括: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 个答案:

答案 0 :(得分:6)

maven-compiler-plugin中没有直接配置来做到这一点。传递的参数用于整个执行,因此传递-Xlint:all将适用于所有要编译的源。

这里的解决方案是在两次传递中编译它:第一次传递将编译生成的源而不进行任何lint检查,第二次传递将编译项目源(可能取决于生成的类)。同样,Compiler Plugin没有提供指定编译源的路径的方法:它编译当前Maven项目的所有源。

你有2个解决方案:使用2个Compiler Plugin执行,包括/排除或分成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>

这是有效的,因为第一次执行会覆盖Maven在default-compile阶段自动启动的compile执行,因此它确保首先编译生成的类。

使用两个模块

因此,您需要将其拆分为2个模块,其中第一个模块将生成源并编译它们,而第二个模块将依赖于第一个模块。创建multi-module Maven project并拥有父my-parent with 2 modules

<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>

您可以在此处添加<pluginManagement>块来定义使用它的所有模块的默认配置,例如<source><target>

第一个模块my-generating-module负责生成和编译源代码而不进行任何lint检查。默认情况下,showWarningsfalse,因此您可以保留默认配置。

然后,在第二个模块中,您可以依赖第一个模块,添加lint检查。由于这只会编译您的项目源(生成的类已经编译并打包在另一个模块中),因此您不会收到任何警告。