[JAVA-1271] Java driver does not clean up thread resources (sometimes) Created: 11/Jun/14 Updated: 19/Oct/16 Resolved: 19/Oct/16 |
|
| Status: | Closed |
| Project: | Java Driver |
| Component/s: | Error Handling |
| Affects Version/s: | 2.12.0 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Minor - P4 |
| Reporter: | Chris LeCompte | Assignee: | Unassigned |
| Resolution: | Won't Fix | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
Tomcat 7.0.27 |
||
| Description |
|
In the case of a RuntimeException such as a ClassNotFoundException, the Java driver may not clean up all of its resources, in particular the non-daemon threads used for pool eviction (the PooledConnectionProvider.sizeMaintenanceTimer). This can cause web containers such as Tomcat to fail to shut down properly. The scenario is as follows: 1. Deploy a web application which deploys a MongoClient connected to a 3 node replica set. Even though MongoClient.close is called by the application, some threads will remain. Any replica set polling threads other than the primary along with threads for maintaining the pools. What happens here is the following: 1. MongoClient.close() is called The PooledConnectionProvider should ensure that all threads created are shut down regardless of failures in the pool.close method. Likewise the other close methods should insulate themselves from such failures. Also, the threads Timer threads spawned for pool eviction should probably be set as daemon threads to avoid shutdown issues. |
| Comments |
| Comment by Jeffrey Yemin [ 19/Oct/16 ] |
|
I don't see a way to fix this in the general case, as a ClassNofFoundException could potentially be thrown at any level, even before we get to the PooledConnectionProvider.close() method. So insulating that method against failure doesn't guarantee that it will get called in the first place. Since a Tomcat upgrade has mitigated the issue for you, and as no one else has reported this, I'm going to close as Won't Fix. If it comes up for other users we can re-open it. |
| Comment by Chris LeCompte [ 12/Jun/14 ] |
|
The application is calling MongoClient.close() as part of a destroy method of a singleton bean in a spring context. The problem wasn't that classes were being unloaded but not loaded in the first place and since the file handle has been removed (the original webapp deleted) the loading of the class fails. There is no stack trace since the exception is swallowed up by: try { _connector.close(); }catch (final Throwable t) { /* nada */ }in Mongo.close(). An upgrade of tomcat seems to have mitigated although presumably it could still surface in other albeit rare cases. It would probably make more sense to shut down the maintenance timer before closing the pool as well since there's a bit of a race condition between shutting down the pool completely and the running of the maintenance task. |
| Comment by Jeffrey Yemin [ 12/Jun/14 ] |
|
It's not clear to me why Tomcat starts unloading classes before MongoClient.close() completes. Where is the application calling MongoClient.close() from? Do you have a stack trace? |