21

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.

What's happening?

3 Answers 3

22

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. Same thing in Lambda, I was passing the ProfileCredentialsProvider into the constructor which cause that error. Using AmazonS3 s3Client = new AmazonS3Client(); works.
FYI - I had this problem in a docker ECS container. It's the same thing as with Lambda. Look in your code for new ProfileCredentialsProvider(someProfile)) and replace it with DefaultAWSCredentialsProviderChain.getInstance()
I left an answer with code examples here: stackoverflow.com/questions/41796355/…
4

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/

Comments

3

my code worked fine as below:

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

1 Comment

This didnt work for me. When i checked DefaultAWSCredentialsProviderChain.getInstance() , is creating a new ProfileCredentialsProvider which might have caused the issue. Not sure. Still didn't get any reoslution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.