【发布时间】:2011-07-21 14:30:08
【问题描述】:
在 catch 子句中我想打印异常的轨迹:
try {
...
} catch (Exception exc) {
exc.printStackTrace();
...
}
但在某些情况下,我没有得到堆栈跟踪,而是看到如下内容:
Exception in thread "pool-1-thread-2" java.lang.AbstractMethodError: java.lang.Exception.printStackTrace()V
...
通常,如果库在运行时与编译时的版本不同,则应该会发生此异常,但在这种情况下,我使用 Java 库中的类。 printStackTrace 是在 Throwable 中实现的,因此该方法不能在 Exception 或任何派生类中抽象。此外,这个 AbstractMethodError 并不总是被抛出,有时在这个特定的 catch 子句中还有其他异常(程序流取决于来自文件的数据和当前时间,所以有时会发生其他事情,比如我自己的代码中抛出的 ArrayIndexOutOfBoundsExceptions 或 IllegalStateExceptions并且我希望而不是奇怪的错误)。
所以,问题是:那个特定的 AbstractMethodError 怎么可能发生?
PS:我在 Linux 上使用 Eclipse Helios,并使用 JDK 1.6.0_24 作为运行时环境来启动我的应用程序。
编辑:有一个错字(printStrackTrace),我更正了。只是写在我的脑海中,与我的问题没有任何关系。它是(或应该是)一个独立的应用程序,没有 Web 应用程序,没有 Eclipse RCP 应用程序,只是一个普通的旧 Java 应用程序(或多或少)。问题也确实出现在另一台计算机上 - Eclipse Helios 和 Fedora Linux 也是如此,但使用的是 JDK 1.6.0_21。
令我惊讶的是,它确实可以调用getClass().getName()(但我没有尝试过其他方法),但类型为java.lang.ArrayIndexOutOfBoundsException 的异常。我只是尝试使用 OpenJDK 1.6.0(因为它已经安装在我的系统上)并得到了不同的结果。 printStackTrace 没有抛出AbstractMethodError,而是只打印了一个空行,getMessage() 返回了null(而不是抛出错误)。所以我不知道异常到底是在哪里引发的,因为层次结构中较高的 try-catch-block 捕获异常只是为了优雅地停止应用程序的一部分。我可能会在某些方面捕捉到这种异常类型,以了解它的来源。但这并不能解释异常本身的奇怪行为。
编辑 2: 最后我找到了问题所在。结果是我昨天已经在同一行发生了一个异常,但有时异常本身的行为很奇怪。我在List(更准确地说:使用Collections.unmodifiableList(List) 包装的ArrayList)上调用get(int),其索引为-1(这是初始值,在循环内应该更改此索引,但它不会出于任何原因)。至少现在我知道去哪里修复ArrayIndexOutOfBoundsException,但我仍然不知道为什么异常本身表现得很奇怪。
编辑 3: 我尝试了 Throwable.class.getMethod("printStackTrace").invoke(exc); 而不是 exc.printStackTrace(); 并得到了 java.lang.NoSuchMethodError: java.lang.Throwable.printStackTrace()V 而不是 java.lang.AbstractMethodError。我还尝试使用javac 和jar 从shell 编译java 文件(只有一个异常来自的库,因为手动编译所有jar 会很乏味)。结果是一样的。如果我在该行自己抛出IndexArrayOutOfBoundsException,堆栈跟踪将被打印得很好。也许我不得不希望这个问题非常罕见,永远不会在其他任何地方发生。
【问题讨论】:
-
让他休息一下,我相信他知道正确的语法。
-
这是一个网络应用程序吗?通过 Java Web Start 安装的独立胖客户端?我们需要更多信息才能提供帮助。
-
听起来像是损坏的运行时库。你能重新安装Java吗?
-
是什么异常导致了输出?使用
System.out.println(exc.getClass().getName());之类的东西检查或使用调试器。哪个方法抛出异常? -
非常好奇。一切都为一些类加载器问题/java构建路径设置问题而哭泣,但无论如何这很奇怪。如果你尝试
Throwable.class.getMethod("printStackTrace").invoke(exc)会发生什么