我们希望将一个Java项目分发给用户。它不使用Java 1.5之外的任何Java功能,因此我们希望它在Java 1.5及更高版本上运行。
此时,您可能正确地注意到Java 1.6是目前最早的可用,那么为什么要定位Java 1.5呢?但是,这并没有改变旧版本交叉编译问题的一般性质。
因此,通常开始交叉编译尝试的方法是将-source 1.5
和-target 1.5
选项指定为javac
,此时会收到有关-bootclasspath
的着名警告没有设置:
$ javac -source 1.5 -target 1.5 Test.java
warning: [options] bootstrap class path not set in conjunction with -source 1.5
1 warning
现在,根据Oracle blog post以及official documentation,交叉编译的正确做法是:
要使用JDK N中的javac交叉编译到较旧的平台版本,正确的做法是:
- 使用较旧的-source设置。
- 将bootclasspath设置为针对旧平台的rt.jar(或等效项)进行编译。
如果不采取第二步,javac将尽职尽责地使用旧语言规则与新库相结合,这可能导致类文件无法在较旧的平台上运行,因为可以包含对不存在的方法的引用。 / p>
例如,引用官方文档:
% javac -source 1.6 -target 1.6 -bootclasspath jdk1.6.0/lib/rt.jar \
-extdirs "" OldCode.java
这很棒,并且在Stack Overflow和其他互联网上都已经多次回答过。
但是,我们发现的资源似乎都没有表明在哪里可以找到旧版Java的rt.jar
。例如,除了rt.jar
以外,JDK 1.7不附带{:}}:
$ find jdk-1.7.0_45 -name rt.jar
jdk-1.7.0_45/jre/lib/rt.jar
这使人们认为,例如,为了获得Java 1.6的rt.jar
,需要下载JDK 1.6。但后来出现了两个问题:
那么,我们如何实际指定-bootclasspath
选项来使用这种交叉编译功能?
答案 0 :(得分:3)
rt.jar包含在JRE中。如果你有JDK 1.6和JRE 1.5,你将能够执行交叉编译。
使用JDK 1.6:
$ javac -source 1.5 -target 1.5 -bootclasspath jre1.5.0/lib/rt.jar Test.java
这里的优点是JRE可以小到完整JDK的1/3。您通常可以删除旧的JDK版本而无需删除旧的JRE版本。
如果您需要获取旧的JRE,可以在Java Archive页面上找到以下链接http://www.oracle.com/technetwork/java/javase/archive-139210.html
答案 1 :(得分:0)
This type of compilation is primarily motivated by needing to target a JRE that is already in production or an otherwise existing install, IME. In that case, pulling the JRE bootclasspath files from the existing install and making them available from the build system(s) would be the first task. The bootclasspath value you specify will depend on where you put the JRE bootclasspath files during that step.
FYI, you may need quite a few more files than just rt.jar. E.g., when targeting IBM Java 6.