In one of our (commandline) applications that is using BagIt as a dependency, we noticed the application hanging on termination. After hanging for exactly 60 seconds the process is killed automatically by the JVM. This behavior occurred after upgrading to BagIt 5.x.
- After some digging around, I found that this behavior was ultimately caused by
BagVerifier.isValid.
- This class has an
ExecutorService with a that is used twice in isValid, namely in the two subcalls to checkHashes. I mention this especially because the ExecutorService is closed by calling shutdown inside finalize, which is one of those 'forbidden' methods to override in Java...
- However, even without these two calls, the application keeps showing the described behavior. We can further trace this to the first call in
isValid: isComplete.
- After doing some interaction with
MandatoryVerifier (which do not cause the described behavior), this method calls PayloadVerifier.verifyPayload. Just as BagVerifier, this class has an ExecutorService that is closed by calling shutdown inside finalize!
PayloadVerifier.verifyPayload first calls getAllFilesListedInManifests which works correctly (it does not cause the described behavior). After that, it takes the result from this call and uses it in checkAllFilesListedInManifestExist, where the ExecutorService of this class is used. This call causes the described behavior!
- When this method is altered, however, such that the
ExecutorService is not used (a.k.a. all tasks are executed using the underlying Runnable.run() method), the described behavior does not occur...
I have a suspicion that the finalize method in PayloadVerifier (and BagVerifier) are causing the hanging behavior. When running the application with a debugger attached, the finalize methods of either class are never called... Could it be the case that this ExecutorService therefore leaves a number of threads open, which block the termination process?
Full disclosure: the project I'm talking about is demonstrating this behavior since DANS-KNAW/easy-bag-store#29 (or this commit), which upgrades the code to BagIt 5.x. The specific call that causes this behavior can be found here.
If you need more information or you want me to test something, please let me know! I'll be happy to help out.
In one of our (commandline) applications that is using BagIt as a dependency, we noticed the application hanging on termination. After hanging for exactly 60 seconds the process is killed automatically by the JVM. This behavior occurred after upgrading to BagIt 5.x.
BagVerifier.isValid.ExecutorServicewith a that is used twice inisValid, namely in the two subcalls tocheckHashes. I mention this especially because theExecutorServiceis closed by callingshutdowninsidefinalize, which is one of those 'forbidden' methods to override in Java...isValid:isComplete.MandatoryVerifier(which do not cause the described behavior), this method callsPayloadVerifier.verifyPayload. Just asBagVerifier, this class has anExecutorServicethat is closed by callingshutdowninsidefinalize!PayloadVerifier.verifyPayloadfirst callsgetAllFilesListedInManifestswhich works correctly (it does not cause the described behavior). After that, it takes the result from this call and uses it incheckAllFilesListedInManifestExist, where theExecutorServiceof this class is used. This call causes the described behavior!ExecutorServiceis not used (a.k.a. all tasks are executed using the underlyingRunnable.run()method), the described behavior does not occur...I have a suspicion that the
finalizemethod inPayloadVerifier(andBagVerifier) are causing the hanging behavior. When running the application with a debugger attached, thefinalizemethods of either class are never called... Could it be the case that thisExecutorServicetherefore leaves a number of threads open, which block the termination process?Full disclosure: the project I'm talking about is demonstrating this behavior since DANS-KNAW/easy-bag-store#29 (or this commit), which upgrades the code to BagIt 5.x. The specific call that causes this behavior can be found here.
If you need more information or you want me to test something, please let me know! I'll be happy to help out.