---剧透预警---
简短的答案是,为了将源代码编译为旧版本,您需要同时提供选项和.请参阅此文章。而如果你想将源代码编译到更新的版本,你需要在编译器插件上设置、、、、和,并在surefire插件上设置...-source
-bootclasspath
<source>
<target>
<compilerVersion>
<fork>
<executable>
<jvm>
现在的故事...
我遇到了同样的问题。事实证明,编译以前的版本可能不如设置和那么容易。我的具体情况是,我有一个Java 1.7 JDK,我的类与1.7不兼容(他们向我正在实现的接口添加了一个新方法)。当我尝试编译它时,编译器给了我一条错误消息,指出我没有实现接口方法。无论如何,我尝试设置编译器插件:<source>
<target>
<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>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
但是当我运行构建时,我得到了同样的错误。所以我在调试中运行了maven,并看到了这个:
[INFO] [DEBUG] Command line options:
[INFO] [DEBUG] -d C:\... -nowarn -target 1.6 -source 1.6 -encoding UTF-8
请注意, ...为了简洁起见,代替了实际的论点
在输出中。以 开头的消息是实际的完整编译参数列表。因此,如果删除该标志并将其余部分粘贴到命令行上,则可以看到编译器的实际输出:-d
-nowarn
javac
javac -d C:\... -target 1.6 -source 1.6 -encoding UTF-8
warning: [options] bootstrap class path not set in conjunction with -source 1.6
这将打印出未与 -source 1.6 一起设置的 handy-dandy 警告引导类路径。稍微谷歌搜索一下,就会发现这篇文章,其中指出:
要使用 Javac 从 JDK N 交叉编译器到较旧的平台版本,正确的做法是:
- 使用较旧的 -source 设置。
- 将引导类路径设置为针对旧平台的 rt.jar(或等效项)进行编译。
如果不采取第二步,javac将尽职尽责地使用旧语言规则与新库相结合,这可能导致类文件在旧平台上不起作用,因为可以包含对不存在的方法的引用。
现在引用编译器插件的 maven 文档,给出:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<compilerArguments>
<verbose />
<bootclasspath>${java.home}\lib\rt.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>
然后,您可以将其与早期配置相结合,以获得:
<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>
<encoding>UTF-8</encoding>
<bootclasspath>${java.home}\lib\rt.jar</bootclasspath>
</configuration>
</plugin>
现在,您只需要使该变量可用于您的 mvn(通过 -D 系统属性,或通过普通的旧环境变量,或者您可以变得非常花哨,并将其填充到用户设置的 java 6 配置文件中)。${java.home}
现在只需运行您的构建,然后去拿一杯冰镇啤酒,而它却在摇晃......
---- 编辑----
最后一件事...在 bootclasspath 中包含 rt.jar 始终是必需的,但是,我发现根据具体情况可能需要更多。我必须包含jce.jar(与rt.jar位于同一目录中),因为我的应用程序正在执行加密工作。
---- 编辑 2 ----
为了咧嘴一笑,我从另一个方向尝试了一下。我没有运行 java 7 编译 java 6 的 maven,而是运行了 java 6 编译的 java 7。第一次尝试非常简单:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<fork>true</fork>
<verbose>true</verbose>
<compilerVersion>1.7</compilerVersion>
<executable>${JAVA_7_HOME}/bin/javac</executable>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
基本上,我将 my 和 设置为 1.7,但这显然是不够的,因为 6 无法编译 7 代码。所以回到编译器插件,实际上有一个示例页面描述了需要做什么。也就是说,您需要使用java 7关闭新进程。所以现在我想我已经准备好了。是时候启动构建了...<source>
<target>
<fork>
<executable>
C:\Projects\my-project>mvn package
...
Caused by: java.lang.UnsupportedClassVersionError: mypackage.StupidTest : Unsup
ported major.minor version 51.0
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
到底是什么 不受支持的类版本错误?仔细观察就会告诉我们,是 maven-surefire-plugin 失败了。所以我尝试了,果然我得到了成功,因为surefire插件从未启动过。所以我跑了一圈,注意到了这个宝石:mvn compile
mvn -X package
Forking command line: cmd.exe /X /C ""C:\Program Files\Java\jdk1.6.0_29\jre\bin\
java" -jar C:\Projects\my-project\target\surefire\surefirebooter2373372991878002
398.jar C:\Projects\my-project\target\surefire\surefire1861974777102399530tmp C:
\Projects\my-project\target\surefire\surefire4120025668267754796tmp"
好的,所以它运行的java 6。为什么?surefire的文档给出了这个:
jvm:
Option to specify the jvm (or path to the java executable) to use with the forking
options. For the default, the jvm will be a new instance of the same VM as the one
used to run Maven. JVM settings are not inherited from MAVEN_OPTS.
由于我们使用java 6 VM运行mvn,因此它分叉了一个java 6 VM用于其单元测试。因此,请适当地设置此选项:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<jvm>${JAVA_7_HOME}/bin/java</jvm>
</configuration>
</plugin>
并启动构建...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------