76

I'm trying to read the files available on Amazon S3, as the question explains the problem. I couldn't find an alternative call for the deprecated constructor.

Here's the code:

private String AccessKeyID = "xxxxxxxxxxxxxxxxxxxx";
private String SecretAccessKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
private static String bucketName     = "documentcontainer";
private static String keyName     = "test";
//private static String uploadFileName    = "/PATH TO FILE WHICH WANT TO UPLOAD/abc.txt";

AWSCredentials credentials = new BasicAWSCredentials(AccessKeyID, SecretAccessKey);

void downloadfile() throws IOException
{

    // Problem lies here - AmazonS3Client is deprecated
    AmazonS3 s3client = new AmazonS3Client(credentials);
        try {
        System.out.println("Downloading an object...");
        S3Object s3object = s3client.getObject(new GetObjectRequest(
                bucketName, keyName));
        System.out.println("Content-Type: "  +
                s3object.getObjectMetadata().getContentType());
        InputStream input = s3object.getObjectContent();

        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        while (true) {
            String line = reader.readLine();
            if (line == null) break;

            System.out.println("    " + line);
        }
        System.out.println();
    } catch (AmazonServiceException ase) {
          //do something
    } catch (AmazonClientException ace) {
        // do something
    }
 }

Any help? If more explanation is needed please mention it. I have checked on the sample code provided in .zip file of SDK, and it's the same.

J.A.I.L.
  • 10,644
  • 4
  • 37
  • 50
Asif Ali
  • 1,422
  • 2
  • 12
  • 28

7 Answers7

150

You can either use AmazonS3ClientBuilder or AwsClientBuilder as alternatives.

For S3, simplest would be with AmazonS3ClientBuilder.

BasicAWSCredentials creds = new BasicAWSCredentials("access_key", "secret_key"); 

AmazonS3 s3Client = AmazonS3ClientBuilder
    .standard()
    .withCredentials(new AWSStaticCredentialsProvider(creds))
    .build();
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
franklinsijo
  • 17,784
  • 4
  • 45
  • 63
  • 2
    Was there any reason behind this deprecation, are there any benefits of using AmazonS3ClientBuilder.standard() vs new AmazonS3Client (from the previous SDKs) – rockstarjindal May 18 '17 at 14:16
  • 2
    Both `AmazonS3ClientBuilder` and `AwsClientBuilder` are not present in the latest NuGet packages for .Net 4.0, but various methods are depreciated including `StoredProfileAWSCredentials` (which I am currently using). Does anyone know the recommended approach for .Net 4.0? – bikeman868 Jul 25 '17 at 00:08
  • 4
    As you use AmazonS3ClientBuilder, myClient.setRegion() no longer works. You've got to AmazonS3ClientBuilder.standard().withCredential().withRegion("eu-west-1").build(); – user3526918 Oct 01 '17 at 14:48
  • AWSStaticCredentialsProvider is also depricated @franklinsijo – Amit Kumar Feb 08 '18 at 06:54
  • 1
    @rockstarjindal The client builder are better than old constructor in following ways. Clients created with builders are Immutable. Client must have explicit region. Builders provide a cleaner chaining API. – Priyadarshi Kunal Jul 25 '18 at 18:58
15

Use the code listed below to create an S3 client without credentials:

AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build();

An usage example would be a lambda function calling S3.

Dan Mandel
  • 637
  • 1
  • 8
  • 26
Sid
  • 693
  • 6
  • 8
  • thanks but only worked for me when i included withRegion() – Clive Sargeant Dec 29 '17 at 09:10
  • A client created via the builders must have a region that is defined either explicitly (i.e. by calling withRegion) or as part of the DefaultAwsRegionProviderChain. If the builder can’t determine the region for a client, an SdkClientException is thrown. – Priyadarshi Kunal Jul 25 '18 at 19:00
10

You need to pass the region information through the

com.amazonaws.regions.Region object.

Use AmazonS3Client(credentials, Region.getRegion(Regions.REPLACE_WITH_YOUR_REGION))
Abhay Pratap
  • 1,886
  • 11
  • 15
2

You can create S3 default client as follows(with aws-java-sdk-s3-1.11.232):

AmazonS3ClientBuilder.defaultClient();
Sach
  • 373
  • 3
  • 9
  • 1
    Where is it getting the credentials from? – JaviOverflow Aug 11 '18 at 09:53
  • From AWS documentaion at :https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html You can do this in the following ways: 1.Use the default credential provider chain (recommended). 2.Use a specific credential provider or provider chain. 3.Supply the credentials yourself. It is recommended to use IAM roles. E.g. for AWS lambda, create an IAM role which has access to S3 and create the client in lambda code. Supply this Role while configuring your lambda, similarly for EC2 instance or ECS etc. – Sach Aug 13 '18 at 01:51
  • 1
    could you explain this a little bit more? "1.Use the default credential provider chain" – JaviOverflow Aug 13 '18 at 07:43
2

Deprecated with only creentials in constructor, you can use something like this:

 val awsConfiguration = AWSConfiguration(context)
 val awsCreds = CognitoCachingCredentialsProvider(context, awsConfiguration)
 val s3Client = AmazonS3Client(awsCreds, Region.getRegion(Regions.EU_CENTRAL_1))
Siarhei
  • 2,358
  • 3
  • 27
  • 63
1

Using the AWS SDK for Java 2.x, one can also build its own credentialProvider like so:

// Credential provider

package com.myproxylib.aws;

import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;

public class CustomCredentialsProvider implements AwsCredentialsProvider {

    private final String accessKeyId;
    private final String secretAccessKey;

    public CustomCredentialsProvider(String accessKeyId, String secretAccessKey) {
        this.secretAccessKey = secretAccessKey;
        this.accessKeyId = accessKeyId;
    }

    @Override
    public AwsCredentials resolveCredentials() {
        return new CustomAwsCredentialsResolver(accessKeyId, secretAccessKey);
    }

}

// Crenditals resolver


package com.myproxylib.aws;

import software.amazon.awssdk.auth.credentials.AwsCredentials;

public class CustomAwsCredentialsResolver implements AwsCredentials {

    private final String accessKeyId;
    private final String secretAccessKey;

    CustomAwsCredentialsResolver(String accessKeyId, String secretAccessKey) {
        this.secretAccessKey = secretAccessKey;
        this.accessKeyId = accessKeyId;
    }

    @Override
    public String accessKeyId() {
        return accessKeyId;
    }

    @Override
    public String secretAccessKey() {
        return secretAccessKey;
    }
}

// Usage of the provider


package com.myproxylib.aws.s3;

public class S3Storage implements IS3StorageCapable {

    private final S3Client s3Client;

    public S3Storage(String accessKeyId, String secretAccessKey, String region) {

        this.s3Client = S3Client.builder().credentialsProvider(new CustomCredentialsProvider(accessKeyId, secretAccessKey)).region(of(region)).build();
    }

NOTE:

  1. of course, the library user can get the credentials from wherever he wants, parse it into a java Properties before calling the S3 constructor.

  2. When possible, favour the other methods mentionned in other answers and doc. My use case was necessary for this.

exaucae
  • 2,071
  • 1
  • 14
  • 24
0
implementation 'com.amazonaws:aws-android-sdk-s3:2.16.12'

val key = "XXX"
val secret = "XXX"
val credentials = BasicAWSCredentials(key, secret)
val s3 = AmazonS3Client(
    credentials, com.amazonaws.regions.Region.getRegion(
        Regions.US_EAST_2
    )
)
val expires = Date(Date().time + 1000 * 60 * 60)

val keyFile = "13/thumbnail_800x600_13_photo.jpeg"
val generatePresignedUrlRequest = GeneratePresignedUrlRequest(
    "bucket_name",
    keyFile
)
generatePresignedUrlRequest.expiration = expires
val url: URL = s3.generatePresignedUrl(generatePresignedUrlRequest)

GlideApp.with(this)
    .load(url.toString())
    .apply(RequestOptions.centerCropTransform())
    .into(image)