When the JVM is stopped using SIGINT, Boot's shutdown hook runs and closes the application context. Class loading that occurs during this close processing may fail due to a thread being interrupted while calling FileChannel.read(ByteBuffer, long). The interruption causes the read to close the channel and fail with a ClosedByInterruptException. This leaves FileChannelDataBlock with a FileChannel that should be open according to its reference count but isn't.

Comment From: wilkinsona

Possible fix: https://github.com/wilkinsona/spring-boot/tree/gh-38154

Comment From: philwebb

The tracker stuff is only used in tests to I think we could get away without tracking the reopen if want to.

Comment From: wilkinsona

Thanks for having a look, Phil. I think I might be confused looking at the code in the future if we omit the tracking so I'd prefer to keep it. I've pushed a commit that refines the fix as I think it was a mistake to reset the thread's interrupted flag and retry the read. Instead, we now just repair the file channel and re-throw the exception. This allows the interruption on the current thread to continue will also ensuring that the file channel is usable on other threads. I've tested it with @onobc's sample that brought the problem to my attention and it seems to work.

Comment From: onobc

Thanks for the quick turnaround @wilkinsona and @philwebb I will pickup the SNAPSHOT and verify it w/ Spring for Apache Pulsar.