AWS 从 S3 下载对象时出错,“配置文件不能为空”
Posted
技术标签:
【中文标题】AWS 从 S3 下载对象时出错,“配置文件不能为空”【英文标题】:AWS error downloading object from S3, "profile file cannot be null" 【发布时间】:2017-06-07 08:56:58 【问题描述】:我已经看过this,但没有答案来解释我的问题。我首先使用了here(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 params 都不为空。这里有什么差异?为什么它只能在我的 PC 上成功?这是否与我必须补充 aws-sdk jar 应该已经拥有的许多 jar 的事实有关(jackson-databind、jackson-core、jackson-annotations、httpclient、httpcore、commons-logging 和 joda-时间)?看起来很相似,否则会出现无法解释的错误(给出非空参数,aws-sdk 中的某些内容说它是空的)。
【问题讨论】:
不确定你是否看过这个:***.com/a/41670728/3770040 我仍在查看您的链接以及从中链接的“使用 AWS 凭证”页面,但我从未为我的 Eclipse 项目设置这些,而且我没有凭证文件。我只是开箱即用地运行示例,它运行良好。我还是一头雾水。 好的,我想我发现了问题:我认为凭据会存储在项目文件夹中,但我完全忘记了 ~/.aws/credentials 文件,尽管它是黑色的和我链接的问题中的白色。我只需要知道如何为在我的 EC2 实例上运行的 jar 进行设置。 作为一般规则,请记住,就安全性而言,始终建议使用 EC2 角色,而不是在实例存储中存储用户凭据的配置文件。 【参考方案1】:看起来您在 cmets 中解决了这个问题,但我对此感到很恼火,想为未来的读者留下更清晰的答案。非常清楚,这里的问题与 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 中。
【讨论】:
【参考方案3】:原因是你朋友的电脑没有“凭证”文件。
要解决问题,请创建文件:
C:\Users\USERNAME \.aws\credentials"
对于 Windows,或创建文件:
~/.aws/credentials
适用于 macOS、Linux 或 Unix。然后写
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key"
进入文件。
或者,也可以设置aws_access_key_id
和aws_secret_access_key
的环境变量。
【讨论】:
抱歉忘记了文件头前面的[default]。 如果您打算在 EC2 实例、ECS、Fargate、Lambda 等上使用您的代码,那么这可能不适合您。不要依赖文件作为获得信誉的唯一途径。 确保credentials
文件实际上是在程序运行的用户下创建的;例如如果您的应用程序是守护进程并以用户 foo
身份运行,则该文件应位于 /home/foo/.aws/
... 并且如果您碰巧使用 sudo
运行,则该文件应该(显然)位于 @987654330 @【参考方案4】:
我已经使用了以下代码并为我工作,希望它会有所帮助
BasicAWSCredentials credentials = new BasicAWSCredentials(accesskey, secretkey);
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion("ap-south-1")
.build();
【讨论】:
【参考方案5】:BasicAWSCredentials
可能需要所有三个组件;
BasicAWSCredentials credentials = new BasicAWSCredentials(accesskey, secretkey, accessToken);
另外,请考虑凭据是否来自您的 .aws 文件夹,或者您提供的只是上面的BasicCredentials
行。
【讨论】:
以上是关于AWS 从 S3 下载对象时出错,“配置文件不能为空”的主要内容,如果未能解决你的问题,请参考以下文章
使用 Psycopg2 将数据从 S3 复制到 AWS Redshift 时出错
使用 pyspark 从 AWS s3 Bucket 读取 csv 时出错