Как записать исключения, замаскированные окончательными исключениями блока в Java? - PullRequest
4 голосов
/ 31 марта 2011

Просто примечание : я знаю , что в Java finally блок никогда не должен генерировать исключения, в противном случае это [очень, очень, очень] плохая практика.Я знаю , что я должен использовать try-catch внутри finally для обработки (например, регистрации или игнорирования) всех исключений и предотвращения их распространения.Я знаю , что в Throwable Java 7 есть метод getSuppressed, но я нацеливаюсь на Java 5 & 6.

Проблема: В Java, в try-finally, если есть исключение (назовите его ) генерируется блоком try, элемент управления достигает блока finally (в случае без исключения он также достигает его, но в этом вопросе это не интересно).Затем, если блок finally выдает исключение (назовите его B ), исключение A подавляется или маскируется / проглатывается, а исключение B распространяется навызывающий.

Вопрос: Могу ли я как-то обнаружить ситуацию, когда одно исключение подавляется другим, и записать / записать первое?... Я потратил слишком много времени на то, чтобы выяснить, почему возникло конкретное исключение, и не зная, что на самом деле произошло.

Обоснование: часто проблемные блоки try-finally кодируются в библиотеке (сегодня это был Hibernate), поэтомуЯ не могу их изменить.

Ограничения решения: Как я уже отмечал в начале, возможное решение не должно ретранслироваться на Java 7, но, с другой стороны, не обязательно должно быть производственным классом (будучитакой был бы бонус).AOP - это вариант здесь.

(Пожалуйста, не публикуйте тривиальные ответы типа "используйте Java 7 для разработки":)

Ответы [ 2 ]

1 голос
/ 31 марта 2011

Проблема, я думаю, в том, что даже с АОП вы не можете перехватить процесс исключения. С помощью AOP вы можете захватить, скажем, все созданные исключения, но не можете знать, когда они потребляются.

Например:

try {
    ...
} catch (Exception e) {
    log.boom("Ouchies happened here", e);
}

Не каждое исключение перебрасывается.

Однако на определенном уровне МОСТ исключение, в конце концов, генерируется, чтобы вызывающий мог обработать их.

Итак, учитывая, что в любом случае вы, скорее всего, «утечете» исключения, игра должна попытаться найти «протекающие» исключения.

Используя AOP, вы можете скрывать каждое Исключение по мере его создания (можете ли вы сделать это на уровне Exception или делать это на уровне отдельного класса, я не могу сказать - не слишком знакомо с AOP в практика в этом случае).

Как только вы захватываете исключения по мере их создания, вы начинаете переносить вызовы методов через AOP. Когда вы сделаете это, вы можете перехватывать исключения, создаваемые методом.

Итак, немного поработав, вы узнаете, возвращаясь из метода а) какие исключения были созданы и б) какие были выброшены. Если вы пройдете исключение, «вызванное» деревом возвращенного исключения из метода, вы можете выбросить их из списка «исключений, созданных этим методом». Остальные утечки.

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

Это несовершенно, и, безусловно, я бы не стал использовать его в производстве (мне просто нужно было бы приложить немало усилий, чтобы разобраться во всех условиях гонки, связанных с записью и тому подобным. Больше работы, чем я хотел бы сделать для такого рода отладки, честно говоря). Но он может дать вам информацию, которую вы ищете, особенно если использовать ее в небольшом домене классов.

0 голосов
/ 31 марта 2011

Существует метод JNI с именем «ExceptionCheck ()», который, что неудивительно, проверяет наличие ожидающего исключения. Вы можете вызвать его в середине нативного метода, чтобы увидеть, не вызвал ли какой-то предыдущий вызов исключение, ожидающее возврата метода JNI до его фактического вызова. Интересно, вы могли бы вызвать нативный метод из finally, а затем попытаться использовать ExceptionCheck, чтобы увидеть, есть ли ожидающее исключение, сработает ли это. Я понятия не имею, так ли это, но я бы сказал, что стоит попробовать.

...