我的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"
谢谢, 凯文
答案 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>
接下来就是你不需要像你想象的那样频繁。例如,通过使用source
和target
值,您可以为您要定位的JRE生成正确的字节码...您将遇到的唯一问题是使用新的方法JRE 1.7 ...这是Mojo's Animal Sniffer Plugin的用武之地。动物嗅探器可用于确保您只使用您所定位的JRE方法。一般社区的共识是,在Maven编译器插件配置中使用source
和target
配置选项以及使用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,所以基本上我就是这样做的:
您开始定义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%
父pom.xml定义:
<properties>
<jdk.version>6</jdk.version>
<jdk>${env.JAVA_HOME_6}</jdk>
</properties>
主要的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>
需要JDK 1.7的模块必须覆盖以下属性:
<properties>
<jdk.version>7</jdk.version>
<jdk>${env.JAVA_HOME_7}</jdk>
</properties>
就是这样,我们现在可以使用自己特定的最低java版本要求构建每个模块。
答案 2 :(得分:2)
在顶部pom上使用JDK6的设置,它将由所有模块继承,并使用所需的不同配置覆盖服务器pom。
关于JDK的路径,您可以指定它,请参见此处:http://maven.apache.org/plugins/maven-compiler-plugin/examples/compile-using-different-jdk.html