【问题标题】:Different maven compiler versions for test and main用于测试和主要的不同 Maven 编译器版本
【发布时间】:2010-11-15 21:08:03
【问题描述】:

如何配置 maven 编译器以使用 java 5 作为我的测试代码和 java 1.4 作为我的主要代码?

【问题讨论】:

    标签: java maven compiler-construction maven-2 maven-3


    【解决方案1】:

    如果您想设置与相关 Java 版本的合规性,您可以为每次执行配置编译器插件。假设 Maven 使用的 JDK 至少与您指定的最高版本一样最新。通过使用属性,您可以在命令行上覆盖该配置,如果需要,可以在子级中覆盖该配置:

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

    如果您的意思是使用不同的编译器,那就有点麻烦了。因为您需要指定 JDK 的路径以及您使用的编译器版本。同样,这些可以在属性中定义。虽然您可能想在 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>
    

    请注意,在配置文件中定义编译器配置可能是有意义的,为您支持的每个 JDK 配置一个配置文件,这样您的正常构建就不会依赖于设置的属性。

    另外,在 Maven 3.x 中,您需要在指定可执行文件时包含 fork 参数, 例如:

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

    【讨论】:

    • 当我尝试使用源和目标版本1.8 进行测试和1.7 用于主代码的第一个示例时,当mvn compilemvn test-compile 分开运行时编译成功,但在命令中比如mvn compile test-compile或者更简单的mvn test-compile(其中compile被拉进来)&lt;source&gt;1.7&lt;/source&gt;的主要配置似乎优先,它失败了。
    • 解决方案是&lt;id&gt;default-testCompile&lt;/id&gt;覆盖了默认行为。上面的答案增加了一个额外的执行。
    • 请原谅我对处决缺乏了解。如果执行 maven 测试,这是否会导致主应用程序代码编译为与测试代码相同的目标版本?或者主源和测试源会有不同的目标字节码版本?
    • @ChrisBetti 这取决于 配置选项的设置。使用的编译器并不规定使用的字节码版本。
    【解决方案2】:

    使用maven-compiler-plugin,版本 3.5.1 编译 java 7 源和 java 8 测试源的接受答案没有运气。因为编译插件对主源和测试源都使用了源/目标参数。

    但我发现,测试源和目标有单独的配置参数。

    所以对我来说有效的解决方案是

     <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <testSource>1.8</testSource>
                    <testTarget>1.8</testTarget>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

    【讨论】:

    【解决方案3】:

    我至少为我的情况找到了解决方案。

    我正在编写一个需要与 Java 1.7 兼容但依赖于 JDK 8 中的 nashorn 引擎来测试其某些功能的库,这是为 maintest.

    当谈到对 main 和 test 使用不同的编译器/JRE 版本时,说版本 A 用于 main 和版本 B 用于 testA 严格小于 B,我们真的想要实现以下目标:

    1. 在开发过程中让 IDE(在我的例子中为 Eclipse)使用 JDK 版本 B,以免引入编译错误(项目图标上的红色叉号)。
    2. 使 JUnit 测试可在您的 IDE 中运行。
    3. 使 JUnit 测试可从命令行通过 mvn clean test 运行,这是发布所必需的。
    4. 使用 JRE Amain 中编译源代码,这可以自动检测使用来自 JDK B 的新功能。
    5. 在测试用例代码中免费使用来自 JDK B 的新功能/新 API。

    以下 pom 声明有效(例如 let A = 1.7B = 1.8):

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.5.1</version>
                    <configuration>
                        <fork>true</fork>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                    <executions>
                       <execution>
                          <id>default-compile</id>
                          <configuration>
                             <compilerArguments>
                                <source>1.7</source>
                                <target>1.7</target>
                             </compilerArguments>
                          </configuration>
                       </execution>
                       <execution>
                          <id>default-testCompile</id>
                          <configuration>
                             <compilerArguments>
                                <source>1.8</source>
                                <target>1.8</target>
                             </compilerArguments>
                          </configuration>
                       </execution>
                    </executions>
                </plugin>
    

    首先,&lt;source&gt;1.8&lt;/source&gt; &lt;target&gt;1.8&lt;/target&gt; 是让 Eclipse 满意并为项目本身使用 1.8 的必要条件,正如其他人指出的那样,Eclipse 仍有一个未决的错误,并且本身不支持单个项目中的不同 JDK 版本。

    其次,在源代码编译和测试源代码编译过程中,使用&lt;execution&gt; 覆盖sourcetarget 参数。 default-compiledefault-testCompile 是编译器插件的特殊名称。

    第三,一定要使用compilerArguments,而不是compilerArgs。据我所知,只有compilerArguments 可用于在运行时覆盖参数设置。

    【讨论】:

      猜你喜欢
      • 2016-05-14
      • 2021-08-31
      • 2017-11-16
      • 2019-10-08
      • 2012-09-07
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      相关资源
      最近更新 更多