web-dev-qa-db-fra.com

Erreur AWS lors du téléchargement de l'objet à partir de S3, "le fichier de profil ne peut pas être nul"

J'ai déjà vu this , mais il n'y avait pas de réponse pour expliquer mon problème. J'ai d'abord utilisé l'exemple fourni ici (classe GetObject), et cela a fonctionné immédiatement sur mon bureau. Cependant, mon ami n'a pas pu le faire fonctionner sur sa machine, ni sur notre instance EC2.

Il a été mentionné qu'il devait y avoir des fichiers d'informations d'identification spécifiés, ce qui est logique, mais je n'ai jamais eu à le faire et je suis presque sûr que les autorisations par défaut ont été définies pour permettre d'accéder à ce compartiment.

Voici le 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.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)

Je peux garantir que ni le bucketName ni les paramètres clés dans GetObjectRequest ne sont nuls. Quelle est la différence ici? Pourquoi cela pourrait-il réussir uniquement sur mon PC? Est-ce que cela est lié au fait que j'ai dû compléter de nombreux pots que le pot aws-sdk était censé avoir déjà (jackson-databind, jackson-core, jackson-annotations, httpclient, httpcore, commons-logging et joda- temps)? Cela semble similaire, avec les erreurs autrement inexplicables (donner des paramètres non nuls, quelque chose dans aws-sdk dit que c'est nul).

17
Xenalin

Il semble que vous ayez résolu cela dans les commentaires, mais je me suis brûlé là-dessus et je veux laisser une réponse plus claire aux futurs lecteurs. Pour être très clair, le problème ici n'a rien à voir avec les fichiers en S. Ce message d'erreur a rien à voir avec le fichier sur votre disque dur ni le fichier que vous essayez de pousser/tirer de S3. Le problème est que vous initialisez S3 avec quelque chose comme:

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

Lorsque vous faites cela, il recherche dans ~/.aws/credentials une liste de profils. Cela peut très bien fonctionner sur votre ordinateur, mais ne fonctionnera nulle part où vous obtenez un accès AWS via un rôle IAM (par exemple, Lambda, Docker, instance EC2, etc.). Le correctif consiste à initialiser AmazonS3Client comme:

AmazonS3 s3Client = new AmazonS3Client();

Si vous utilisez du code qui nécessite une sorte de fournisseur d'informations d'identification, vous pouvez également faire:

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

Espérons que cela aide la prochaine personne. Dans mon cas, j'utilisais DynamoDB et SQS, mais j'ai eu la même erreur. Au départ, j'ai ignoré cette question parce que je pensais que votre problème était lié à S3 et qu'il était super confus. Poignet giflé.

39
Ryan Shillington

La réponse la plus votée de Ryan m'a mis sur la bonne voie, mais comme AmazonS3Client est désormais obsolète, ce code a résolu le problème pour moi

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

Ce code semble récupérer correctement le rôle IAM actif, par exemple dans Lambda.

5
Jonathan

La raison en est que l'ordinateur de votre ami n'a pas le fichier "pouvoirs".

Pour résoudre le problème, créez un fichier:

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

pour Windows, ou créez un fichier:

~/.aws/credentials

pour macOS, Linux ou Unix. Et puis écris

aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key"

dans le fichier.

Ou, vous pouvez également définir la variable d'environnement de aws_access_key_id et aws_secret_access_key.

3
Aragorn