在 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(因为它已经安装在我的系统上)并得到了不同的结果。而不是抛出 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 应用程序并在崩溃前检查输出中的最新行,您可能会得到有关冲突库的线索 (与编译时相比,运行时不同)。
关于java - 调用 Exception.printStackTrace 时出现 AbstractMethodError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6777710/