AbstractMethodError при вызове Exception.printStackTrace - PullRequest
6 голосов
/ 21 июля 2011

Внутри предложения 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 в эту строку, трассировка стека будет напечатана очень хорошо. Может быть, я должен надеяться, что эта проблема встречается очень редко и больше никогда не возникнет.

1 Ответ

2 голосов
/ 22 июля 2011

Насколько я понимаю, вы запустили свое приложение в Eclipse Helios.Это может быть причиной из-за модульности Eclipse с OSGi и выделенным загрузчиком классов: иерархия ClassLoader, используемая для запуска вашего приложения, может привести к неправильной связи.Это в основном зависит от того, какой класс исключений и какие файлы JAR включены в путь к классу вашего приложения - один из ваших собственных файлов JAR может конфликтовать с файлом JAR, используемым в самом Eclipse.Можете ли вы предоставить дополнительную информацию?

Я полагаю, вы запускаете ее с конфигурацией запуска "java application".Вы отметили один из флажков, таких как «Включить системные библиотеки» или «Включенный унаследованный основной» или какие-либо другие параметры?

Кстати, ваше приложение, наконец, будет работать как автономная виртуальная машина Java, и оно должно прекрасно работатьхорошо в этом контексте.

Если это не так, запустите ваше Java-приложение с параметром командной строки -verbose:class и проверьте последнюю строку в выходных данных перед сбоем, вы можете получить представление о конфликтующих библиотеках (отличается во время выполнения от времени компиляции).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...