从 S3 下载对象的 AWS 错误,“配置文件不能为空”

我已经看到了这一点,但没有答案来解释我的问题。我首先使用了此处提供的示例(GetObject 类),它立即在我的桌面上工作。但是,我的朋友无法让它在他的机器上工作,也无法在我们的EC2实例上工作。

有人提到要指定凭证文件,这是有道理的,但我从未这样做过,并且我很确定默认设置了默认权限以允许访问此存储桶。

下面是堆栈跟踪:

Exception in thread "main" java.lang.IllegalArgumentException: profile file cannot be null
    at com.amazonaws.util.ValidationUtils.assertNotNull(ValidationUtils.java:37)
    at com.amazonaws.auth.profile.ProfilesConfigFile.<init>(ProfilesConfigFile.java:142)
    at com.amazonaws.auth.profile.ProfilesConfigFile.<init>(ProfilesConfigFile.java:133)
    at com.amazonaws.auth.profile.ProfilesConfigFile.<init>(ProfilesConfigFile.java:100)
    at com.amazonaws.auth.profile.ProfileCredentialsProvider.getCredentials(ProfileCredentialsProvider.java:135)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1029)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1049)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:949)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:662)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:636)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:619)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$300(AmazonHttpClient.java:587)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:574)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:446)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4035)
    at com.amazonaws.services.s3.AmazonS3Client.getBucketRegionViaHeadRequest(AmazonS3Client.java:4474)
    at com.amazonaws.services.s3.AmazonS3Client.fetchRegionFromCache(AmazonS3Client.java:4448)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4020)
    at com.amazonaws.services.s3.AmazonS3Client.getObject(AmazonS3Client.java:1307)
    at GetObject.main(GetObject.java:26)

我可以保证,GetObjectRequest 中的 bucketName 和 key 参数都不是 null。这里有什么差异?为什么它只能在我的电脑上成功?这是否与以下事实有关:我必须补充aws-sdk jar应该已经拥有的大量jar(jackson-databind,jackson-core,jackson-annotations,httpclient,httpcore,commons-logging和joda-time)?它似乎很相似,否则无法解释的错误(给出非空参数,aws-sdk中的某些东西说它是空的)。


答案 1

看起来你在评论中解决了这个问题,但我对此感到焦头烂额,并希望为未来的读者留下更清晰的答案。为了超级清楚,这里的问题与S3中的文件无关。此错误消息与硬盘驱动器上的文件无关,也与您尝试从 S3 推送/拉取的文件无关。问题是您正在使用如下内容初始化S3:

AmazonS3 s3Client = new AmazonS3Client(new ProfileCredentialsProvider());

执行此操作时,它会在 ~/.aws/credentials 中查找配置文件列表。这可能在您的计算机上效果很好,但在您通过 IAM 角色(例如 Lambda、Docker、EC2 实例等)获得 AWS 访问权限的任何地方都不起作用。修复程序是初始化AmazonS3Client,如下所示:

AmazonS3 s3Client = new AmazonS3Client();

如果使用的代码需要某种凭据提供程序,则还可以执行以下操作:

AmazonS3 s3Client = new AmazonS3Client(DefaultAWSCredentialsProviderChain.getInstance());

希望这对下一个人有所帮助。就我而言,我使用的是 DynamoDB 和 SQS,但我遇到了同样的错误。我最初忽略了这个问题,因为我认为您的问题与S3有关,并且非常困惑。手腕被拍打。

在较新版本的 SDK 上,您需要使用以下代码:

AmazonS3 s3Client = AmazonS3ClientBuilder.standard()                  
                      .withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
                      .build();

答案 2

Ryan的投票率最高的答案使我走上了正确的轨道,但由于AmazonS3Client现已弃用,因此此代码为我解决了问题

    AmazonS3 s3 = AmazonS3ClientBuilder.standard()
                  .withCredentials(DefaultAWSCredentialsProviderChain.getInstance())
                  .build();

此代码似乎可以正确选取活动的 IAM 角色,例如在 Lambda 中。


推荐