Compiling Sources Using A Different JDK

Using Maven Toolchains

The preferable way to use a different JDK is to use the toolchains mechanism. During the build of a project, Maven, without toolchains, will use the JDK to perform various steps, like compiling the Java sources, generate the Javadoc, run unit tests or sign JARs. Each of those plugins need a tool of the JDK to operate: javac, javadoc, jarsigner, etc. A toolchain is a way to specify the path to the JDK to use for all of those plugins in a centralized manner, independent from the one running Maven itself.

To set this up, refer to the Guide to Using Toolchains, which makes use of the Maven Toolchains Plugin.

With the maven-toolchains-plugin you configure 1 default JDK toolchain for all related maven-plugins. Since maven-compiler-plugin 3.6.0 when using with Maven 3.3.1+ it is also possible to give the plugin its own toolchain, which can be useful in case of different JDK calls per execution block (e.g. the test sources require a different compiler compared to the main sources).

Configuring the Compiler Plugin

Outside of a toolchain, it is still possible to tell the Compiler Plugin the specific JDK to use during compilation. Note that such configuration will be specific to this plugin, and will not affect others.

The compilerVersion parameter can be used to specify the version of the compiler that the plugin will use. However, you also need to set fork to true for this to work. For example:

<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.12.1</version>
        <configuration>
          <verbose>true</verbose>
          <fork>true</fork>
          <executable><!-- path-to-javac --></executable>
          <compilerVersion>1.3</compilerVersion>
        </configuration>
      </plugin>
    </plugins>
    [...]
  </build>
  [...]
</project>

To avoid hard-coding a filesystem path for the executable, you can use a property. For example:

          <executable>${JAVA_1_4_HOME}/bin/javac</executable>

Each developer then defines this property in settings.xml, or sets an environment variable, so that the build remains portable.

<settings>
  [...]
  <profiles>
    [...]
    <profile>
      <id>compiler</id>
        <properties>
          <JAVA_1_4_HOME>C:\Program Files\Java\j2sdk1.4.2_09</JAVA_1_4_HOME>
        </properties>
    </profile>
  </profiles>
  [...]
  <activeProfiles>
    <activeProfile>compiler</activeProfile>
  </activeProfiles>
</settings>

If you build with a different JDK, you may want to customize the jar file manifest.