Pet*_*ter 6 java exception abstract
在catch子句中,我想打印异常的strack跟踪:
try {
...
} catch (Exception exc) {
exc.printStackTrace();
...
}
Run Code Online (Sandbox Code Playgroud)
但在某些情况下,我没有得到堆栈跟踪,而是看到这样的东西:
Exception in thread "pool-1-thread-2" java.lang.AbstractMethodError: java.lang.Exception.printStackTrace()V
...
Run Code Online (Sandbox Code Playgroud)
通常,如果库在运行时与编译时的版本不同,则会发生此异常,但在这种情况下,我使用Java库中的类.printStackTrace是在Throwable中实现的,因此这个方法在Exception或任何派生类中都不能是抽象的.此外,并不总是抛出此AbstractMethodError,有时在此特定catch子句中还有其他异常(程序流依赖于文件中的数据和当前时间,因此有时会发生其他事情,如我自己的代码中抛出的ArrayIndexOutOfBoundsExceptions或IllegalStateExceptions并且我期望而不是奇怪的错误).
所以,问题是:如何发生特定的AbstractMethodError?
PS:我在Linux上使用Eclipse Helios并使用JDK 1.6.0_24作为Runtime Environment来启动我的应用程序.
编辑:有一个拼写错误(printStrackTrace),我纠正了它.只是写在我的脑海里,与我的问题没有任何关系.它(或应该是)独立的应用程序,没有Web应用程序,没有Eclipse RCP应用程序,只是一个普通的旧Java应用程序(或多或少).问题确实发生在另一台计算机上 - 也可以使用Eclipse Helios,也可以使用Fedora Linux,但使用JDK 1.6.0_21.
令我惊讶的是,它确实可以调用getClass().getName()(但我没有尝试过其他方法),例外是类型java.lang.ArrayIndexOutOfBoundsException.我只是尝试使用OpenJDK 1.6.0(因为它已经安装在我的系统上)并得到了不同的结果.而不是抛出AbstractMethodError,printStackTrace只打印一个空行并getMessage()返回null(而不是抛出错误).所以我不知道抛出异常的确切位置,因为层次结构中的try-catch-block捕获异常只是为了优雅地停止应用程序的一部分.我可能会在某些方面捕获这种异常类型,以便了解它的来源.但这并不能解释异常本身的奇怪行为.
编辑2:最后我追踪了问题.事实证明这是我昨天在同一条线上发生的一个例外,但有时异常本身表现得很奇怪.我调用get(int)了一个List(更确切地说是一个ArrayList被包装使用的Collections.unmodifiableList(List))索引是-1(这是一个初始值,在一个循环中这个索引应该被改变,但它不会出于任何原因).至少现在我知道在哪里修复它ArrayIndexOutOfBoundsException,但我仍然不知道为什么异常本身表现得很奇怪.
编辑3:我尝试了Throwable.class.getMethod("printStackTrace").invoke(exc);而不是exc.printStackTrace();得到了java.lang.NoSuchMethodError: java.lang.Throwable.printStackTrace()V而不是java.lang.AbstractMethodError.我还尝试使用javac和从shell编译java文件jar(只有一个库来自异常,因为手动编译所有jar会很繁琐).结果是一样的.如果我IndexArrayOutOfBoundsException在该线上抛出一个自己,堆栈跟踪将被打印得很好.也许我不得不希望这个问题非常罕见,并且永远不会发生在其他任何地方.
据我了解,您已经在 Eclipse Helios 中启动了您的应用程序。这可能是因为 Eclipse 具有 OSGi 和专用类加载器的模块化性:用于运行应用程序的 ClassLoader 层次结构可能会导致无效链接。这主要取决于所涉及的异常类以及您的应用程序类路径中包含哪些 jar 文件 - 您自己的 jar 文件之一可能与 Eclipse 本身使用的 jar 文件冲突。您能否提供更多详细信息?
我猜你用“java应用程序”运行配置启动它。您是否选中了“包含系统库”或“包含继承的主函数”或任何其他选项等复选框之一?
顺便说一句,您的应用程序最终将作为独立的 Java 虚拟机运行,并且它应该在该上下文中运行得很好。
如果不是这种情况,请使用-verbose:class命令行选项运行 java 应用程序,并在崩溃前检查输出中的最新行,您可能会得到有关冲突库的线索(运行时与编译时不同)。