Search code examples
javamaven

Different maven compiler versions for test and main


How can I configure the maven compiler to use java 5 for my test code and java 1.4 for my main code?


Solution

  • If you want to set compliance to the relevant Java version, you can configure the compiler plugin for each execution. Assuming Maven is using a JDK at least as current as the highest version you specify. By using properties you can override that configuration on the commandline or in a child if needed:

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <configuration>
        <source>${compileSource}</source>
        <target>${compileSource}</target>
      </configuration>
      <executions>
        <execution>
          <id>test-compile</id>
          <phase>process-test-sources</phase>
          <goals>
            <goal>testCompile</goal>
          </goals>
          <configuration>
            <source>${testCompileSource}</source>
            <target>${testCompileSource}</target>
          </configuration>
        </execution>
      </executions>
    </plugin>
    ...
    <properties>
      <compileSource>1.4</compileSource>
      <testCompileSource>1.5</testCompileSource>
    </properties>
    

    If you mean using different compilers, that's a bit more involved. as you need to specify the path to the JDK and what compiler version you're using. Again these can be defined in properties. Though you may want to define them in your settings.xml

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <configuration>
        <source>${compileSource}</source>
        <target>${compileSource}</target>
        <executable>${compileJdkPath}/bin/javac</executable>
        <compilerVersion>${compileSource}</compilerVersion>
      </configuration>
      <executions>
        <execution>
          <id>test-compile</id>
          <phase>process-test-sources</phase>
          <goals>
            <goal>testCompile</goal>
          </goals>
          <configuration>
            <source>${testCompileSource}</source>
            <target>${testCompileSource}</target>
            <executable>${testCompileJdkPath}/bin/javac</executable>
            <compilerVersion>${testCompileSource}</compilerVersion>
          </configuration>
        </execution>
      </executions>
    </plugin>
    ...
    <properties>
      <compileSource>1.4</compileSource>
      <testCompileSource>1.5</testCompileSource>
      <compileJdkPath>path/to/jdk</compileJdkPath>
      <testCompileJdkPath>path/to/test/jdk<testCompileJdkPath>
    </properties>
    

    Note it might make sense to define the compiler configurations in profiles, one for each JDK you support, so that your normal builds don't rely on properties being set.

    Also, in Maven 3.x, you need to include the fork parameter when specifying the executable, e.g.:

      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <executions>
          <execution>
            <id>default-testCompile</id>
            <phase>test-compile</phase>
            <goals>
              <goal>testCompile</goal>
            </goals>
            <configuration>
              <fork>true</fork>
              <executable>${testCompileJdkPath}/bin/javac</executable>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>            
          </execution>
        </executions>
      </plugin>