如何捕获“Unsupported major.minor version”错误?

3

我了解这种错误的问题。我希望我的程序能够检测正在运行的Java版本,并向用户提供更加优雅的消息,而不是有些神秘的“异常线程”消息。我可以检测正在运行的Java版本,但似乎我的程序从未运行到检查代码。

简而言之...我的程序如何捕捉此错误、展示消息并正常退出?


1
如果您在程序启动时遇到此错误,则没有机会:您的代码甚至不会被执行。 - fge
@fge,是的,这是可能的。只需要一些谷歌搜索,你就可以找到这样的解决方案。 - Andremoniy
2
@Andremoniy,你似乎是这方面的专家,如果你能为我们节省一些搜索时间并在回答中添加一个简短的描述,那就太棒了。 - us2012
1
关键问题是:你是否正在构建具有错误版本的类?如果是这样,只需使用“-target”编译器选项重新构建它,以使用正确的版本。 - parsifal
2
@us2012 https://dev59.com/jWw15IYBdhLWcg3w1vSB@us2012 https://dev59.com/jWw15IYBdhLWcg3w1vSB - Andremoniy
显示剩余4条评论
2个回答

0
所以这是一个java.lang.UnsupportedClassVersionError错误。它明显是Java中Error类的后代,它继承了java.lang.ClassFormatError,而后者又继承了java.lang.LinkageError(它是java.lang.Error的直接子类)。 当Java虚拟机尝试读取一个类文件并发现特定类文件中的主要和次要版本号不受支持时,就会抛出此错误。这种情况发生在使用比执行该类文件的JVM版本更高的Java编译器生成类文件的情况下。
这很容易理解-编译器如何在编译时就知道使用哪个版本的JVM来执行编译后的类文件呢?不可能吧?其他错误也是如此。这就是所有错误都无需检查的原因。
为什么你要给用户看到这个错误消息!正如你所说的那样,“晦涩难懂”的消息只有在您使用早期版本的JVM来执行与您用于编译源代码的相应版本的编译器编译的类文件时才会发出。 现在,为什么要这样做呢?

为什么 Errors 从未被检测到?我不理解你的陈述。它们可以在 try... catch (Error err) ... 中捕获。 - Andremoniy
2
您的措辞有误。并非永不检测到错误,而是它们是未经检查的异常。异常是已检查和未检查的事实仅在“编译时”起作用(即,无需捕获/抛出它们),因此除非您捕获它们,否则它们会一直上升到main() - fge
2
你可以通过使用超旧版本的编译器来确保这一点!开个玩笑...但是,认真地说,你可以提供信息,说明这个jar只能与x+版本的JVM一起使用。这应该事先告知用户,而不是让他们使用这个jar,然后遇到这个错误,尽管有一个友好的提示信息! - Amar
3
@Paul - 更好的方法可能是改变你的应用程序分发方式。例如,使用Java WebStart。我认为,即使你花费了很多精力在退出前提供愉悦的信息,你的用户仍然会困惑其他事情(比如根本没有JVM)。 - parsifal
好的。我想底线是这种类型的错误发生在程序实际开始之前,导致程序终止。因此,由于程序在实际开始之前已经结束,所以程序无法处理错误。@parsifal,我会采纳你的建议。感谢所有为这个主题贡献了他们的想法和经验的人。 - Paul
显示剩余3条评论

0

这个异常是从 ClassLoader 抛出的,所以我建议您编写自己的版本的 ClassLoader,以便追溯此类错误。

更新:更具体地说,您可以尝试覆盖方法 defineClass,在那里捕获此类异常并以方便的方式包装它。

更新2:正如我在评论中提到的,以及 us2012 重述了我的想法(感谢他),您必须使用低于用户VM版本的 -target 编译您的类加载器


1
会起作用吗?您自己的ClassLoader可能与用户的JVM不兼容,就像您尝试运行的代码一样。我错了吗? - us2012
@us2012 你所说的“自己的ClassLoader与用户的JVM不兼容”是什么意思?我没听懂。你可以使用自己的类加载器,这是没有过时的。 - Andremoniy
@Amar,你错了。在简单的try...catch中也可以检测到错误。请阅读手册。 - Andremoniy
2
这取决于错误被抛出的原因。如果是您编译的代码,那么使用类加载器会得到相同的错误。如果是第三方库,则类加载器方法将起作用(因为您使用可接受的-target编译类加载器)。 - parsifal
1
@Andremoniy,啊,但这是重要的一点,你必须使用保证比用户VM版本低的-target编译你的类加载器!你应该在你的答案中加入这个。 (另外,一个单独的.jar文件是否可以包含使用不同-target编译的类?) - us2012
显示剩余4条评论

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