本文介绍了编译不同Java版本的Maven模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My maven project has a few modules: server, web, etc.

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

I would like to build all but my server module on Java 6. For the server module, I'd like to compile it with Java 7.

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

Here's my pom.xml below, but I think that if I modify it to 1.7, then all of my modules will be compiled with Java 7. Also, does maven use the JAVA_HOME environment variable to determine which Java version to use?

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

EDIT 另外,

maven --version

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

indicate that maven is compiling my java code with 1.7?

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"

谢谢,凯文

推荐答案

有许多技巧可以使用与运行 Maven 不同版本的 JDK 来编译源代码,例如,您可以使用某些东西喜欢

There are a number of hacks out there for compiling source code with a different version of the JDK than you are using to run Maven, for example you can use something like

<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 中.在你的机器上一切正常,但是当你因为硬盘故障而不得不重建你的机器时,或者当你想在不同的机器上构建时,你会被卡住,因为路径很可能不会匹配.

The issue with this approach is that you now have hard-coded the path to the JDK into your POM. Everything will work just fine on your machine but when you have to rebuild your machine because the HDD failed, or when you want to build on a different machine, you will be stuck as the path will most likely not match up.

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

The correct best practice way to handle this is via Toolchains. This will see you creating a ~/.m2/toolchains.xml file that describes where each of the different toolchains in your system are. Then the version of the JDK can be applied by the Maven Toolchains Plugin, e.g.

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

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

The next thing is that you don't need this as often as you would think. For example by using the source and target values you can generate the correct bytecode for the JRE that you are targeting... the only issue that you will then hit is the use of methods that are new in JRE 1.7... which is where Mojo's Animal Sniffer Plugin comes in. Animal Sniffer can be used to ensure that you only use the methods of the JRE that you are targeting. The general community consensus is that the use of source and target configuration options in the Maven Compiler Plugin configuration coupled with the use of Mojo's Animal Sniffer virtually eliminates the need for toolchains on the Compiler end of things.... on the Surefire end of things there is still need for toolchains... and I have a few edge cases that I need to update the compiler plugin and the toolchains plugins for to handle but, realistically you will not hit those edge cases ;-)

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

Just to be sure that your original question is completely answered (since the above answers the question you wanted to ask - as opposed to the one you asked)

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

At present you are compiling with JDK 1.7 however depending on the version of the Maven Compiler Plugin you are using, you may be compiling with either <source>1.4</source><target>1.4</target> or <source>1.5</source><target>1.5</target> unless you have changed the configuration of the Maven Compiler Plugin in your pom.xml. That will dictate which language features are available to you, but not which classes... so you would be generating code that will work on JRE 1.7 and provided you have not used any new classes/methods introduced since 1.4/1.5 (Such as String.isEmpty()) should also work on JRE 1.4/1.5... the only way to be sure if it works on such an old JVM is to either: run it on the old JVM OR use Animal Sniffer.

这篇关于编译不同Java版本的Maven模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 19:57