A discussion in Code Review chat determined the following behaviour from a ScheduledExecutorService:
A task scheduled to run fails with a 'serious' problem, but there's no report, exception, or log of the problem. In other contexts, the application would normally terminate with an Error. In the context of the ScheduledExecutorService, though, there is no Exception/Error 'handling' at all.
First, to fabricate a problem. The following class has a static initializer that is guaranteed to fail:
public class InitializerFault {
private static final int value = Integer.parseInt("fubar");
@Override
public String toString() {
return "" + value;
}
}
When run as:
public static void main(String[] args) {
System.out.println(new InitializerFault());
}
it produces (which is exactly what I would expect):
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
But, when run as:
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");
}
it produces just:
Built thread Thread[TestThread,5,main]
Exiting
There is no mention of any error, no fault, no dump, nothing. This ExceptionInInitializerError has resulted in a complicated real-life debug process, where the problem was very hard to isolate.
Two questions:
ScheduledExecutorService.scheduleAtFixedRate
returns a ScheduledFuture
. If we call ScheduledFuture.get()
the thread will block and wait for the periodic task completion, which may happen upon task cancellation or if the task throws an exception. In the latter case get() will throw java.util.concurrent.ExecutionException
with wrapped original exception
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With