用不同的Java版本编译Maven模块 [英] Compile Maven Module with Different Java Version

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

问题描述

我的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 --version

表示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"

谢谢, 凯文

解决方案

目前有许多技巧可以使用与运行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失败而必须重建计算机时,或者当您要在另一台计算机上进行构建时,您会被卡住,因为路径很可能不会配对.

正确的最佳实践方法是通过 Mojo的动物嗅探器插件出现的地方.嗅探器可用于确保仅使用目标JRE的方法.整个社区的共识是,在Maven编译器插件配置中使用sourcetarget配置选项,再加上Mojo的Animal Sniffer的使用,实际上消除了在编译器末端使用工具链的必要. Surefire结束时仍然需要工具链...而且我有一些极端情况需要更新编译器插件和工具链插件以进行处理,但实际上,您不会遇到那些极端情况;-)

请确保您的原始问题已完全回答(因为以上内容回答了您要提出的问题-与您提出的问题相反)

目前,您正在使用JDK 1.7 进行编译,具体取决于所使用的Maven编译器插件的版本,除非您已更改了<source>1.4</source><target>1.4</target><source>1.5</source><target>1.5</target>,否则可能正在使用<source>1.4</source><target>1.4</target><source>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.

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

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.

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 Also, does the below output of

maven --version

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"

Thanks, Kevin

解决方案

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>

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.

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>

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)

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模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆