'Shutdown IdleConnectionReaper in AWS Java SDK v2
I'm using S3Client from Java SDK v2. to upload/download files from AWS S3 in a distributed web application.
I had a problem with idle-connection-reaper
daemon thread preventing/delaying the class from being unloaded during shutdown. I did some investigations and I figured out that in AWS Java SDK v1, this could be resolved by calling IdleConnectionReaper.shutdown()
method.
I imported apache client to my project
<!-- https://mvnrepository.com/artifact/software.amazon.awssdk/apache-client -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>apache-client</artifactId>
<version>2.17.162</version>
</dependency>
And I would like to do the same thing using AWS Java SDK v2. The problem is that shutdown()
method is no longer static and exposed.
They changed the class to a Singleton and the only exposed APIs are:
public synchronized boolean registerConnectionManager(HttpClientConnectionManager manager, long maxIdleTime)
public synchronized boolean deregisterConnectionManager(HttpClientConnectionManager manager)
deregisterConnectionManager()
calls shutdown internally but I don't know what HttpClientConnectionManager
I should give as an argument for both methods
My question is: Is there another approach to shutdown that daemon thread or I should stick to the new implementation of IdleConnectionReaper
? If so, what are exactly HttpClientConnectionManager
parameter in both registerConnectionManager
and deregisterConnectionManager
methods?
Solution 1:[1]
You shouldn't need to interact with the v2 IdleConnectionReaper
anymore, and that's why the public interface has changed to reflect this.
There is a key difference between AWS Java SDK v1 & v2 in regards to the S3 client.
V1's AmazonS3Client
implements the AmazonS3
custom interface which provides the shutdown
method to be implemented.
This wasn't enforced & was an optional method so I assume the daemon thread was needed to prevent leaks in case the S3 client was not closed at all anywhere.
V2's S3Client
implements the AutoClosable
interface, an inherent interface in java.lang
after version 7.
With AutoClosable
, the AWS SDK is clearly communicating the expectation of your application managing the closing & cleanup of the S3 client. This is preferably done by delegating the closing of the client to the JVM by enclosing it in a try-with-resources statement or if needs be, explicitly via S3Client.close()
.
The AWS Java SDK v2 utilises newer features of the Java language & as such, it expects you to handle your resources correctly in line with modern Java development practices.
Close your S3 client objects (& object content streams!) correctly & you will be fine.
Solution 2:[2]
Just more analysis: The inner ReaperTask has a 1 minute sleep time during which it doesn't check its 'stopping' flag - hence it does not realize it should shut down. However it will be interrupted/shut down once the last connection manager is reregistered.
On my side the issue was using the SDK builder with an injected HttpClient (also built by an SDK builder). This causes a wrapper around it, preventing deregistering on close of the outer client.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |