Лучшее понимание исключений и ведение журнала в среде J2EE - PullRequest
1 голос
/ 05 ноября 2011

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

try {
    doSomething();
} catch (MyException e) {
    log.error("Exception:", e);
    throw e;
}

После того, как исключение выдается на бизнес-уровне, оно затем распространяется до уровня представления, который снова перехватывает исключение, обычно оборачивает его в PortletException или ServletException и выдает его снова.Затем он обрабатывается обработчиком Spring, который показывает «дружественное» сообщение пользователю.В конечном итоге я хотел бы обрабатывать только исключения, для которых мы хотим показать конкретное сообщение об ошибке, и просто игнорировать все остальное.

Вопросы:

  1. IsНужно ли регистрировать исключения на бизнес-уровне?Если нет, нужно ли вообще регистрировать исключения (особенно непроверенные)?
  2. Что происходит с неперехваченными исключениями, которые не регистрируются с помощью log4j?(Если они все еще печатаются в консоли, какова цель log4j?)

Я не понимаю, как работает этот процесс ...

Спасибо.

РЕДАКТИРОВАТЬ: Если исключение происходит во внешней библиотеке (Spring, Hibernate и т. Д.), Предполагается ли, что эти исключения будут распечатаны с использованием любого используемого механизма ведения журнала?В этом случае, я предполагаю, что мне нужно будет только регистрировать исключения, которые генерирует мой код ... или я здесь далеко от базы?

Ответы [ 6 ]

4 голосов
/ 05 ноября 2011

Прежде чем продолжить, пожалуйста, внимательно посмотрите на:

Ниже приведены некоторые из общепринятых принципов обработка исключений:

  1. Если вы не можете обработать исключение, не отлавливайте его.
  2. Если вы поймали исключение, не глотайте его.
  3. Поймать исключение как можно ближе к его источнику.
  4. Записать исключение, где вы его поймали, если только вы не планируете его перебрасывать.
  5. Структурируйте свои методы в соответствии с тем, насколько тонкой должна быть обработка исключений.
  6. Используйте столько типизированных исключений, сколько вам нужно, особенно для исключений приложения.

Пункт 1 явно находится в конфликте с пунктом 3. Практическим решением является компромисс> между тем, насколько близко к источнику вы поймали исключение, и как далеко вы допустили его падение, прежде чем полностью потеряли намерение или контент оригинального исключения.

IBM DeveloperWorks: лучшие практики EJB

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

Независимо от того, как вы поступите с этим, убедитесь, что вы понимаете смысл добавления исключения приложения в приложение Java EE. Вам может потребоваться выяснить, как она взаимодействует с вашей логикой управления транзакциями, особенно когда речь идет об откате транзакций. В моей работе мне пришлось добавить исключение @ApplicationException (rollback = false), чтобы запретить менеджеру транзакций откатывать мою транзакцию, когда исключение генерируется и распространяется вверх.

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

Итак, вернемся к вашим вопросам:

Необходимо ли регистрировать исключения на бизнес-уровне?

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

Если нет, нужно ли вообще регистрировать исключения (особенно непроверенные из них)?

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

Что происходит с необработанными исключениями, которые не регистрируются с помощью log4j? (Если они все еще печатаются в консоли, какова цель log4j?)

Я думаю, что он в конечном итоге будет перехвачен веб-контейнером и выведен на консоль. Если исключение распространяется вверх и достигает исключения веб-контейнера, обрабатывающего сети безопасности, ваше исключение выходит из-под контроля. Обычно это признак плохого дизайна. Лучше всего, если вы будете контролировать свои исключения. Зачем удивляться, как контейнер будет реагировать на неисследованное исключение? Также, насколько полезным будет это исключение для пользователя? Я думаю, что информация, представленная из неисследованных исключений, почти бесполезна, поскольку они настолько далеки от источника ошибки, что становятся неактуальными и трудными для работы при отладке.

1 голос
/ 05 ноября 2011

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

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

Другая проблема при обработке приложения и его отображении пользователю.

Ура!

0 голосов
/ 05 ноября 2011

Во-первых, вы можете и должны регистрировать трассировку стека исключений для всех исключений.На самом деле, IMO, если вы только регистрируете, что произошло исключение, вы можете вообще не регистрировать его.Однако очень часто к этому приводит расслабленный взгляд на исключения.Вы должны стремиться к тому, чтобы иметь 2 файла журнала или одну конкретную категорию, которые, если исключения относятся к этой категории, означают, что произошло что-то критическое и должны быть устранены.Даже если это означает регистрацию одного и того же исключения много раз.Скорее, слишком много, чем не совсем.

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

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

0 голосов
/ 05 ноября 2011

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

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

Если этот флажок снят, обычно это исключение, которое вы не знаете или не можете обработать.

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

Некоторые из контейнеров (т. Е. EJB) необходимы для регистрации возникших исключений. Более того, в EJB 3.x, если вы находитесь в транзакции, управляемой JTA, и вы не поймете непроверенное исключение, которое не помечено как @ApplicationException(rollback=false), транзакция будет автоматически откатываться. Это может быть причиной того, что вы можете увидеть некоторые блоки try ... catch с простым логированием кода внутри.

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

НТН!

0 голосов
/ 05 ноября 2011

Нужно ли регистрировать исключения на бизнес-уровне?

Нет. Но больше журналов = лучшее понимание того, что происходит. Другими словами, больше журналов = низкая производительность.

Что происходит с необработанными исключениями, которые не регистрируются с помощью log4j?

Вы их потеряли. Логгеры, приятные вещи, которые вы можете сохранять журналы в том месте, где вам нужно, и использовать фильтры, чтобы получать только актуальные журналы.

0 голосов
/ 05 ноября 2011

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

Да, это несколько многословно, чтобы объявить все методы как throws MyException.По этой причине Spring (который вы используете) предпочитает работать с непроверенными исключениями.Кстати, это новая функция в Java 7: вы можете игнорировать исключения, не заявляя, что метод их выбрасывает.

Я считаю, что нам все еще нужны проверенные исключения для разработки библиотек, предоставляющих API сторонним приложениям.Исключения прикладного уровня должны быть в основном во время выполнения и находиться в одном центральном месте.

...