AmazonS3Builder生成有效的AmazonS3对象,但最终返回null

时间:2017-03-30 17:09:52

标签: java amazon-s3 aws-java-sdk

我正在使用AWS Java SDK v1,并尝试使用构建器创建AmazonS3实例。我遵循AWS文档here中的指南并使用BasicAWSCredentials对象传递显式凭据。当构建器构建时,我得到一个空客户端回到s3Client,这是我存储实例的地方,我不知道为什么。 try-catch块没有抛出或捕获的错误。以下是我建立连接的方式:

    BasicAWSCredentials awsCreds = null;
    try {
        awsCreds = new BasicAWSCredentials(settings.getAccessKey(), settings.getSecretKey());
    } catch (Exception e) {
        e.printStackTrace();
        throw new IOException(e.getMessage());
    }

    try {
        AmazonS3 s3Client = AmazonS3Client.builder()
                .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                .withRegion(Regions.US_EAST_1)
                .build();
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println(s3Client);

我已经使用Eclipse调试器逐步完成了它,看起来build()调用实际上正在返回一个有效的AmazonS3Client实例,但是在此引用返回到s3Client变量之前,那里&# 39;调用checkPackageAccess()的步骤,此返回值是由于某种原因返回的值。在进一步检查时,我发现checkPackageAccess()是java.lang.ClassLoader中的一个被JVM调用的方法,它有一个void返回类型。在我的应用程序中,看起来没有设置默认的SecurityManager,因此在ClassLoader的checkPackageAccess()方法中没有其他函数调用。

我对这种行为感到有点困惑。我的JRE是1.8。据我所知,在查找类定义时总是调用ClassLoader,但是为什么在类已经实例化之后调用它,为什么build()函数的原始返回值不会返回到调用者上下文?在这种情况下,调试器显示存在有效的AmazonS3Client对象,即使在checkPackageAccess调用之前,调用也会返回build()

我之前在同一个项目中创建了一个几乎完全相同代码的AmazonRedshift实例,并且顺利运行,所以我非常肯定问题出在AmazonS3类或构建器上,但我和#39;我不知道在哪里,我没有看到任何错误或奇怪的打印。

用于与Amazon Redshift建立类似连接的代码:

        BasicAWSCredentials awsCreds = null;
    try {
        awsCreds = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
    } catch (Exception e) {
        e.printStackTrace();
        throw new IOException(e.getMessage());
    }
    try {
        client = AmazonRedshiftClientBuilder.standard()
                                .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                                .withRegion(Regions.US_EAST_1)
                                .build();
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println(client);

以前有人调试过这类问题吗?我该怎么做才能解决这个问题并找回有效的实例?

2 个答案:

答案 0 :(得分:0)

您是否愿意从自己的类而不是S3Client方法builder()构建构建器?以下代码与您的Redshift案例相似,对我来说没问题。

    static final String BUCKET_NAME = "hello-world";

    /** Creates bucket
    @param args Command line arguments*/
    public static void main(final String[] args) {

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

            CreateBucketRequest request = new
                    CreateBucketRequest(BUCKET_NAME);

            Bucket bucket = s3.createBucket(request);

    System.out.println("S3 Hello World completed.");

对于它的价值,我的编译器找不到静态builder()方法,尽管它确实在API中。

答案 1 :(得分:0)

问题最终变得更加根本。写这篇文章让我感到尴尬。我必须在我的代码上找到第二双眼睛才能找到它,但我在try块中重新声明了s3Client。

private AmazonS3 s3Client = null;

...

BasicAWSCredentials awsCreds = null;
try {
    awsCreds = new BasicAWSCredentials(settings.getAccessKey(), settings.getSecretKey());
} catch (Exception e) {
    e.printStackTrace();
    throw new IOException(e.getMessage());
}

try {
    AmazonS3 s3Client = AmazonS3Client.builder()
            .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
            .withRegion(Regions.US_EAST_1)
            .build();
} catch (Exception e) {
    e.printStackTrace();
}
System.out.println(s3Client);

当它到达实际使用AmazonS3对象的代码时,持有对它的引用的局部变量已经超出了范围。无法相信我没有抓住这一点。