AWS Java S3 Uploading error: “profile file cannot

2020-07-02 09:32发布

问题:

I get an exception when trying to upload a file to Amazon S3 from my Java Spring application. The method is pretty simple:

private void productionFileSaver(String keyName, File f) throws InterruptedException {

        String bucketName = "{my-bucket-name}";
        TransferManager tm = new TransferManager(new ProfileCredentialsProvider());        
        // TransferManager processes all transfers asynchronously, 
        // so this call will return immediately.
        Upload upload = tm.upload(
                bucketName, keyName, new File("/mypath/myfile.png"));

        try {
            // Or you can block and wait for the upload to finish
            upload.waitForCompletion();
            System.out.println("Upload complete.");
        } catch (AmazonClientException amazonClientException) {
            System.out.println("Unable to upload file, upload was aborted.");
            amazonClientException.printStackTrace();
        }
    }

It is basically the same that amazon provides here, and the same exception with the exactly same message ("profile file cannot be null") appears when trying this other version. The problem is not related to the file not existing or being null (I have already checked in a thousand ways that the File argument recieved by TransferManager.upload method exists before calling it).

I cannot find any info about my exception message "profile file cannot be null". The first lines of the error log are the following:

com.amazonaws.AmazonClientException: Unable to complete transfer: profile file cannot be null
    at com.amazonaws.services.s3.transfer.internal.AbstractTransfer.unwrapExecutionException(AbstractTransfer.java:281)
    at com.amazonaws.services.s3.transfer.internal.AbstractTransfer.rethrowExecutionException(AbstractTransfer.java:265)
    at com.amazonaws.services.s3.transfer.internal.AbstractTransfer.waitForCompletion(AbstractTransfer.java:103)
    at com.fullteaching.backend.file.FileController.productionFileSaver(FileController.java:371)
    at com.fullteaching.backend.file.FileController.handlePictureUpload(FileController.java:247)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)

My S3 policy allows getting and puttings objects for all kind of users.

Any idea about what's happening?

回答1:

ProfileCredentialsProvider() creates a new profile credentials provider that returns the AWS security credentials configured for the default profile.

So, if you haven't any configuration for default profile at ~/.aws/credentials, while trying to put object, it yields that error.

If you run your code on Lambda service, it will not provide this file. In that case, you also do not need to provide credentials. Just assign right IAM Role to your lambda function, then using default constructor should solve issue.

You may want to change TransferManager constructor according to your needs.



回答2:

The solution was pretty simple: I was trying to implement this communication without an AmazonS3 bean for Spring.

This link will help with the configuration:

http://codeomitted.com/upload-file-to-s3-with-spring/



回答3:

my code worked fine as below:

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