如何避免在针对旧版JDK时出现NoClassDefFoundErrors和NoSuchMethodErrors?

5
假设我想编写一个应用程序,针对某个JRE版本(例如1.6),但是在我用来开发它的机器上安装了更新的JRE版本(例如1.7)。
朴素的方法是将编译器级别设置为1.6(我使用Eclipse,但这可能并不是非常重要,因为问题是普遍的)。然而,这是不够的。设置编译器的源级别确保源文件仅使用该Java版本可用的语言特性,因此生成的类文件具有正确的次要版本,因此目标JVM将能够加载和运行它们。
但是还有另一个更微妙的问题:如果我在代码中使用了1.7中添加的类或方法,并尝试在安装了1.6运行时的计算机上运行该应用程序,则会出现“ NoClassDefFoundError”或“ NoSuchMethodError”。
问题在于同一程序在开发机器上正常运行,因为安装在其中的1.7 JDK包含这些类。编译器或IDE也不会抱怨。唯一表明我正在引用将不可用的类和方法的指示器是JavaDoc中的“ Since 1.7”注释。
那么如何确保我从未使用过旧版JRE中不可用的类或方法?唯一可靠的解决方案是始终在构建路径上具有完全匹配的目标JRE版本吗?这意味着我需要为每种情况(1.7、1.6、可能是1.5,甚至1.4)在我的开发机器上安装额外的JDK。

是的,我建议为您所针对的每个版本安装一个JDK。 - jtahlborn
那是一个天真的解决方案,而且不必要。 - Andrew Thompson
1
@AndrewThompson - 嗯,那正是你的解决方案。你怎么想象在没有不同版本安装的情况下拥有不同的rt.jars呢?这绝对不是天真的。实际上,这是一个非常直接和最安全的解决方案。 - jtahlborn
1个回答

3
使用 bootcpasspath 选项指向一个1.6 JRE(具体地说是 rt.jar)进行编译。这样做将强制检查所有引用的类、方法和属性是否实际存在于提供的 rt.jar 中。
有关更多详细信息,请参见javac - 交叉编译选项

那么您的意思是说,在开发机器上实际安装了1.6 JRE(或任何其他目标JRE)是必要的? - Natix
不需要,但是你需要访问 rt.jar。获取访问权限的方法之一是安装相关的 JRE。 - Andrew Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接