我们有一个 Java 项目,希望分发给用户。它不使用 Java 1.5 以外的任何 Java 功能,因此我们希望它能够在 Java 1.5 及更高版本上运行。
此时,您可能正确地注意到 Java 1.6 是目前可用的最旧版本,那么为什么要以 Java 1.5 为目标呢?但是,这不会改变旧版本交叉编译问题的一般性质。
因此,通常开始交叉编译尝试的方法是为 javac
指定 -source 1.5
和 -target 1.5
选项,在哪一点会收到关于 -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 ,交叉编译的正确做法是:
To use javac from JDK N to cross-compiler to an older platform version, the correct practice is to:
- Use the older -source setting.
- Set the bootclasspath to compile against the rt.jar (or equivalent) for the older platform.
If the second step is not taken, javac will dutifully use the old language rules combined with new libraries, which can result in class files that do not work on the older platform since references to non-existent methods can get included.
比如引用官方文档:
% javac -source 1.6 -target 1.6 -bootclasspath jdk1.6.0/lib/rt.jar \
-extdirs "" OldCode.java
这太棒了,之前在 Stack Overflow 和互联网的其他地方已经回答了很多次。
但是,我们找到的所有资源似乎都没有指明在哪里可以找到旧版 Java 的 rt.jar
。例如,JDK 1.7 不附带 rt.jar
除了它自己的:
$ 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。但是接下来出现两个问题:
- 如果我们下载 JDK 1.6,我们不妨用它来编译而不是 JDK 1.7;
- 如果我们希望针对 Java 1.5 进行交叉编译,则 JDK 1.5 不再可供下载。
那么,我们如何实际指定 -bootclasspath
选项来使用此交叉编译功能?
最佳答案
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 存档页面上的链接找到它们 http://www.oracle.com/technetwork/java/javase/archive-139210.html
关于java - 为旧版本的 Java 进行交叉编译时,在哪里可以找到 Bootstrap 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22168437/