如何在Maven中强制使用特定JDK进行编译

7

我在一个使用不同Java版本的应用程序环境中工作:7、8和之后版本。 因此,开发人员安装了几个JDK,并且每个Maven pom.xml确实具有正确的<source><target>标记。然而,有时候开发人员无意中使用更高版本的JDK进行编译。所以他们可能会在Java 7中包含一个Java 8类,比如java.time.LocalDate,它可以在编译时解决导入问题从而可以通过编译。但是,当该应用程序稍后移植到运行在JRE 7上时,它将失败,因为找不到Java 8类。 可以像下面这样在pom.xml中创建一个配置文件:

<profile>
  <id>compiler</id>
    <properties>
      <JAVA_1_4_HOME>C:\Program Files\Java\j2sdk1.4.2_09</JAVA_1_4_HOME>
    </properties>
</profile>

然而,JDK的位置因开发者而异,我希望有一个对所有人通用的pom.xml文件。因此问题是,如何强制Maven使用特定的JDK版本?不仅包括和,还涉及到JDK本身,并且是一种通用的方式,不绑定到任何给定的计算机。

1
@MarcStröbel 我也曾经这样想过。但是如果你安装了JDK 8编译器并且maven.compiler.{source,target}设置为1.7,编译仍然会成功! - Silviu Burcea
你的代码不使用Java 8的特性也没关系... JDK版本并不重要,编译器输出兼容1.7。 - Marc Stroebel
1
@MarcStröbel 这就是问题所在,OP希望强制禁止在源/目标设置为1.7时使用JDK 8功能。 - Silviu Burcea
1
我看到了...http://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html。页面底部有一些提示,例如使用Animal Sniffer Maven插件来检查api的使用。 - Marc Stroebel
1
还要注意,工具链允许Maven知道多个JDK。 - Thorbjørn Ravn Andersen
显示剩余3条评论
2个回答

9

我最初认为将maven-compiler-plugin的源/目标设置为1.7就足以使编译失败,但是如果你安装了JDK 8,则编译会成功(奇怪!)。

你真正需要的是maven-enforcer-plugin。请参见以下配置,我已将其放置在运行validate阶段之前,也就是compile之前:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-enforcer-plugin</artifactId>
            <version>3.0.0-M3</version>
            <executions>
                <execution>
                    <id>default-cli</id>
                    <phase>validate</phase>
                    <goals>
                        <goal>enforce</goal>
                    </goals>
                    <configuration>
                        <rules>
                            <requireJavaVersion>
                                <version>[1.7,1.8)</version>
                            </requireJavaVersion>
                        </rules>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

输出:

[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ compiler-demo ---
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireJavaVersion failed with message:
Detected JDK Version: 1.8.0-152 is not in the allowed range [1.7,1.8).

您甚至可以设置自定义消息,使同事们更清楚明白,例如:

<rules>
  <requireJavaVersion>
    <version>[1.7,1.8)</version>    <message>Project requires JDK 7</message>  </requireJavaVersion></rules>

输出:

[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ compiler-demo ---
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireJavaVersion failed with message:
Project requires JDK 7

为了探索插件的能力,我试图看看它是否支持多个版本范围。 它确实支持(在JDK 11上运行以尝试它):

<requireJavaVersion>
    <version>[1.7,1.8),[9,10)</version>
</requireJavaVersion>

输出:

[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ compiler-demo ---
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireJavaVersion failed with message:
Detected JDK Version: 11.0.1 is not in the allowed range [1.7,1.8),[9,10).

1
这会检测Java版本,而不是javac版本。请参见https://issues.apache.org/jira/browse/MENFORCER-368 - caduceus

0
export JAVA_HOME=..... && mvn clean compile

这将确保您正在使用正确的JDK


如果我导出JDK 11,那会解决什么问题?什么都不会解决。 - Silviu Burcea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接