woddle
woddle

Reputation: 1622

AWS SDK - AmazonS3Client doesn't shutdown

I find that creating an AmazonS3Client means my process hangs around even when it's doing nothing. I'm doing a file upload, but I've trimmed it down to just this.

When I run the following code (with working credentials) it prints "Simple is finished" but the process doesn't exit until eventually maven:exec tells me:

Simple is finished
[WARNING] thread Thread[java-sdk-http-connection-reaper,5,Simple] was interrupted but is still alive after waiting at least 15000msecs
[WARNING] thread Thread[java-sdk-http-connection-reaper,5,Simple] will linger despite being asked to die via interruption
[WARNING] NOTE: 1 thread(s) did not finish despite being asked to  via interruption. This is not a problem with exec:java, it is a problem with the running code. Although not serious, it should be remedied.
[WARNING] Couldn't destroy threadgroup org.codehaus.mojo.exec.ExecJavaMojo$IsolatedThreadGroup[name=Simple,maxpri=10]
java.lang.IllegalThreadStateException

The code:

    import com.amazonaws.auth.AWSCredentials;
    import com.amazonaws.auth.BasicAWSCredentials;
    import com.amazonaws.services.s3.AmazonS3;
    import com.amazonaws.services.s3.AmazonS3Client;

    public class Simple {

        private static String accessKey = "XXX";
        private static String secretKey = "ZZZ";

        public static void main(String[] args) {

            AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
            AmazonS3 s3client = new AmazonS3Client(credentials);
            System.out.println("Simple is finished");        
        }

    }

Is it supposed to work like this? Is there a way to kill it off?

edit: add version information:

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk</artifactId>
    <version>1.9.33</version>
</dependency>

Upvotes: 3

Views: 5301

Answers (3)

smw
smw

Reputation: 21

I wanted to give a little more context on the answer that recommends this solution, since I can't comment:

((AmazonS3Client) s3client).shutdown();

According to the aws developer guide, connection pool resources aren't actually cleaned up until the client is garbage collected. Calling shutdown forces the client to release its resources, which is why this solution works.

Here's the shutdown method from AmazonWebServiceClient.java (parent class of AmazonS3Client):

/**
 * Shuts down this client object, releasing any resources that might be held
 * open. This is an optional method, and callers are not expected to call
 * it, but can if they want to explicitly release any open resources. Once a
 * client has been shutdown, it should not be used to make any more
 * requests.
 */
public void shutdown() {
    client.shutdown();
}

Upvotes: 2

Ben B
Ben B

Reputation: 88

The above solutions work, here's two others:

  • Make a manual call to System.gc() (after AmazonS3 is out of scope)
  • or, add flag exec.cleanupDaemonThreads=false when running maven

I ran into the same issue. The AmazonS3Client actually will get cleaned up by garbage collection if GC runs; however, depending on your jvm, that might never happen. In my case, even running with -Dexec.daemonThreadJoinTimeout=-1, which makes maven wait indefinitely for threads to close, it never closes.

aws-java-sdk-s3 version 1.10.24

Upvotes: 1

woddle
woddle

Reputation: 1622

Either of these seems to work:

((AmazonS3Client) s3client).shutdown();

or

try {
    com.amazonaws.http.IdleConnectionReaper.shutdown();
} catch (Throwable t) {
    // etc
}

Although I'm not sure how correct they are.

Upvotes: 6

Related Questions