Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven 3: How to exclude generated sources from Xlint check?

We only allow java source code without Xlint errors. However, when sources are generated by third party tools, this is not practical. Examples of generated sources in our use-case are: JFlex, JavaCC, JAXB and annotation processors.

So the question is: how to exclude the generated sources from the Xlint checks? (see current configuration below)

<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>
like image 294
rmuller Avatar asked Oct 12 '16 09:10

rmuller


1 Answers

There is no direct configuration in the maven-compiler-plugin to do that. The parameters passed are for the whole execution, so passing -Xlint:all would apply to all sources to compile.

The solution here is to compile it in two pass: first pass would compile the generated sources without any lint check, and the second pass would compile your project sources (that might depend on the generated classes). Again, the Compiler Plugin doesn't offer a way to specify a path to sources to compile: it compiles all of the sources of the current Maven project.

You have 2 solutions: use 2 executions of the Compiler Plugin with includes/excludes or split this in 2 modules.

Include/Exclude

The idea is to have 2 executions: one that would exclude your main classes (and compile the generated ones), while the other execution would include them. Note that the inclusion/exclusion mechanism works on the fully qualified name of the classes, not the directory structure; so you can't exclude src/main/java.

Assuming all of your main java source files are under the my.package package, you can have:

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

This works because the first execution overrides the default-compile execution that Maven launches automatically on the compile phase, so it makes sure that the generated classes are compiled first.

Using two modules

As such, you need to split this in 2 modules, where the first module would generate the sources and compile them, while the second module would depend on the first one. Create a multi-module Maven project and have a parent 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>

You could add a <pluginManagement> block here to define default configuration for all the modules using it, like <source> and <target>.

The first module, my-generating-module, is responsible for generating and compiling the sources without any lint check. By default, showWarnings is false so you can keep the default configuration.

Then, in the second module, you can have a dependency on this first one, adding the lint check. Since this will only compile your project sources (the classes generated were already compiled and packaged in the other module), you won't have any warnings for those.

like image 127
Tunaki Avatar answered Oct 11 '22 12:10

Tunaki