3

我正在使用 AWS Java SDK v1,并且正在尝试使用构建器创建 AmazonS3 实例。我在此处遵循 AWS 文档中的指南,并使用 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变量之前,有一个步骤checkPackageAccess()被调用,这个返回值是什么由于某种原因被退回。经过进一步检查,我发现这checkPackageAccess()是 java.lang.ClassLoader 中的一个方法,它被 JVM 调用,并且它具有 void 返回类型。在我的应用程序中,似乎没有设置默认的 SecurityManager,因此在 ClassLoader 的checkPackageAccess()方法中没有调用其他函数。

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

我之前在同一个项目中使用几乎相同的代码制作了一个 AmazonRedshift 实例,并且运行顺利,所以我很肯定问题出在 AmazonS3 类或构建器上,但我不确定我在哪里'没有看到任何错误或奇怪的打印。

用于与 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);

有没有人调试过这种问题?我能做些什么来解决这个问题并取回一个有效的实例?

4

2 回答 2

1

这个问题最终变得更加根本。写到这里,我几乎感到尴尬。我必须用另一双眼睛看我的代码才能找到它,但我在 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 对象的代码时,持有对它的引用的局部变量已经超出范围。不敢相信我没有抓住这个。

于 2017-04-03T14:32:52.413 回答
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 中。

于 2017-03-30T21:05:53.647 回答