Aws-sdk-android: Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'com.amazonaws.auth.CognitoCachingCredentialsProvider com.amazonaws.mobile.auth.core.IdentityManager.getUnderlyingProvider()'

Created on 7 Mar 2018  Â·  24Comments  Â·  Source: aws-amplify/aws-sdk-android

To help us solve your problem better, please answer the following list of questions.

  • What service are you using?
    AWS

  • In what version of SDK are you facing the problem?
    // Amazon SDK
    compile 'com.amazonaws:aws-android-sdk-s3:2.6.16'
    compile 'com.amazonaws:aws-android-sdk-core:2.6.16'
    compile 'com.amazonaws:aws-android-sdk-ddb:2.6.16'
    compile ('com.amazonaws:aws-android-sdk-mobile-client:2.6.+@aar') { transitive = true; }

  • Is the issue limited to Simulators / Actual Devices?
    Some devices from production.

  • Can your problem be resolved if you bump to a higher version of SDK?
    I am using the higher

  • Is this problem related to specific Android/OS version?
    Devices
    samsung 66%
    LGE 24%
    motorola 10%
    Operating Systems
    7

  • Can you give us steps to reproduce with a minimal, complete, and verifiable example? Please include any specific network conditions that might be required to reproduce the problem.
    We use your SDK to upload files, in some devices this line is breaking the code.
    try {
    transferUtility = Util.getTransferUtility(this)
    transferUtility = TransferUtility.builder()
    .context(applicationContext)
    .awsConfiguration(AWSMobileClient.getInstance().configuration)
    .s3Client( AmazonS3Client(AWSMobileClient.getInstance().credentialsProvider))
    .build();
    } catch (exception: Exception) {
    application.uploadingProcessHelper.uploadFailed(uploadId)
    Crashlytics.logException(exception)
    Log.d(TAG_UPLOAD, "Amazon transferUtility Error: ", exception)
    }

  • Please include a stacktrace if applicable.
    Fatal Exception: java.lang.NullPointerException
    Attempt to invoke virtual method 'com.amazonaws.auth.CognitoCachingCredentialsProvider com.amazonaws.mobile.auth.core.IdentityManager.getUnderlyingProvider()' on a null object reference

AWSMobileClient

Most helpful comment

Thank you @alejouribesanchez for reporting to us. Sorry for the inconvenience caused.

You need to invoke the initialize method before using the credentials provider. See the fixed code here:

AWSMobileClient will create the AWSConfiguration object and the CognitoCachingCredentialsProvider object successfully when the onComplete method is invoked.
So you can retrieve the information in onComplete and then pass it down to the TransferUtility creation.

AWSMobileClient.getInstance().initialize(this,new AWSStartupHandler() {
            @Override
            public void onComplete(AWSStartupResult awsStartupResult) {
               transferUtility = TransferUtility.builder()
                  .context(applicationContext)
                  .awsConfiguration(AWSMobileClient.getInstance().getConfiguration())
                  .s3Client( AmazonS3Client(AWSMobileClient.getInstance().getCredentialsProvider()))
                  .build();
          }
}).execute();

We have put the instructions in the AWSMobileClient in the comments in the code here: https://docs.aws.amazon.com/aws-mobile/latest/developerguide/how-to-transfer-files-with-transfer-utility.html

But we will update the doc to reflect the onComplete method asap. Thank you for pointing this out.

All 24 comments

Thank you @alejouribesanchez for reporting to us. Sorry for the inconvenience caused.

You need to invoke the initialize method before using the credentials provider. See the fixed code here:

AWSMobileClient will create the AWSConfiguration object and the CognitoCachingCredentialsProvider object successfully when the onComplete method is invoked.
So you can retrieve the information in onComplete and then pass it down to the TransferUtility creation.

AWSMobileClient.getInstance().initialize(this,new AWSStartupHandler() {
            @Override
            public void onComplete(AWSStartupResult awsStartupResult) {
               transferUtility = TransferUtility.builder()
                  .context(applicationContext)
                  .awsConfiguration(AWSMobileClient.getInstance().getConfiguration())
                  .s3Client( AmazonS3Client(AWSMobileClient.getInstance().getCredentialsProvider()))
                  .build();
          }
}).execute();

We have put the instructions in the AWSMobileClient in the comments in the code here: https://docs.aws.amazon.com/aws-mobile/latest/developerguide/how-to-transfer-files-with-transfer-utility.html

But we will update the doc to reflect the onComplete method asap. Thank you for pointing this out.

Cool, thanks for the update

@alejouribesanchez Please let us know if this unblocks you and if transferUtility instance is created without any crash.

I will update the code and push to production on friday so I will let you
know this weekend after the users upgrade to the new version and I have the
fabric report

El 7 mar. 2018 3:21 PM, "Karthikeyan" notifications@github.com escribió:

@alejouribesanchez https://github.com/alejouribesanchez Please let us
know if this unblocks you and if transferUtility instance is created
without any crash.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/aws/aws-sdk-android/issues/420#issuecomment-371268536,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ADxISVFi6GwqvVkAc5rUckja8qNo2gumks5tcD6rgaJpZM4Sg2PM
.

@kvasukib Hi, I am trying to use your code but method onComplete is never called, I tried in different ways and the method is never called.

override fun onCreate() {
super.onCreate()
transferUtility = Util.getTransferUtility(this)
AWSMobileClient.getInstance().initialize(this, this)
}

override fun onComplete(awsStartupResult: AWSStartupResult?) {
    try {
        transferUtility = TransferUtility.builder()
                .context(applicationContext)
                .awsConfiguration(AWSMobileClient.getInstance().configuration)
                .s3Client( AmazonS3Client(AWSMobileClient.getInstance().credentialsProvider))
                .build();
        Log.d(TAG_UPLOAD, "AWSStartupResult onComplete called")
    } catch (exception: Exception) {
        Crashlytics.logException(exception)
        Log.d(TAG_UPLOAD, "Amazon transferUtility Error: ", exception)
    }
}

Thank you @alejouribesanchez for the quick reply.

You need to call execute():

override fun onCreate() {
  super.onCreate()
  transferUtility = Util.getTransferUtility(this)
  AWSMobileClient.getInstance().initialize(this, this).execute();
}

Hi @kvasukib I was trying to use with that execute() but there is a problem, I am doing the uploading process in background into a service class not activity class, but I found a issue in your SDK you are forcing a context to be casted to activity. So I am getting an exception

screen shot 2018-03-08 at 5 14 34 pm

screen shot 2018-03-08 at 5 07 09 pm

I mean the context is a service class instead of activity class

Thank you @alejouribesanchez for the reply. We re ware of that issue and we are trying to fix it. In that case, you can do the following:

try {
    AWSConfiguration config = new AWSConfiguration(getApplicationContext());
    transferUtility = TransferUtility.builder()
            .context(getApplicationContext())
            .awsConfiguration(config)
            .s3Client( AmazonS3Client(new CognitoCachingCredentialsProvider(geApplicationContext(), config))
            .build();
} catch (exception: Exception) {
    Crashlytics.logException(exception)
    Log.d(TAG_UPLOAD, "Amazon transferUtility Error: ", exception)
}

@kvasukib is there other way? because if I use CogitoCachingCredentialsProvider I need to compile 'com.amazonaws:aws-android-sdk-auth-ui:2.6.+@aar' and that in implies at I need to change my min sdk from 19 to 23 which is not a good solution because I am still supporting a lot devices with android 5.0

Thank you @alejouribesanchez for the reply. CognitoCachingCredentialsProvider is part of 'com.amazonaws:aws-android-sdk-core:2.6.+@' which is supported from Android SDK 10. So you should be able to use it.

Please let us know if this works for you!

Closing this issue. Please re-open if this issue persists.

Hi, I tried the solution suggested but did not work for me:

  1. On Create method of the service class I called this line:
    AWSMobileClient.getInstance().initialize(this,this).execute()

But the method onComplete was never called.

override fun onComplete(awsStartupResult: AWSStartupResult?) {
try {
val config = AWSConfiguration(applicationContext);
transferUtility = TransferUtility.builder()
.context(applicationContext)
.awsConfiguration(config)
.s3Client( AmazonS3Client(CognitoCachingCredentialsProvider(applicationContext, config)))
.build()
} catch (exception: Exception) {
Crashlytics.logException(exception)
Log.d(TAG_UPLOAD, "Amazon transferUtility Error: ", exception)
}

Also I am getting this error:

E/AWSMobileClient: Error occurred in fetching the Cognito Identity and resuming the auth session
java.lang.ClassCastException: com.iqboxyinc.iqboxy.datagateway.datasource.userdocuments.services.UploadDocumentsService cannot be cast to android.app.Activity
at com.amazonaws.mobile.client.AWSMobileClient.fetchCognitoIdentity(AWSMobileClient.java:287)
at com.amazonaws.mobile.client.AWSMobileClient.initializeWithBuilder(AWSMobileClient.java:186)
at com.amazonaws.mobile.client.AWSMobileClient.access$100(AWSMobileClient.java:74)
at com.amazonaws.mobile.client.AWSMobileClient$InitializeBuilder.execute(AWSMobileClient.java:446)
at com.iqboxyinc.iqboxy.datagateway.datasource.userdocuments.services.UploadDocumentsService.onCreate(UploadDocumentsService.kt:141)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3534)
at android.app.ActivityThread.-wrap6(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1732)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)

Thanks for your help I will be waiting for an answer

screen shot 2018-03-15 at 11 06 20 pm
screen shot 2018-03-15 at 11 05 39 pm

Also @kvasukib I was trying to use your answer 'CogitoCachingCredentialsProvider is part of 'com.amazonaws:aws-android-sdk-core:2.6.+@' which is supported from Android SDK 10. So you should be able to use it.' But I did not find anything called "CogitoCachingCredentialsProvider" instead of that I found "CognitoCachingCredentialsProvider" I think that was the reason I was trying to search in other packages that class but I think you misspelling, right?

Hi @alejouribesanchez, Sorry for the inconvenience caused.

try {
    AWSConfiguration config = new AWSConfiguration(geApplicationContext());
    transferUtility = TransferUtility.builder()
            .context(getApplicationContext())
            .awsConfiguration(config)
            .s3Client(new AmazonS3Client(new CognitoCachingCredentialsProvider(geApplicationContext(), config))
            .build();
} catch (exception: Exception) {
    Crashlytics.logException(exception)
    Log.d(TAG_UPLOAD, "Amazon transferUtility Error: ", exception)
}

You are right! It's CognitoCachingCredentialsProvider. You can grab it from 'com.amazonaws:aws-android-sdk-core:2.6.+'. Also, since you are creating Transferutility from an application context, we recommend using CognitoCachingCredentialsProvider and AmazonS3Client to create TransferUtility rather than using AWSMobileClient. We are taking it as a feature request to add support for application context in AWSMobileClient. Thank you!

Hi @alejouribesanchez,

Here is the code in kotlin to instantiate TransferUtility:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var config = AWSConfiguration(applicationContext)
        var credentialsProvider = CognitoCachingCredentialsProvider(applicationContext, config)
        var s3Client = AmazonS3Client(credentialsProvider)
        var tu = TransferUtility.builder()
                .awsConfiguration(config)
                .context(applicationContext)
                .s3Client(s3Client)
                .build()

        var str = java.util.UUID.randomUUID().toString()
        var fileName = "filename.txt"

        val filePath = getFilesDir().getPath().toString() + fileName
        var file = File(filePath)
        val writer = BufferedWriter(FileWriter(filePath))
        writer.write(str)
        writer.close()

        var uploadObserver = tu.upload(fileName, file)
        print (uploadObserver.bytesTotal)
        uploadObserver.setTransferListener(object : TransferListener {

            override fun onStateChanged(id: Int, state: TransferState) {
                if (TransferState.COMPLETED === state) {
                    // Handle a completed upload.
                    Log.d("", "State completed.")
                }
            }

            override fun onProgressChanged(id: Int, bytesCurrent: Long, bytesTotal: Long) {
                val percentDonef = bytesCurrent.toFloat() / bytesTotal.toFloat() * 100
                val percentDone = percentDonef.toInt()

                Log.d("YourActivity", "ID:" + id + " bytesCurrent: " + bytesCurrent
                        + " bytesTotal: " + bytesTotal + " " + percentDone + "%")
            }

            override fun onError(id: Int, ex: Exception) {
                // Handle errors
                Log.e("", ex.toString())
            }

        })
        print (uploadObserver.bytesTransferred)
    }

@kvasukib I am using the fix you posted but getting "method call expected" error on theAmazonS3Client( CognitoCachingCredentials) line

        TransferUtility transferUtility = TransferUtility.builder()
                .context(getApplicationContext())
                .awsConfiguration(config)
                .s3Client(AmazonS3Client(new CognitoCachingCredentialsProvider(getApplicationContext(), config))
                        .build();

API 23

Packages
```
implementation('com.amazonaws:aws-android-sdk-mobile-client:2.6.+@aar'){
transitive = true;
}
implementation 'com.amazonaws:aws-android-sdk-s3:2.6.+'
implementation 'com.amazonaws:aws-android-sdk-cognito:2.6.+'
implementation 'com.amazonaws:aws-android-sdk-ddb:2.6.+'

```

@jmgamboa Are you trying to do in Java or Kotlin?

Java:

AWSConfiguration config = new AWSConfiguration(getApplicationContext());

AmazonS3Client s3Client = new AmazonS3Client(new CognitoCachingCredentialsProvider(getApplicationContext(), config);
s3Client.setRegion(Regions.getRegion(Regions.US_WEST_2));

TransferUtility transferUtility = TransferUtility.builder()
                .context(getApplicationContext())
                .awsConfiguration(config)
                .s3Client(s3Client)
                .build();

Kotlin:

        var config = AWSConfiguration(applicationContext)
        var credentialsProvider = CognitoCachingCredentialsProvider(applicationContext, config)
        var s3Client = AmazonS3Client(credentialsProvider)
        var tu = TransferUtility.builder()
                .awsConfiguration(config)
                .context(applicationContext)
                .s3Client(s3Client)
                .build()

@kvasukib it was Java. copy-pasta issue. resolved for me thanks.

Thank you for confirming.

Is this being tracked anywhere? If not, it might be a good idea to keep this open.

Hi @kvasukib I was trying to use with that execute() but there is a problem, I am doing the uploading process in background into a service class not activity class, but I found a issue in your SDK you are forcing a context to be casted to activity. So I am getting an exception

screen shot 2018-03-08 at 5 14 34 pm

screen shot 2018-03-08 at 5 07 09 pm

I mean the context is a service class instead of activity class

The docs are a little confusing in light of this bug: https://docs.aws.amazon.com/aws-mobile/latest/developerguide/add-aws-mobile-analytics.html

It recommends that Android users start sessions in Application.onCreate, but we can't actually initialize this thing in an Application. Do we have to worry about re-initializing the client if we switch to a new activity?

Agree with @naddeoa, it's an issue. I'm having the same issue with push messages. In my case, the initialized AWS instance somehow goes out of scope. It happens if the app was in background for some time. When I receive a new push message, I forward it to PinpointManager#handleCampaignPush (according to docs), which then fails because AWS is not initialized. However, I cannot initialize AWS from my Firebase notification service since it requires activity context.

@aarnaut AWSMobileClient creates two objects: CognitoCachingCredentialsProvider and AWSConfiguration. As a workaround (until AWSMobileClient supports application context), I would recommend doing the following to get unblocked. The following example shows how to create a PinpointManager in the Application class.

package com.amazonaws.pinpointapp;

import android.app.Application;
import android.util.Log;

import com.amazonaws.auth.CognitoCachingCredentialsProvider;
import com.amazonaws.mobile.config.AWSConfiguration;
import com.amazonaws.mobileconnectors.pinpoint.PinpointConfiguration;
import com.amazonaws.mobileconnectors.pinpoint.PinpointManager;

public class MyApplication extends Application {
    private static final String LOG_TAG = MyApplication.class.getSimpleName();
    public static PinpointManager pinpointManager;
    private AbstractApplicationLifeCycleHelper applicationLifeCycleHelper;

    @Override
    public void onCreate() {
        super.onCreate();

        AWSConfiguration awsConfiguration = new AWSConfiguration(this);
        PinpointConfiguration pinpointConfiguration = new PinpointConfiguration(this,
                new CognitoCachingCredentialsProvider(this, awsConfiguration),
                awsConfiguration);
        pinpointManager = new PinpointManager(pinpointConfiguration);
    }
}

@kvasukib Thank you for the quick reply. I'll give it a try.

Was this page helpful?
0 / 5 - 0 ratings