Azure / azure-iot-sdk-java

A Java SDK for connecting devices to Microsoft Azure IoT services
https://azure.github.io/azure-iot-sdk-java/
Other
198 stars 237 forks source link

[Device Client] null pointer exception after long connection drop #306

Closed kugelbit closed 6 years ago

kugelbit commented 6 years ago

Description of the issue:

In my application i have to face long internet-connection drops. So i was testing around with your SDK. I wrote my own retry-policy, where i try to connect infinitely. I already set setOperationTimeout(Long.MAX_VALUE) to make the infinitely retry logic possible. In my test i connect to the azure cloud and send a telemetry message once in a second. After some time i cut the connection and let the retry policy kick in. After some more time (i run the app overnigth without any connection) i provide the connection again. If i do so i get the following exception:

Exception in thread "main" java.lang.NullPointerException at java.lang.StringBuilder.<init>(Unknown Source) at com.microsoft.azure.sdk.iot.device.net.IotHubUri.<init>(IotHubUri.java:76) at com.microsoft.azure.sdk.iot.device.net.IotHubUri.<init>(IotHubUri.java:112) at com.microsoft.azure.sdk.iot.device.net.IotHubUri.getResourceUri(IotHubUri.java:171) at com.microsoft.azure.sdk.iot.device.auth.IotHubSasToken.<init>(IotHubSasToken.java:80) at com.microsoft.azure.sdk.iot.device.auth.IotHubSasTokenSoftwareAuthenticationProvider.getRenewedSasToken(IotHubSasTokenSoftwareAuthenticationProvider.java:99) at com.microsoft.azure.sdk.iot.device.transport.amqps.AmqpsDeviceAuthenticationCBS.createCBSAuthenticationMessage(AmqpsDeviceAuthenticationCBS.java:305) at com.microsoft.azure.sdk.iot.device.transport.amqps.AmqpsDeviceAuthenticationCBS.authenticate(AmqpsDeviceAuthenticationCBS.java:234) at com.microsoft.azure.sdk.iot.device.transport.amqps.AmqpsSessionDeviceOperation.authenticate(AmqpsSessionDeviceOperation.java:129) at com.microsoft.azure.sdk.iot.device.transport.amqps.AmqpsSessionManager.authenticate(AmqpsSessionManager.java:149) at com.microsoft.azure.sdk.iot.device.transport.amqps.AmqpsIotHubConnection.authenticate(AmqpsIotHubConnection.java:275) at com.microsoft.azure.sdk.iot.device.transport.amqps.AmqpsIotHubConnection.open(AmqpsIotHubConnection.java:203) at com.microsoft.azure.sdk.iot.device.transport.IotHubTransport.openConnection(IotHubTransport.java:641) at com.microsoft.azure.sdk.iot.device.transport.IotHubTransport.open(IotHubTransport.java:277) at com.microsoft.azure.sdk.iot.device.DeviceIO.open(DeviceIO.java:160) at com.microsoft.azure.sdk.iot.device.InternalClient.open(InternalClient.java:130) at com.microsoft.azure.sdk.iot.device.DeviceClient.open(DeviceClient.java:317) at de.XXXXX.mantiscloudinterface.MantisAzureClient.mainLoop(MantisAzureClient.java:242) at de.XXXXX.mantiscloudinterface.MantisAzureClient.main(MantisAzureClient.java:160)

The last debug log entry i get from the sdk is:

06:50:13.954 [main] DEBUG com.microsoft.azure.sdk.iot.device.transport.amqps.AmqpsSessionDeviceOperation - Entered in method authenticate

So in the authenticate() function the amqpsDeviceAuthentication.authenticate() function is called. Im using the standard config with SAS-Tokens so i think the resulting function call is the authenticate() function from the AmqpsDeviceAuthenticationCBS Class. In this function the class internal function createCBSAuthenticationMessage() is called. In this function im not sure what happens but i think it tries to get an new SAS token with the function deviceClientConfig.getSasTokenAuthentication().getRenewedSasToken(). I use the standard config so i think the resulationg SasTokenAuthentication()-Provider is the IotHubSasTokenSoftwareAuthenticationProvider. In the getRenewedSasToken() function a new IotHubSasToken is created and the constructor of the IoTHubSasToken calls the getResourceUri() function where the null pointer exception cames from.

Is there something wrong with my configuration ? Or does the carbage collector delete the requiered Object ? Or is there something with my memory?

timtay-microsoft commented 6 years ago

This is an odd bug. The string value that the IotHubUri constructor is looking for should never be null. Do you have any insight on how memory constrained your device was leading up to this null pointer?

timtay-microsoft commented 6 years ago

I was able to reproduce this error after a while, and the issue here was closely related to issue #304

The issue here was a bug in our reconnection logic due to a problem with how we refreshed our sas token at the end of its life.

I'll have the fix for this issue checked into master soon, and will likely release a new package on 8/31 so that you can avoid this issue. Thanks for the detailed write up on this issue, it helped a lot!

timtay-microsoft commented 6 years ago

The fix for this issue has been checked into master and should be released on 8/30. Thanks for your patience with this issue!

timtay-microsoft commented 6 years ago

The fix for this issue has been released as of Device Client 1.14.0, so I'm closing this issue now.

az-iot-builder-01 commented 6 years ago

@kugelbit, thank you for your contribution to our open-sourced project! Please help us improve by filling out this 2-minute customer satisfaction survey