我们有一个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
Run Code Online (Sandbox Code Playgroud)
现在,根据Oracle博客文章以及官方文档,交叉编译的正确做法是:
要使用JDK N中的javac交叉编译到较旧的平台版本,正确的做法是:
- 使用较旧的-source设置.
- 将bootclasspath设置为针对旧平台的rt.jar(或等效项)进行编译.
如果不采取第二步,javac将尽职尽责地使用旧语言规则与新库相结合,这可能导致类文件无法在旧平台上运行,因为可以包含对不存在的方法的引用.
例如,引用官方文档:
% javac -source 1.6 -target 1.6 -bootclasspath jdk1.6.0/lib/rt.jar \
-extdirs "" OldCode.java
Run Code Online (Sandbox Code Playgroud)
这很好,并且在Stack Overflow和Internet的其他部分之前已经多次回答.
但是,我们发现的资源似乎都没有表明在哪里可以找到rt.jar
旧版本的Java.例如,rt.jar
除了自己的JDK 1.7 之外,JDK 1.7不附带:
$ find jdk-1.7.0_45 -name rt.jar
jdk-1.7.0_45/jre/lib/rt.jar
Run Code Online (Sandbox Code Playgroud)
这使人们认为,例如,为了获得rt.jar
Java …