java AWS 从 S3 下载对象时出错,“配置文件不能为空”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41796355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 06:10:10  来源:igfitidea点击:

AWS error downloading object from S3, "profile file cannot be null"

javaamazon-web-servicesamazon-s3amazon-ec2

提问by Xenalin

I've already seen this, but there was no answer to explain my problem. I first used the sample provided here(GetObject class), and it worked immediately on my desktop. However, my friend could not get it to work on his machine, nor will it work on our EC2 instance.

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

It was mentioned that there are to be credentials files specified, which makes sense, but I never had to do that and am pretty sure the default permissions were set to enable accessing this bucket.

有人提到必须指定凭据文件,这是有道理的,但我从来不必这样做,并且我很确定默认权限已设置为允许访问此存储桶。

Here's the stacktrace:

这是堆栈跟踪:

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.access0(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)

I can guarantee that neither the bucketName nor the key params in the GetObjectRequest are null. What's the discrepancy here? Why might it succeed only on my PC? Is this at all related to the fact that I had to supplement numerous jars that the aws-sdk jar was supposed to have already (Hymanson-databind, Hymanson-core, Hymanson-annotations, httpclient, httpcore, commons-logging, and joda-time)? It seems similar, what with the otherwise inexplicable errors (giving non-null params, something in aws-sdk says it's null).

我可以保证 GetObjectRequest 中的 bucketName 和 key 参数都不为空。这里有什么不同?为什么它只能在我的 PC 上成功?这是否与我必须补充 aws-sdk jar 应该已经拥有的许多 jar 的事实有关(Hymanson-databind、Hymanson-core、Hymanson-annotations、httpclient、httpcore、commons-logging 和 joda-时间)?看起来很相似,还有其他莫名其妙的错误(给出非空参数,aws-sdk 中的某些内容表示它为空)。

回答by Ryan Shillington

It looks like you solved this in the comments, but I got burned on this and want to leave a clearer answer for future readers. To be super clear, the problem here has nothing to do with files in S3. This error message has nothingto do with the file on your hard drive nor the file that you're trying to push/pull from S3. The problem is that you're initializing S3 with something like:

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

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

When you do that, it looks in ~/.aws/credentials for a list of profiles. This might work great on your computer but won't work anywhere that you're getting AWS access through an IAM role (ex. Lambda, Docker, EC2 instance, etc). The fix, is to initialize the AmazonS3Client like:

当您这样做时,它会在 ~/.aws/credentials 中查找配置文件列表。这可能在您的计算机上运行良好,但不适用于您通过 IAM 角色(例如 Lambda、Docker、EC2 实例等)获得 AWS 访问权限的任何地方。修复方法是初始化 AmazonS3Client,如:

AmazonS3 s3Client = new AmazonS3Client();

If you're using code that requires some kind of credentials provider, you can also do:

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

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

Hopefully that helps the next person. In my case, I was using DynamoDB and SQS, but I had the same error. I originally ignored this question because I thought your problem was S3 related and was super confused. Wrist slapped.

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

回答by Jonathan

The top voted answer by Ryan put me on the right track, but since AmazonS3Client is now deprecated, this code has resolved the problem for me

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

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

This code appears to correctly pick up the active IAM role, say in Lambda.

这段代码似乎正确地选择了活动的 IAM 角色,比如在 Lambda 中。

回答by Aragorn

The reason is that the computer of your friend doesn't have the "credentials" file.

原因是您朋友的计算机没有“凭据”文件。

To solve the problem, create file:

为了解决这个问题,创建文件:

C:\Users\USERNAME \.aws\credentials"

for Windows, or create file:

对于 Windows,或创建文件:

~/.aws/credentials

for macOS, Linux or Unix. And then write

适用于 macOS、Linux 或 Unix。然后写

aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key"

into the file.

进入文件。

Or, you can also set the environment variable of aws_access_key_idand aws_secret_access_key.

或者,你也可以设置环境变量aws_access_key_idaws_secret_access_key