Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AbstractMethodError on calling Exception.printStackTrace

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
    ...

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).

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

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

Edit: 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.

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.

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.

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.

like image 367
Peter Avatar asked Jul 21 '11 14:07

Peter


1 Answers

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 ?

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 ?

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

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).

like image 102
Yves Martin Avatar answered Nov 10 '22 04:11

Yves Martin