Jump To:
- Where should I start
- How do I enable logging
- How do I get more information from an error code?
- I keep getting AWS_ERROR_MQTT_UNEXPECTED_HANGUP
- I am experiencing deadlocks
- How to debug in VSCode?
- What certificates do I need?
- I am getting AWS_IO_TLS_ERROR_DEFAULT_TRUST_STORE_NOT_FOUND
- How do I build and use the Android SDK?
- Where can I find MQTT 311 Samples?
- How can I improve the library size?
- Certificate and Private Key Usage Across Different Versions of the SDK on macOS
- Manual Publish Acknowledgement and QoS 1 Redelivery
- I still have more questions about this sdk?
If you are just getting started make sure you install this sdk and then build and run the Mqtt5 X509 Sample
To enable logging in the samples, you will need to set the following system properties when running the samples:
-Daws.crt.debugnative=true
-Daws.crt.log.destination=File
-Daws.crt.log.level=Trace
-Daws.crt.log.filename=<path and filename>aws.crt.debugnative: Whether to debug native (C/C++) code. Can be eithertrueorfalse.aws.crt.log.destination: Where the logs are output to. Can beFile,Stdout, orStderr. Defaults toStderr.aws.crt.log.level: The level of logging shown. Can beTrace,Debug,Info,Warn,Error,Fatal, orNone. Defaults toWarn.aws.crt.log.filename: The path to save the log file. Only needed ifaws.crt.log.destinationis set toFile.
For example, to run Mqtt X509 with logging you could use the following:
mvn compile exec:java -pl samples/Mqtt/Mqtt5X509 -Daws.crt.debugnative=true -Daws.crt.log.level=Debug -Daws.crt.log.destination=Stdout -Dexec.args='--endpoint <endpoint> --cert <path to cert> --key <path to key>'You can also enable CloudWatch logging for IoT which will provide you with additional information that is not available on the client side sdk.
When error codes are returned from the aws-crt-java they can be translated into human readable errors using the following:
import software.amazon.awssdk.crt.CRT;
// Print out the error code name
System.out.println(CRT.awsErrorName(errorCode));
// Print out a description of the error code
System.out.println(CRT.awsErrorString(errorCode));
This could be many different things, but it is most likely a policy issue. Start by using a super permissive IAM policy called AWSIOTFullAccess which looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:*"
],
"Resource": "*"
}
]
}After getting it working make sure to only allow the actions and resources that you need. More info about IoT IAM policies can be found here.
You MUST NOT perform blocking operations on any callback, or you will cause a deadlock. For example: in the on_publish_received callback, do not send a publish, and then wait for the future to complete within the callback. The Client cannot do work until your callback returns, so the thread will be stuck.
Here is an example launch.json file to run the X509 sample
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "x509",
"request": "launch",
"mainClass": "mqtt5x509.Mqtt5X509",
"projectName": "Mqtt5X509",
"args": "--endpoint <account-number>-ats.iot.<region>.amazonaws.com --cert <path to cert> --key <path to key> --client-id test-client",
"vmArgs": "-Daws.crt.debugnative=true -Daws.crt.log.destination=Stdout",
"console": "externalTerminal"
}
]
}- You can download pre-generated certificates from the AWS console (this is the simplest and is recommended for testing)
- You can also generate your own certificates to fit your specific use case. You can find documentation for that here and here
- Certificates that you will need to run the samples
- Device certificate
- Intermediate device certificate that is used to generate the key below
- When using samples it can look like this:
--cert abcde12345-certificate.pem.crt
- Key files
- You should have generated/downloaded private and public keys that will be used to verify that communications are coming from you
- When using samples you only need the private key and it will look like this:
--key abcde12345-private.pem.key
- Device certificate
This error usually occurs when the SDK cannot find or access the system's default trust store for TLS certificate validation. You can resolve this by downloading and specifying the Root CA certificate explicitly.
Root CA Certificate
- Download the root CA certificate file that corresponds to the type of data endpoint and cipher suite you're using (you most likely want Amazon Root CA 1 if you are using the AWS IoT service)
- This certificate is generated and provided by Amazon. You can download it here or download it when getting the other certificates from the AWS Console
Set Root CA for the client builder
// When building your MQTT5 client, specify the CA file
// Mqtt5ClientBuilder builder = <setup your client builder based on your auth type>
builder.withCertificateAuthorityFromPath(null, "<path to AmazonRootCA1.pem>");Instructions for building, installing, and use of the Android SDK can be found here
The MQTT 311 Samples can be found in the v1.27.2 samples folder here
The SDK depends on aws-crt-java, which includes native binaries for multiple platforms (~50MB total). Here are two approaches to reduce size:
Use classifiers to include only your target platform's binaries:
<dependency>
<groupId>software.amazon.awssdk.crt</groupId>
<artifactId>aws-crt</artifactId>
<version>0.39.0</version>
<classifier>linux-x86_64</classifier> <!-- Only Linux 64-bit -->
</dependency>See all available classifiers.
For maximum control, build both CRT and SDK locally:
- Build aws-crt-java from source
- Update
sdk/pom.xmlto use local aws-crt build:<dependency> <groupId>software.amazon.awssdk.crt</groupId> <artifactId>aws-crt</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency>
- Build the SDK from source
A certificate and private key pair cannot be shared on a macOS device between aws-iot-device-sdk-java-v2 v1.29.0 and other versions. In the update to v1.29.0 we migrated macOS from using Apple's deprecated Security Framework to SecItem API. In doing so, certificate and private keys are imported in a non-backwards compatible manner into the Apple Keychain.
When using manual publish acknowledgement, there are two important behaviors to be aware of regarding QoS 1 message redelivery:
Broker redelivery of unacknowledged publishes
The AWS IoT broker will periodically resend unacknowledged QoS 1 PUBLISH packets. These redeliveries should be treated as duplicates even if the DUP flag in the PUBLISH packet is not set. If the manual publish acknowledgement is not acquired again for a redelivered packet, the acknowledgement will be sent automatically.
Session resumption after disconnect/reconnect
Upon a disconnect and reconnect of the MQTT5 client, if a session is resumed, any previously acquired acknowledgement handle is void. The broker will resend the unacknowledged PUBLISH packet, and the acknowledgement must be reacquired from that resent packet. If the resent packet is not handled for manual acknowledgement, the acknowledgement will be sent automatically.
- Here are the AWS IoT Core docs for more details about IoT Core
- Here are the AWS IoT Greengrass v2 docs for more details about greengrass
- Discussion questions are also a great way to ask other questions about this sdk.
- Open an issue if you find a bug or have a feature request