调用 Exception.printStackTrace 时出现 AbstractMethodError [英] AbstractMethodError on calling Exception.printStackTrace

查看:18
本文介绍了调用 Exception.printStackTrace 时出现 AbstractMethodError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 catch 子句中,我想打印异常的跟踪跟踪:

Inside a catch clause I want to print the strack trace of the exception:

try {
    ...
} catch (Exception exc) {
    exc.printStackTrace();
    ...
}

但在某些情况下,我没有得到堆栈跟踪,而是看到如下内容:

But in some cases I don't get a stack trace and instead see something like this:

Exception in thread "pool-1-thread-2" java.lang.AbstractMethodError: java.lang.Exception.printStackTrace()V
    ...

通常,如果库在运行时的版本与编译时的版本不同,则会发生此异常,但在这种情况下,我使用的是 Java 库中的类.printStackTrace 是在 Throwable 中实现的,所以这个方法在 Exception 或任何派生类中都不能是抽象的.此外,这个 AbstractMethodError 并不总是抛出,有时在这个特定的 catch 子句中还有其他异常(程序流取决于来自文件的数据和当前时间,所以有时会发生其他事情,如我自己的代码中抛出的 ArrayIndexOutOfBoundsExceptions 或 IllegalStateExceptions并且我会期望而不是奇怪的错误).

Usually, this exception should occur if a library has not the same version at runtime as at compile time, but in this case I work with a class from the Java library. printStackTrace is implemented in Throwable, so this method can't be abstract in Exception or any derived class. Further, this AbstractMethodError isn't always thrown, sometimes there are other exceptions at this specific catch clause (program flow depends on data from a file and the current time, so sometimes other stuff happens like ArrayIndexOutOfBoundsExceptions or IllegalStateExceptions that are thrown in my own code and that I would expect instead of the strange error).

那么,问题是:那个特定的 AbstractMethodError 怎么可能发生?

So, the question is: How is it possible for that particular AbstractMethodError to occur?

PS:我在 Linux 上使用 Eclipse Helios,并使用 JDK 1.6.0_24 作为运行时环境来启动我的应用程序.

PS: I am using Eclipse Helios on Linux and use JDK 1.6.0_24 as Runtime Environment to launch my application.

有一个错字 (printStrackTrace),我更正了.只是写在我的脑海中,与我的问题无关.它是(或应该是)一个独立的应用程序,没有网络应用程序,没有 Eclipse RCP 应用程序,只是一个普通的旧 Java 应用程序(或多或少).该问题也出现在另一台计算机上 - 同样是 Eclipse Helios,也是 Fedora Linux,但使用的是 JDK 1.6.0_21.

There was a typo (printStrackTrace), I corrected it. Was just written out of my mind and hasn't anything to do with my problem. It is (or should be) a standalone application, no web-application, no Eclipse RCP application, just a plain old Java application (more or less). The problem does occur on another computer, too - also with Eclipse Helios, also with Fedora Linux, but with JDK 1.6.0_21.

令我惊讶的是,确实可以调用 getClass().getName()(但我没有尝试过其他方法),异常类型为 java.lang.ArrayIndexOutOfBoundsException.我只是尝试使用 OpenJDK 1.6.0(因为它已经安装在我的系统上)并得到了不同的结果.而不是抛出 AbstractMethodErrorprintStackTrace 只打印一个空行,getMessage() 返回 null(而不是抛出错误).所以我不知道异常到底是在哪里抛出的,因为层次结构中较高的 try-catch-block 捕获异常只是为了优雅地停止应用程序的一部分.我可能会在某些点上捕获此异常类型以了解它的来源.但这并不能解释异常本身的奇怪行为.

To my surprise it was indeed possible to call getClass().getName() (but no other method I tried), the exception is of type java.lang.ArrayIndexOutOfBoundsException. I just tried to use OpenJDK 1.6.0 (because it is already installed on my system) and got different results. Instead of throwing the AbstractMethodError, printStackTrace printed just an empty line and getMessage() returned null (instead of throwing the error). So I don't know where exactly the exception was thrown, because a try-catch-block high up in hierarchy catches the exception just to stop a part of the application gracefully. I might catch this exception type on some points to get an idea where it comes from. But that won't explain the strange behavior of the exception itself.

编辑 2: 最后我找到了问题所在.结果证明是昨天在完全相同的行上发生在我身上的异常,但有时异常本身的行为很奇怪.我在 List 上调用 get(int)(更准确地说:使用 Collections.unmodifiableList(List)<包装的 ArrayList/code>) 的索引为 -1 (这是初始值,在循环内该索引应该更改,但不会出于任何原因).至少现在我知道在哪里可以修复 ArrayIndexOutOfBoundsException,但我仍然不知道为什么异常本身表现得很奇怪.

Edit 2: Finally I tracked the problem down. It turned out to be an exception that occurred to me already yesterday at the exact same line, but sometimes the exception itself behaves strange. I call get(int) on a List (more precisely: an ArrayList that was wrapped using Collections.unmodifiableList(List)) with an index that is -1 (that is the initial value, inside a loop this index should be changed, but it will not for whatever reason). At least now I know where to look to fix the ArrayIndexOutOfBoundsException, but I still have no clue why the exception itself behaves strange.

编辑 3: 我尝试了 Throwable.class.getMethod("printStackTrace").invoke(exc); 而不是 exc.printStackTrace(); 并得到一个 java.lang.NoSuchMethodError: java.lang.Throwable.printStackTrace()V 而不是 java.lang.AbstractMethodError.我还尝试使用 javacjar 从 shell 编译 java 文件(只有异常来自的一个库,因为手动编译所有 jars 会很乏味).结果是一样的.如果我自己在该行抛出 IndexArrayOutOfBoundsException ,堆栈跟踪将被打印得很好.也许我不得不希望这个问题非常罕见,永远不会发生在其他任何地方.

Edit 3: I tried Throwable.class.getMethod("printStackTrace").invoke(exc); instead of exc.printStackTrace(); and got a java.lang.NoSuchMethodError: java.lang.Throwable.printStackTrace()V instead of the java.lang.AbstractMethodError. I also tried to compile the java files from the shell using javac and jar (only the one library the exception is coming from, because it would be tedious to manually compile all jars). The result is the same. If I throw an IndexArrayOutOfBoundsException myself at that line, the stack trace will be printed just fine. Maybe I have to hope that this problem is very rare and will never occur anywhere else.

推荐答案

据我所知,您已经在 Eclipse Helios 中启动了您的应用程序.这可能是因为带有 OSGi 和专用类加载器的 Eclipse 的模块化原因:用于运行应用程序的类加载器层次结构可能会导致无效链接.它主要取决于所关注的异常类以及您在应用程序类路径中包含哪些 jar 文件 - 您自己的 jar 之一可能与 Eclipse 本身使用的 jar 文件发生冲突.您能否提供更多详细信息?

As I understand you have launched your application inside Eclipse Helios. This may be the reason because of the modularity of Eclipse with OSGi and dedicated classloader: the ClassLoader hierarchy used to run your application may lead to invalid linkage. It mainly depends on what exception class is concerned and which jar files you have included in your application classpath - one of your own jar may conflict with a jar file used in Eclipse itself. May you provide additional details ?

我猜您使用java 应用程序"运行配置启动它.您是否选中了包含系统库"或包含继承的主库"或任何其他选项等复选框之一?

I guess you launch it with a "java application" run configuration. Have you checked one of the checkboxes like "Include system libraries" or "Included inherited main" or any other options ?

顺便说一下,您的应用程序最终将作为独立的 Java 虚拟机运行,并且在该上下文中应该运行良好.

By the way, your application will finally run as a standalone Java virtual machine and it should run perfectly well in that context.

如果不是这种情况,请使用 -verbose:class 命令行选项运行您的 java 应用程序并在崩溃前检查输出中的最新行,您可能会得到有关冲突库的线索(运行时与编译时不同).

If it is not the case, run your java application with -verbose:class command-line option and inspect latest line in output before the crash, you may get a clue about the conflictual libraries (different at runtime compared to compile-time).

这篇关于调用 Exception.printStackTrace 时出现 AbstractMethodError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆