Guide to Using Toolchains

What is Toolchains?

The Maven Toolchains provide a way for plugins to discover what JDK (or other tools) are to be used during the build, without the need to configure them in each plugin nor in every pom.xml, or forcing a precise location among every machine building the project.

With Maven Toolchains, a project can now be built using a specific version of JDK independent from the one Maven is running with. Think how JDK versions can be set in IDEs like Idea, NetBeans and Eclipse, or how you can build with an older JDK from Maven running with a recent one.

Toolchains will only work in Maven 2.0.9 and higher versions. For more details about its design and implementation, please see Toolchains.

Below are some plugins which are JDK-toolchain-aware, meaning they can use any JDK configured with toolchains:

  1. maven-compiler-plugin, starting with 2.1,
  2. maven-javadoc-plugin, starting with 2.5,
  3. maven-surefire-plugin, starting with 2.5,
  4. exec-maven-plugin (Codehaus MOJO), starting with 1.1.1.

Using Toolchains in Your Project

There are two essential components that you need to configure in order to use toolchains:

  1. the maven-toolchains-plugin in your project POM,
  2. the toolchains.xml file on the building machine.

The maven-toolchains-plugin is the one that sets the toolchain to be used by the toolchain-aware plugins in your project.

For example, you want to use a different JDK version to build your project than the version used to run Maven, you can configure the version you want to use via this plugin as shown in the pom.xml below:

<plugins>
 ...
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-toolchains-plugin</artifactId>
    <version>1.0</version>
    <executions>
      <execution>
        <phase>validate</phase>
        <goals>
          <goal>toolchain</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <toolchains>
        <jdk>
          <version>1.5</version>
          <vendor>sun</vendor>
        </jdk>
      </toolchains>
    </configuration>
  </plugin>
  ...
</plugins>

As you can see in the example above, a JDK toolchain with <version> "1.5" and <vendor> "sun" is to be used. Now how does the plugin know where this JDK is installed? This is where the toolchains.xml file comes in.

The toolchains.xml file (see below) is the configuration file where you set the installation paths of your toolchains. This file should be put in your $user.home/.m2 directory. When the maven-toolchains-plugin executes, the maven-toolchain component used by the plugin would look for the toolchains.xml file, reads it and looks for the matching toolchain configured in the plugin. In our example, that would be a JDK toolchain with <version> "1.5" and <vendor> "sun". Once a match is found, the plugin then sets the toolchain to be used in the MavenSession. As you can see in our toolchains.xml below, there is indeed a JDK toolchain with <version> "1.5" and <vendor> "sun" configured. So when the maven-compiler-plugin we've configured in our pom.xml above executes, it would see that a JDK toolchain is set in the MavenSession and would thereby use that toolchain (that would be the JDK installed at /path/to/jdk/1.5 for our example) to compile the sources.

<?xml version="1.0" encoding="UTF8"?>
<toolchains>
  <toolchain>
    <type>jdk</type>
    <provides>
      <version>1.5</version>
      <vendor>sun</vendor>
      <id>default</id>
    </provides>
    <configuration>
      <jdkHome>/path/to/jdk/1.5</jdkHome>
    </configuration>
  </toolchain>
  <toolchain>
    <type>jdk</type>
    <provides>
      <version>1.6</version>
      <vendor>sun</vendor>
      <id>ide</id>
    </provides>
    <configuration>
      <jdkHome>/path/to/jdk/1.6</jdkHome>
    </configuration>
  </toolchain>
  <toolchain>
    <type>netbeans</type>
    <provides>
      <version>5.5</version>
    </provides>
    <configuration>
      <installDir>/path/to/netbeans/5.5</installDir>
    </configuration>
  </toolchain>
</toolchains>

Note that you can configure as many toolchains as you want in your toolchains.xml file.