Vincent Jørgensen
Vincent Jørgensen

Reputation: 111

AWS S3 Java SDK upload fails with "Connection pool shutdown" in Groovy

I am using the Amazon Java SDK (that latest is version 1.11.147 as of this writing) with Groovy (Groovy Version: 2.4.11 JVM: 1.8.0_112 Vendor: Oracle Corporation OS: Mac OS X) to upload files to S3. Using the instructions from Amazon's documentation for a Transfer Manager, I was able to copy contents from one bucket to another. However, uploading always fails. I attempted the the following 3 methods. I have Grapes grab new versions of httpclient and httpcore because of what I read at the this Stack Overflow Post Apache PoolingHttpClientConnectionManager throwing illegal state exception

@Grapes([
  @Grab(group='com.amazonaws', module='aws-java-sdk', version='1.11.147'),
  // https://mvnrepository.com/artifact/org.apache.commons/commons-compress
  @Grab(group='org.apache.commons', module='commons-compress', version='1.13'),
  // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
  @Grab(group='org.apache.httpcomponents', module='httpclient', version='4.5.3'),
  // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore
  @Grab(group='org.apache.httpcomponents', module='httpcore', version='4.4.6')
])

// creds is String saying which ~/.aws/credentials profile to use
def credentials = new ProfileCredentialsProvider(creds)

def s3client  = AmazonS3ClientBuilder.standard().
                withCredentials(credentials).
                withRegion(region).
                build()
def tx = TransferManagerBuilder.standard().
         withS3Client(s3client).
         build()

def config_path = "/path/to/my/root"
def dir = "key_path"
def f = new File("${config_path}/${dir}/")

// Method 1, upload whole directory in one call
def mfu = tx.uploadDirectory(data_bucket, dir, f, true)
mfu.waitForCompletion() // <-- throws exception, w/o this line, just doesn't upload, but script continues


// Method 2, upload each file separately
def ld
ld = { File file ->
  file.listFiles().each { g ->
    if (g.isDirectory()) {
      ld.call(g)
    } else {
      def key = g.toString().substring(config_path_length)
        def fu = tx.upload(data_bucket, key, g)
      def fu = tx.upload(data_bucket, key, g)
      fu.waitForCompletion() // <-- throws exception, w/o this line, just doesn't upload, but script continues
    }
  }
}
ld.call(f)

// Finally Method 3, avoiding TransferManager altogether, and call putObject directly on each file
def ld
ld = { File file ->
  file.listFiles().each { g ->
    if (g.isDirectory()) {
      ld.call(g)
    } else {
      def key = g.toString().substring(config_path_length)
        def fu = tx.upload(data_bucket, key, g)
      s3client.putObject(new PutObjectRequest(data_bucket, key, g)) // <-- throws exception
    }
  }
}
ld.call(f)

However, no matter which method I try, I always get the following stacktrace:

Caught: java.lang.IllegalStateException: Connection pool shut down java.lang.IllegalStateException: Connection pool shut down at org.apache.http.util.Asserts.check(Asserts.java:34) at org.apache.http.pool.AbstractConnPool.lease(AbstractConnPool.java:184) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection(PoolingHttpClientConnectionManager.java:251) at com.amazonaws.http.conn.ClientConnectionManagerFactory$Handler.invoke(ClientConnectionManagerFactory.java:76) at com.amazonaws.http.conn.$Proxy11.requestConnection(Unknown Source) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:175) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55) at com.amazonaws.http.apache.client.impl.SdkHttpClient.execute(SdkHttpClient.java:72) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1190) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1030) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:742) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:716) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667) at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649) at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513) at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4221) at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4168) at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1718) at com.amazonaws.services.s3.AmazonS3$putObject.call(Unknown Source) ...

I am unable at this time to confirm whether groovy is using the updated httpcomponent libraries, or if that is the problem. Installed in the 1.8 JDK are httpclient_4.2.6 and httpclient_4.3.5. Any suggestions for how to get unstuck would be greatly appreciated. Thank you. -Vincent

Upvotes: 5

Views: 11267

Answers (1)

Vincent J&#248;rgensen
Vincent J&#248;rgensen

Reputation: 111

I figured it out. the s3client had another TranferManager attached to it elsewhere in the code. when tx.shutdownNow() was called, it closed this TransferManager as well.

Upvotes: 5

Related Questions