Внутри предложения 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: я использую Eclipse Helios в Linux и использую JDK 1.6.0_24 в качестве среды выполнения для запуска моего приложения.
Редактировать: Была опечатка (printStrackTrace), я ее исправил. Был просто написан из моего разума и не имеет ничего общего с моей проблемой. Это (или должно быть) отдельное приложение, без веб-приложения, без приложения 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, расположенный высоко в иерархии, перехватывает исключение только для того, чтобы аккуратно остановить часть приложения. Я мог бы поймать этот тип исключения в некоторых моментах, чтобы понять, откуда оно. Но это не объясняет странного поведения самого исключения.
Редактировать 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
. Я также попытался скомпилировать java-файлы из оболочки, используя javac
и jar
(только из одной библиотеки, из которой исходит исключение, потому что было бы утомительно вручную компилировать все jar-файлы). Результат тот же. Если я сам добавлю IndexArrayOutOfBoundsException
в эту строку, трассировка стека будет напечатана очень хорошо. Может быть, я должен надеяться, что эта проблема встречается очень редко и больше никогда не возникнет.