Обсуждение в чате обзора кода определило следующее поведение из ScheduledExecutorService:
Запланированная задача не работает с серьезной проблемой, но нет отчета, исключения или журнала проблемы. В других контекстах приложение обычно заканчивается ошибкой. В контексте ScheduledExecutorService, однако, вообще нет обработки "Исключение/ошибка".
Во-первых, чтобы создать проблему. Следующий класс имеет статический инициализатор, который гарантированно завершится неудачей:
public class InitializerFault {
private static final int value = Integer.parseInt("fubar");
@Override
public String toString() {
return "" + value;
}
}
При запуске как:
public static void main(String[] args) {
System.out.println(new InitializerFault());
}
он производит (именно это я и ожидал):
Exception in thread "main" java.lang.ExceptionInInitializerError
at SimpleHandler.main(SimpleHandler.java:5)
Caused by: java.lang.NumberFormatException: For input string: "fubar"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at InitializerFault.<clinit>(InitializerFault.java:4)
... 1 more
Но при запуске как:
private static final Thread buildThread(Runnable r) {
Thread t = new Thread(r, "TestThread");
t.setDaemon(true);
System.out.println("Built thread " + t);
return t;
}
public static void main(String[] args) throws InterruptedException {
// use a thread factory to create daemon threads ... can be non-daemon as well.
ScheduledExecutorService ses = Executors.newScheduledThreadPool(
2, (r) -> buildThread(r));
ses.scheduleAtFixedRate(
() -> {System.out.println(new InitializerFault());},
500, 1000, TimeUnit.MILLISECONDS);
Thread.sleep(3000);
System.out.println("Exiting");
}
он производит только:
Built thread Thread[TestThread,5,main]
Exiting
Не упоминается ни об ошибках, ни об ошибках, ни о дампе, ничего. Этот ExceptionInInitializerError привел к сложному процессу отладки в реальной жизни, где проблему очень сложно изолировать.
Два вопроса:
- - это ожидаемое поведение Java, что ошибки в исполнителя игнорируются?
- Какой правильный способ справиться с этой ситуацией?