32

我的 maven 项目有几个模块:服务器、Web 等。

我想在 Java 6 上构建除了我的服务器模块之外的所有模块。对于服务器模块,我想用 Java 7 编译它。

下面是我的 pom.xml,但我认为如果我将其修改为 1.7,那么我的所有模块都将使用 Java 7 进行编译。此外,maven 是否使用 JAVA_HOME 环境变量来确定要使用的 Java 版本?

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
                        <version>2.3.2</version>
        <configuration>
            <source>1.6</source>
            <target>1.6</target>
            <memmax>2048m</memmax>
        </configuration>
    </plugin>

编辑另外,以下输出是否

行家——版本

表明maven正在用1.7编译我的java代码?

vagrant@dev:~/bin/apache-tomcat-7.0.29/bin$ mvn --version
Apache Maven 3.0.4 (r1232337; 2012-01-17 08:44:56+0000)
Maven home: /home/vagrant/bin/apache-maven-3.0.4
Java version: 1.7.0_07, vendor: Oracle Corporation
Java home: /home/vagrant/bin/jdk1.7.0_07/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.2.0-23-generic", arch: "amd64", family: "unix"

谢谢,凯文

4

3 回答 3

36

有许多黑客可以使用与运行 Maven 不同的 JDK 版本来编译源代码,例如,您可以使用类似

<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.5.1</version>
        <configuration>
          <executable><!-- path-to-javac --></executable>
        </configuration>
      </plugin>
    </plugins>
    [...]
  </build>
  [...] 
</project>

这种方法的问题是您现在已经将 JDK 的路径硬编码到您的 POM 中。一切都可以在您的机器上正常工作,但是当您因为 HDD 故障而必须重建机器时,或者当您想在另一台机器上构建时,您将被卡住,因为路径很可能不匹配。

处理此问题的正确最佳实践方法是通过Toolchains。这将看到您创建一个~/.m2/toolchains.xml文件,该文件描述系统中每个不同工具链的位置。然后可以通过 Maven Toolchains Plugin 应用 JDK 的版本,例如

<plugins>
 ...
  <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.6</version>
        </jdk>
      </toolchains>
    </configuration>
  </plugin>
  ...
</plugins>

接下来的事情是你并不像你想象的那样经常需要这个。例如,通过使用sourceandtarget值,您可以为您所针对的 JRE 生成正确的字节码......您将遇到的唯一问题是使用 JRE 1.7 中的新方法......这就是Mojo 的 Animal Sniffer Plugin进来了。Animal Sniffer 可用于确保您只使用您所针对的 JRE 的方法。社区的普遍共识是使用sourcetargetMaven Compiler Plugin 配置中的配置选项以及 Mojo 的 Animal Sniffer 的使用几乎消除了 Compiler 端对工具链的需求......在 Surefire 端仍然需要工具链......我有我需要更新编译器插件和工具链插件来处理一些边缘情况,但实际上你不会遇到这些边缘情况;-)

只是为了确保您的原始问题得到完全回答(因为上面回答了您想问的问题 - 而不是您问的问题)

目前您正在使用 JDK 1.7 进行编译,但是根据您使用的 Maven 编译器插件的版本,您可能正在使用其中一个进行编译,<source>1.4</source><target>1.4</target>或者<source>1.5</source><target>1.5</target>除非您更改了pom.xml. 这将决定您可以使用哪些语言功能,而不是哪些类......因此您将生成适用于 JRE 1.7 的代码,并且前提是您没有使用自 1.4/1.5 以来引入的任何新类/方法(例如String.isEmpty())也应该在 JRE 1.4/1.5 上工作......确定它是否适用于这样一个旧 JVM 的唯一方法是:在旧 JVM 上运行它或使用 Animal Sniffer。

于 2012-09-14T07:04:41.877 回答
9

Maven 工具链

要使用多个 Java 版本,您需要使用Maven Toolchains,这需要您toolchains.xml在 Maven 文件夹中创建一个文件~/.m2,其中包含您机器上安装的所有 Java 版本:

<toolchains>
  <toolchain>
    <type>jdk</type>
    <provides>
      <id>Java13</id>
      <version>13</version>
    </provides>
    <configuration>
      <jdkHome>${env.JAVA_HOME_13}</jdkHome>
    </configuration>
  </toolchain>
  <toolchain>
    <type>jdk</type>
    <provides>
      <id>Java9</id>
      <version>9</version>
    </provides>
    <configuration>
      <jdkHome>${env.JAVA_HOME_9}</jdkHome>
    </configuration>
  </toolchain>
  <toolchain>
    <type>jdk</type>
    <provides>
      <id>Java8</id>
      <version>8</version>
    </provides>
    <configuration>
      <jdkHome>${env.JAVA_HOME_8}</jdkHome>
    </configuration>
  </toolchain>
  <toolchain>
    <type>jdk</type>
    <provides>
      <id>Java7</id>
      <version>7</version>
    </provides>
    <configuration>
      <jdkHome>${env.JAVA_HOME_7}</jdkHome>
    </configuration>
  </toolchain>
  <toolchain>
    <type>jdk</type>
    <provides>
      <id>Java6</id>
      <version>6</version>
    </provides>
    <configuration>
      <jdkHome>${env.JAVA_HOME_6}</jdkHome>
    </configuration>
  </toolchain>
</toolchains>

, JAVA_HOME_13, JAVA_HOME_9, JAVA_HOME_8,环境变量被配置JAVA_HOME_7JAVA_HOME_6引用相关 Java 版本的安装路径。

FlexyPool 父 pom.xml 配置文件

FlexyPool项目的父pom.xmlMaven 配置文件定义了全局 Java 版本设置

<properties>
    <jdk.version>8</jdk.version>
    ...
</properties>

现在,我们需要指示编译器和测试插件都使用配置的 java 版本。

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-toolchains-plugin</artifactId>
            <version>1.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>toolchain</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <toolchains>
                    <jdk>
                        <version>${jdk.version}</version>
                    </jdk>
                </toolchains>
            </configuration>
        </plugin>
        
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven-compiler-plugin.version}</version>
            <configuration>
                <source>${jdk.version}</source>
                <target>${jdk.version}</target>
                <showDeprecation>true</showDeprecation>
                <showWarnings>true</showWarnings>
            </configuration>
        </plugin>
        
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>${maven-surefire-plugin.version}</version>
        </plugin>
    </plugins>
</build>

FlexyPool 子 Maven 模块 pom.xml 使用不同的 Java 版本

需要不同 Java 版本的flexy-pool-core-java9子 Maven 模块只需要覆盖默认的jdk.versionMaven 属性:

<properties>
    <jdk.version>9</jdk.version>
</properties>

就是这样,我们现在可以使用自己的最小可行 Java 版本构建每个模块。

于 2014-09-28T07:43:20.563 回答
3

在您的顶级 pom 上使用 JDK6 的设置,它将被所有模块继承,并使用所需的不同配置为您的服务器 pom 覆盖它。

至于JDK的路径,可以指定,看这里:http ://maven.apache.org/plugins/maven-compiler-plugin/examples/compile-using-different-jdk.html

于 2012-09-13T21:14:15.837 回答