Вопрос по java, eclipse – Как отлаживать тихие сбои в приложениях Java?

5

Я пытаюсь отладить проблему в моем Java-приложении, которая не выдает никаких ошибок, исключений и даже не приводит к сбою приложения (похоже, сбой происходит в отдельном потоке).

Проблема, по-видимому, заключается в вызове библиотечной функции (этоJAXBContext.newInstance(String) если это имеет значение). Программа достигнет линии непосредственно перед вызовом, но не сразу после него. мойcatch блоки не вводятся и программа просто продолжает работать.

Проблема возникает при попытке отобразить XML-ответ на веб-запрос, поступивший через Struts. Запрос обработан, и код должен маршалировать объект ответа. Клиент сразу получает ответ (так что код, кажется, не зацикливается), но он просто пустой.

Я установил точку останова непосредственно перед проблемной строкой, но отладчик просто запускает ее, я понятия не имею, почему.

Я использую eclipse, и приложение запускается в контейнере OSGi (Apache Felix), который был запущен с-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y, Из Eclipse я затем использую параметры отладки для «Удаленного Java-приложения». подключить отладчик.

Какими методами можно решить такую проблему?

Вы уверены, что IDE указывает на тот же исходный код, который сформировал двоичные файлы на сервере? Nick Holt
Да, это все на моей локальной машине, и контейнер OSGi выполняет код непосредственно из выходного каталога моей IDE. Hanno Fietz
Да, это звучит правдоподобно, но я понятия не имею, как они могут быть не синхронизированы. Существует только одна копия исходного кода, и исполняемые двоичные файлы являются теми, которые создает среда IDE. Hanno Fietz
Если это проблема, то исполняемые файлы, которые, по вашему мнению, запускаются, не являются фактически запущенными. Обычно сервер распаковывает архивный файл в другой каталог. С JBoss это довольно надежно, но в среде разработки, в которой вы постоянно развертываете, я видел, что горячее развертывание перестало работать - JBoss прекращает распаковывать новые архивные файлы, и сервер продолжает работать на старых двоичных файлах. Я полагаю, у вас могла бы быть подобная проблема здесь. В JBoss вы решаете эту проблему, удаляя архивный файл, отскакивая от сервера, а затем повторно развертывая. Не уверен с OSGI, но я бы попробовал это. Nick Holt
Я не знаком с контейнером OSGi, переносит ли он, как и JBoss, развернутые двоичные файлы в другой каталог? Я попытаюсь внести изменения в ваш код, System.out.println или что-то подобное, а затем убедиться, что он выполняется, чтобы подтвердить это. Обычно я обнаружил, что пропущенные строки кода отладчика указывают, что IDE и сервер не синхронизированы друг с другом. Nick Holt

Ваш Ответ

4   ответа
0

внутри вызова происходит бесконечный цикл, и поэтому вы не получаете дальнейших действий, но это может не вызвать сбой (если память не используется в каждом цикле).

Нет, я так не думаю. Ошибка происходит при обработке веб-запроса, поступающего через Struts, и клиент сразу же получает результат (который является пустым). Таким образом, приложение не зависает, оно выпрыгивает из обработки. Hanno Fietz
2

Дамп - он сообщит вам, блокируются ли какие-либо методы (например, ожидание ввода). [Изменить: перечитывание исходного вопроса, получение дампа потока, вероятно, не поможет, так как похоже, что на самом деле ничего не блокирует. Но я оставляю это здесь, поскольку нахожу это полезным во многих других ситуациях!]

Если вы считаете, что ошибка происходит в другом потоке, вы также можете установитьUncaughtExceptionHandler попытаться поймать это.

Блокировка: нет, не в этот раз. Хорошей идеей была UncaughtExceptionHandler, к сожалению, она тоже ничего не уловила. Hanno Fietz
1

JAXB исходный код.

РЕДАКТИРОВАТЬ:

Что ж, если это действительно плохо, вы можете создать свою собственную частную копию с помощью инструментов отладки. Надеюсь, вам не придется прибегать к этому.

Что ж, я попробую, но без вмешательства отладчика у меня могут возникнуть трудности. Hanno Fietz
6

очевидный вопрос, но вы уверены, что ловите Throwable? Непроверенное исключение может легко привести к смерти рассматриваемого потока (при условии, что никто из вас в стеке вызовов его не перехватит).

Поскольку вы приостанавливаете виртуальную машину при запуске с вашими аргументами отладки, я предполагаю, что вы подтвердили, что отладчик подключается правильно. Тот факт, что вы говорите, что отладчик пропускает сразу после вызова, очень подозрительно. Вы можете достичь каких-либо точек останова в этом приложении? Как насчет этого класса? Как насчет этой темы?

Как вы сузили строку без отладчика? println / отладка в файл?

Можете ли вы вставить фрагмент кода рассматриваемого метода?

Вы можете подтвердить теорию о том, что поток умирает, создав второй поток до возникновения проблемы и присоединив его к потоку, который, по вашему мнению, умирает. Тогда метод run () второго потока будет вызываться при выходе из рассматриваемого потока, и вы будете знать, что он умер (но все равно не будете знать, почему).

В ответ на ваш общий вопрос, когда у меня есть ошибка в приложении Java, которую я не могу воспроизвести в отладчике (что происходит время от времени по разным причинам), я постепенно изменяю свой код с помощью команды sysout printlns или вывода в файлы. При необходимости я также могу изменить код, который вызывает мой код. Если у вас нет исходного кода для кода, который вы вызываете, вы можете попробовать одну из многих структур BCI, чтобы внедрить ваш байт-код в рассматриваемые методы. Это утомительный процесс, но происходит только изредка.

+1 Не все Throwables являются исключениями, и мы обычно ловим исключения; это легко проскользнуть мимо нас.

Похожие вопросы