Могут ли реализации Handler.publish () вызывать исключения времени выполнения?

У меня вопрос по java.util.logging.Handler:

Разрешено ли реализации этого абстрактного метода генерировать исключения RuntimeExceptions или всегда следует сообщать диспетчеру ошибок?

В документации не указывается, но другие методы в классе явно указывают, что они могут выбросить:

public abstract void publish (LogRecord record) Опубликовать LogRecord. Запрос на ведение журнала изначально был направлен объекту Logger, который инициализировал LogRecord и отправил его сюда.

Обработчик отвечает за форматирование сообщения, когда и если это необходимо. Форматирование должно включать локализацию.

Параметры: запись - описание события журнала. Пустая запись игнорируется и не публикуется.

[Ссылка: https://docs.oracle.com/javase/7/docs/api/java/util/logging/Handler.html#publish(java.util.logging.LogRecord)]


person Uri    schedule 18.02.2016    source источник


Ответы (1)


Это тот случай, когда спецификация API не всегда соответствует реализации. Неписаные правила исходного кода выглядят так:

  1. Обработка нулевой записи может быть враждебной или игнорироваться. Подклассы StreamHandler игнорируют null и MemoryHandler не настроен враждебно. Регистратор никогда не передает null для публикации, поэтому на самом деле не имеет значения, что вы выберете.
  2. Любое исключение времени выполнения, выброшенное из isLoggable, ускользнет от обработчика. Это означает, что любое исключение, созданное фильтром, ускользает от метода публикации и не перехватывается диспетчером ошибок. Обратите внимание на отсутствие перечисления ErrorManager.FILTER_FAILURE, так что это означает, что поведение является преднамеренным.
  3. Исключения, которые публикация не должна создавать, перечислены в документации ErrorManager. В большинстве случаев возникают ошибки форматирования и записи.

На самом деле публикация должна делегироваться диспетчеру ошибок, чтобы определить, создает ли исключения или нет. Из Документация по Handler.setErrorManager:

Метод «error» ErrorManager будет вызываться, если при использовании этого Handler возникнут какие-либо ошибки.

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

Если вы хотите получить исключение через Handler.reportError, вам нужно использовать скрытный бросок.

public class HostileErrorManager extends ErrorManager {

    @Override
    public void error(String msg, Exception ex, int code) {
        sneakyThrow(new Throwable(msg + ": " + code, ex));
    }

    @SuppressWarnings("unchecked")
    private <T extends RuntimeException> void sneakyThrow(Throwable t) throws T {
        throw (T) t;
    }
}
person jmehrens    schedule 19.02.2016