Hello,
When an InterruptedException is catched, the Thread#interrupted flag is reset to false (native java behavior). The exception should either be rethrown without wrapping or the Thread should be reinterrupted.
Here is what Sonarqube has to say about this:
There are many interrupted exceptions in this project that swallow the InterruptedException without reinterrupting the Thread.
A concrete issue caused by this behavior
Considering this Thread root loop:
while (!Thread.currentThread().isInterrupted()) {
List<FileNotifyInformation> notifications;
try {
notifications = watcher.watch();
} catch (CIFSException e) {
// Issue 1: we also trap InterruptedException
// Issue 2: the while condition will still evaluate to true because the Thread was not reinterrupted after catching InterruptedException
LOG.error(e.getMessage, e);
continue;
}
// Do something
}
We catch CIFSException to try to reestablish an eventual lost connection on the next loop iteration.
While blocked on SmbWatchHandleImpl#watch, if the Thread is interrupted, we obtain the following stacktrace:
jcifs.smb.SmbException: java.lang.InterruptedException
2026-03-13T09:49:05.231020547Z at jcifs.smb.SmbTransportImpl.send(SmbTransportImpl.java:1585)
2026-03-13T09:49:05.231022352Z at jcifs.smb.SmbSessionImpl.send(SmbSessionImpl.java:409)
2026-03-13T09:49:05.231023790Z at jcifs.smb.SmbTreeImpl.send(SmbTreeImpl.java:472)
2026-03-13T09:49:05.231025314Z at jcifs.smb.SmbTreeConnection.send0(SmbTreeConnection.java:404)
2026-03-13T09:49:05.231026743Z at jcifs.smb.SmbTreeConnection.send(SmbTreeConnection.java:318)
2026-03-13T09:49:05.231028487Z at jcifs.smb.SmbTreeConnection.send(SmbTreeConnection.java:298)
2026-03-13T09:49:05.231030054Z at jcifs.smb.SmbTreeHandleImpl.send(SmbTreeHandleImpl.java:130)
2026-03-13T09:49:05.231031580Z at jcifs.smb.SmbWatchHandleImpl.watch(SmbWatchHandleImpl.java:99)
2026-03-13T09:49:05.231033157Z at com.aqme.SmbFolderWatcher.watch(SmbFolderWatcher.java:60)
2026-03-13T09:49:05.231034759Z at com.aqme.SmbFolderWatcher.lambda$new$0(SmbFolderWatcher.java:42)
2026-03-13T09:49:05.231036378Z at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
2026-03-13T09:49:05.231037903Z at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
2026-03-13T09:49:05.231039454Z at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
2026-03-13T09:49:05.231041058Z at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
2026-03-13T09:49:05.231042573Z at java.base/java.lang.Thread.run(Thread.java:840)
2026-03-13T09:49:05.231044099Z Caused by: jcifs.util.transport.TransportException: java.lang.InterruptedException
2026-03-13T09:49:05.231045656Z at jcifs.util.transport.Transport.sendrecv(Transport.java:246)
2026-03-13T09:49:05.231047143Z at jcifs.smb.SmbTransportImpl.sendrecv(SmbTransportImpl.java:1012)
2026-03-13T09:49:05.231055714Z at jcifs.smb.SmbTransportImpl.send(SmbTransportImpl.java:1578)
2026-03-13T09:49:05.231057733Z ... 14 common frames omitted
2026-03-13T09:49:05.231059325Z Caused by: java.lang.InterruptedException: null
2026-03-13T09:49:05.231060887Z at java.base/java.lang.Object.wait(Native Method)
2026-03-13T09:49:05.231062383Z at java.base/java.lang.Object.wait(Object.java:338)
2026-03-13T09:49:05.231063864Z at jcifs.util.transport.Transport.waitForResponses(Transport.java:370)
2026-03-13T09:49:05.231065415Z at jcifs.util.transport.Transport.sendrecv(Transport.java:232)
2026-03-13T09:49:05.231066975Z ... 16 common frames omitted
Because of this, our loop needs to distinguish InterruptedException from the other CIFSException. But given the current state of this project, one has to walk the CIFSException stacktrace to find InterruptedException.
Hello,
When an
InterruptedExceptionis catched, theThread#interruptedflag is reset to false (native java behavior). The exception should either be rethrown without wrapping or theThreadshould be reinterrupted.Here is what Sonarqube has to say about this:
There are many interrupted exceptions in this project that swallow the
InterruptedExceptionwithout reinterrupting the Thread.A concrete issue caused by this behavior
Considering this
Threadroot loop:We catch
CIFSExceptionto try to reestablish an eventual lost connection on the next loop iteration.While blocked on
SmbWatchHandleImpl#watch, if theThreadis interrupted, we obtain the following stacktrace:Because of this, our loop needs to distinguish
InterruptedExceptionfrom the otherCIFSException. But given the current state of this project, one has to walk theCIFSExceptionstacktrace to findInterruptedException.