Skip to content

User guide

Martin Desruisseaux edited this page Mar 24, 2025 · 13 revisions

Compiler plugin user guide

This page gives an introduction to the Maven compiler plugin 4.0. For differences compared to the previous compiler plugin, see migration from Maven 3 to Maven 4.

Declaring source files

The recommended way to declare source directories is with <source> elements. Note that these sources are declared in the <build> element and therefore can apply to all plugins. If no source is declared, the default values relevant to the compiler plugin are as below:

<build>
  <sources>
    <source>
      <lang>java</lang>
      <scope>main</scope>
      <directory>src/main/java</directory>
    </source>
    <source>
      <lang>java</lang>
      <scope>test</scope>
      <directory>src/test/java</directory>
    </source>
  </sources>
<build>

If a <sources> element is declared, its content will replace the above default values. Therefore, the above defaults may need to be copied if the developer wants to add sources instead of replacing them.

Multiple source directories

The <source> element can be repeated as many times as desired for the same language and scope. Optionally, an enabled flag allows to include or exclude the whole directory according a property value. The following example adds the extension directory only if the value of the include.extension property is set to true. For brevity, this example uses the default values of the <scope> and <lang> elements when applicable.

<build>
  <sources>
    <source>
      <directory>src/main/java</directory>
    </source>
    <source>
      <directory>src/extension/java</directory>
      <enabled>${include.extension}</enabled>
    </source>
    <source>
      <scope>test</scope>
      <directory>src/test/java</directory>
    </source>
  </sources>
<build>

Multi-releases project

The <source> element can be repeated many times with different Java releases. The lowest release value is given to the --release compiler option for the base classes, and the source files in all directories associated to that version are compiled together. Then, the sources of all other releases are compiled in separated javac executions, one execution for each release, in the order of increasing release values. For each new execution, the output directories of all previous executions are added to the class-path with highest releases first, and the output is written in the META-INF/versions/${release}/ sub-directory. Example:

<build>
  <sources>
    <source>
      <directory>src/main/java</directory>
      <targetVersion>17</targetVersion>
    </source>
    <source>
      <directory>src/main/java_21</directory>
      <targetVersion>21</targetVersion>
    </source>
    <source>
      <scope>test</scope>
      <directory>src/test/java</directory>
    </source>
  </sources>
</build>

Note: For targeting Java 8, the version number shall be 8, not 1.8.

Include/exclude filters

For each source directory, the list of source files to compile can be filtered. If <include> elements are specified, only the files that match at least one include filters may be compiled. If no <include> element is specified, then the default filter is glob:**/*.java. Next, if <exclude> elements are specified, all included elements matching at least one exclude filter become excluded.

The filtering implementation uses java.nio.file.PathMatcher. The syntax is described in the Javadoc of standard Java. Various syntaxes are possible, including glob and regex. If no syntax is specified, Maven defaults to the glob syntax where / is the path separator regardless the platform (including Windows), * matches any filename inside a directory and ** matches any number of directories (see above-cited Javadoc for more detailed explanation). All paths to be matched are relative to the path specified in the <directory> element. Example:

<build>
  <sources>
    <source>
      <directory>src/main/java</directory>
      <excludes>
        <exclude>**/Foo*.java</exclude>
      </excludes>
    </source>
    <source>
      <scope>test</scope>
      <directory>src/test/java</directory>
    </source>
  </sources>
</build>

Troubleshooting

If the compilation failed, the Maven compiler plugin writes the options that it used in a javac.args or javac-test.args file (for compilation of main code and test code respectively) in the target directory. The compilation can be executed on the command-line as below. Note that the paths to source files inside javac.args are relative to the project directory. Therefore, that command must be executed in the same directory as the pom.xml file, or in a directory containing a copy or a branch of that project.

javac @target/javac.args

By default, javac.args is not written if the compilation succeed. Users can force the plugin to write that file in the following ways:

  • Execute mvn with the --verbose option (more exactly: enable logging messages at the debug level).
  • Or provide the <verbose>true</verbose> option in the plugin configuration.
Clone this wiki locally