使用不同的Java版本编译Maven模块

时间:2012-09-13 20:23:31

标签: maven

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

我想在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"

谢谢, 凯文

3 个答案:

答案 0 :(得分:30)

有很多黑客可以使用不同版本的JDK编译源代码,而不是运行Maven,例如你可以使用类似

的东西
<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中。一切都可以正常运行你的机器,但是当你因为硬盘出现故障而无法重建你的机器,或者当你想在不同的机器上构建时,你将被困住,因为路径很可能不会匹配。

正确的最佳做法方式是通过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>

接下来就是你不需要像你想象的那样频繁。例如,通过使用sourcetarget值,您可以为您要定位的JRE生成正确的字节码...您将遇到的唯一问题是使用新的方法JRE 1.7 ...这是Mojo's Animal Sniffer Plugin的用武之地。动物嗅探器可用于确保您只使用您所定位的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>进行编译,除非您已在pom.xml中更改了Maven编译器插件的配置。这将决定哪些语言功能可供您使用,而不是哪些类...这样您将生成可用于JRE 1.7和的代码,前提是您没有使用自1.4 / 1.5以来引入的任何新类/方法< / em>(例如String.isEmpty())也应该适用于JRE 1.4 / 1.5 ...确定它是否适用于这样一个旧JVM的唯一方法是:在旧JVM上运行它或使用Animal嗅探器。

答案 1 :(得分:6)

FlexyPool使用JDK 1.6构建,而一个模块必须针对1.7进行编译(由于DBCP2依赖性)。

我写了an article on this topic,所以基本上我就是这样做的:

  1. 您开始定义JDK env变量:

    JAVA_HOME_6     C:\Program Files\Java\jdk1.6.0_38
    JAVA_HOME_7     C:\Program Files\Java\jdk1.7.0_25
    JAVA_HOME       %JAVA_HOME_6%
    
  2. 父pom.xml定义:

    <properties>
       <jdk.version>6</jdk.version>
       <jdk>${env.JAVA_HOME_6}</jdk>
    </properties>
    
  3. 主要的pom.xml定义了以下构建插件:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                    <showDeprecation>true</showDeprecation>
                    <showWarnings>true</showWarnings>
                    <executable>${jdk}/bin/javac</executable>
                    <fork>true</fork>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <jvm>${jdk}/bin/java</jvm>
                    <forkMode>once</forkMode>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
  4. 需要JDK 1.7的模块必须覆盖以下属性:

    <properties>
        <jdk.version>7</jdk.version>
        <jdk>${env.JAVA_HOME_7}</jdk>
    </properties>
    
  5. 就是这样,我们现在可以使用自己特定的最低java版本要求构建每个模块。

答案 2 :(得分:2)

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

关于JDK的路径,您可以指定它,请参见此处:http://maven.apache.org/plugins/maven-compiler-plugin/examples/compile-using-different-jdk.html