I have following code with a try-with-resources which creates two resources and it works fine:
public class SimpleResourceExample {
public static void main(String... args) {
try (var resource1 = new Resource(1);
var resource2 = new Resource(2)) {
System.out.println("Using "+resource1 +" and "+resource2);
Thread.sleep(20 * 1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
private record Resource(int id) implements AutoCloseable {
@Override
public void close() {
System.out.println("Closing resource "+id);
}
}
}
So when I run it I get following output (in 20 seconds):
Using Resource[id=1] and Resource[id=2]
Closing resource 2
Closing resource 1
Process finished with exit code 0
And when I add below code (in main()
, just before try-with-resources), to interrupt the thread, it also works fine:
var t = Thread.currentThread();
new Thread(() -> {
try {
Thread.sleep(10 * 1000);
t.interrupt();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
So this new thread interrupts the main thread after 10 seconds and the resources are also closed, with below output:
Using Resource[id=1] and Resource[id=2]
Closing resource 2
Closing resource 1
Exception in thread "main" java.lang.RuntimeException: java.lang.InterruptedException: sleep interrupted
at ....
Process finished with exit code 1
(stack trace omitted for brevity)
But when I introduce a shutdown-hook with below code:
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("Shutting down");
t.interrupt();
}));
And trigger it with this command:
kill -15 <PID>
I get following output:
Using Resource[id=1] and Resource[id=2]
Shutting down
Process finished with exit code 143 (interrupted by signal 15:SIGTERM)
This means it gets the signal and stops the application. And I think it also sends the interrupt to the main thread, but it doesn’t close resources.
Does anybody why this happens and how to ensure the resources are closed?
Thanks.