Amazon Java SDK Guide
Amazon Java SDK Guide
Developer Guide
Amazon's trademarks and trade dress may not be used in connection with any product or service that is not Amazon's, in any manner
that is likely to cause confusion among customers, or in any manner that disparages or discredits Amazon. All other trademarks not
owned by Amazon are the property of their respective owners, who may or may not be affiliated with, connected to, or sponsored by
Amazon.
AWS SDK for Java Developer Guide
Table of Contents
AWS SDK for Java Developer Guide ..................................................................................................... 1
AWS SDK for Java 2.0 Developer Preview ...................................................................................... 1
Additional Documentation and Resources ...................................................................................... 1
Eclipse IDE Support .................................................................................................................... 1
Developing AWS Applications for Android ..................................................................................... 1
Viewing the SDK's Revision History ............................................................................................... 2
Building Java Reference Documentation for Earlier SDK versions ...................................................... 2
Getting Started .................................................................................................................................. 3
Sign Up for AWS and Create an IAM User .................................................................................... 3
Set up the AWS SDK for Java ..................................................................................................... 4
Prerequisites ...................................................................................................................... 4
Including the SDK in your project ......................................................................................... 4
Downloading and extracting the SDK ................................................................................... 4
Installing previous versions of the SDK ................................................................................. 5
Installing a Java Development Environment .......................................................................... 5
Set up AWS Credentials and Region for Development .................................................................... 6
Setting AWS Credentials ..................................................................................................... 6
Setting the AWS Region ...................................................................................................... 7
Using the SDK with Apache Maven .............................................................................................. 7
Create a new Maven package .............................................................................................. 7
Configure the SDK as a Maven dependency ........................................................................... 8
Build your project .............................................................................................................. 9
Build the SDK with Maven ................................................................................................... 9
Using the SDK with Gradle ......................................................................................................... 9
Using the AWS SDK for Java ............................................................................................................. 11
Best Practices for AWS Development with the AWS SDK for Java ................................................... 11
Amazon S3 ...................................................................................................................... 11
Creating Service Clients ........................................................................................................... 12
Obtaining a Client Builder ................................................................................................. 12
Creating Async Clients ...................................................................................................... 13
Using DefaultClient .......................................................................................................... 13
Client Lifecycle ................................................................................................................. 13
Working with AWS Credentials .................................................................................................. 14
Using the Default Credential Provider Chain ........................................................................ 14
Specifying a Credential Provider or Provider Chain ............................................................... 16
Explicitly Specifying Credentials ......................................................................................... 17
More Info ........................................................................................................................ 17
AWS Region Selection .............................................................................................................. 17
Checking for Service Availability in an AWS Region ............................................................... 17
Choosing a Region ........................................................................................................... 18
Choosing a Specific Endpoint ............................................................................................. 18
Automatically Determine the AWS Region from the Environment ............................................ 18
Exception Handling ................................................................................................................. 19
Why Unchecked Exceptions? .............................................................................................. 19
AmazonServiceException (and Subclasses) ........................................................................... 20
AmazonClientException ..................................................................................................... 20
Asynchronous Programming ..................................................................................................... 20
Java Futures .................................................................................................................... 21
Asynchronous Callbacks .................................................................................................... 22
Best Practices .................................................................................................................. 23
Logging AWS SDK for Java Calls ............................................................................................... 23
Download the Log4J JAR .................................................................................................. 23
Setting the Classpath ........................................................................................................ 24
Service-Specific Errors and Warnings .................................................................................. 24
iii
AWS SDK for Java Developer Guide
iv
AWS SDK for Java Developer Guide
v
AWS SDK for Java Developer Guide
AWS SDK for Java 2.0 Developer Preview
See the AWS Toolkit for Eclipse User Guide for full documentation.
1
AWS SDK for Java Developer Guide
Viewing the SDK's Revision History
The easiest way to build the documentation is using Apache's Maven build tool. Download and install
Maven first if you don't already have it on your system, then use the following instructions to build the
reference documentation.
1. Locate and select the SDK version that you're using on the releases page of the SDK repository on
GitHub.
2. Choose either the zip (most platforms, including Windows) or tar.gz (Linux, macOS, or Unix) link
to download the SDK to your computer.
3. Unpack the archive to a local directory.
4. On the command line, navigate to the directory where you unpacked the archive, and type the
following.
mvn javadoc:javadoc
5. After building is complete, you'll find the generated HTML documentation in the aws-java-sdk/
target/site/apidocs/ directory.
2
AWS SDK for Java Developer Guide
Sign Up for AWS and Create an IAM User
Getting Started
This section provides information about how to install, set up, and use the AWS SDK for Java.
Topics
• Sign Up for AWS and Create an IAM User (p. 3)
• Set up the AWS SDK for Java (p. 4)
• Set up AWS Credentials and Region for Development (p. 6)
• Using the SDK with Apache Maven (p. 7)
• Using the SDK with Gradle (p. 9)
Next, create an IAM user and download (or copy) its secret access key.
3
AWS SDK for Java Developer Guide
Set up the AWS SDK for Java
Next, you should set your credentials (p. 6) in the AWS shared credentials file or in the environment.
Note
If you use the Eclipse IDE, you should consider installing the AWS Toolkit for Eclipse and
providing your credentials as described in Set up AWS Credentials in the AWS Toolkit for Eclipse
User Guide.
Prerequisites
To use the AWS SDK for Java, you must have:
• Apache Maven– If you use Apache Maven, you can specify the entire SDK (or specific SDK components)
as dependencies in your project. See Using the SDK with Apache Maven (p. 7) for details about
how to set up the SDK when using Maven.
• Gradle– If you use Gradle, you can import the Maven Bill of Materials (BOM) in your Gradle project
to automatically manage SDK dependencies. See Using the SDK with Gradle (p. 9) for more
infomation.
• Eclipse IDE– If you use the Eclipse IDE, you may want to install and use the AWS Toolkit for Eclipse,
which will automatically download, install and update the Java SDK for you. For more information and
setup instructions, see the AWS Toolkit for Eclipse User Guide.
If you intend to build your projects using a different IDE, with Apache Ant or by any other means, then
download and extract the SDK as shown in the next section.
4
AWS SDK for Java Developer Guide
Installing previous versions of the SDK
2. After downloading the SDK, extract the contents into a local directory.
• documentation– contains the API documentation (also available on the web: AWS SDK for Java API
Reference).
• lib– contains the SDK .jar files.
• samples– contains working sample code that demonstrates how to use the SDK.
• third-party– contains third-party libraries that are used by the SDK, such as Apache commons
logging, AspectJ and the Spring framework.
To use the SDK, add the full path to the lib and third-party directories to the dependencies in your
build file, and add them to your java CLASSPATH to run your code.
1. Go to the SDK's GitHub page at: AWS SDK for Java (GitHub).
2. Choose the tag corresponding to the version number of the SDK that you want. For example,
1.6.10.
3. Click the Download ZIP button to download the version of the SDK you selected.
4. Unzip the file to a directory on your development system. On many systems, you can use your
graphical file manager to do this, or use the unzip utility in a terminal window.
5. In a terminal window, navigate to the directory where you unzipped the SDK source.
6. Build and install the SDK with the following command (Maven required):
mvn javadoc:javadoc
5
AWS SDK for Java Developer Guide
Set up AWS Credentials and Region for Development
Choosing a JVM
For the best performance of your server-based applications with the AWS SDK for Java, we recommend
that you use the 64-bit version of the Java Virtual Machine (JVM). This JVM runs only in server mode,
even if you specify the -Client option at run time.
Using the 32-bit version of the JVM with the -Server option at run time should provide comparable
performance to the 64-bit JVM.
This topic provides basic information about setting up your AWS credentials for local application
development using the AWS SDK for Java. If you need to set up credentials for use within an EC2
instance or if you're using the Eclipse IDE for development, refer to the following topics instead:
• When using an EC2 instance, create an IAM role and then give your EC2 instance access to that role as
shown in Using IAM Roles to Grant Access to AWS Resources on Amazon EC2 (p. 56).
• Set up AWS credentials within Eclipse using the AWS Toolkit for Eclipse. See Set up AWS Credentials in
the AWS Toolkit for Eclipse User Guide for more information.
• Set credentials in the AWS credentials profile file on your local system, located at:
• ~/.aws/credentials on Linux, macOS, or Unix
• C:\Users\USERNAME \.aws\credentials on Windows
[default]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key
Substitute your own AWS credentials values for the values your_access_key_id and
your_secret_access_key.
• Set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables.
export AWS_ACCESS_KEY_ID=your_access_key_id
export AWS_SECRET_ACCESS_KEY=your_secret_access_key
set AWS_ACCESS_KEY_ID=your_access_key_id
6
AWS SDK for Java Developer Guide
Setting the AWS Region
set AWS_SECRET_ACCESS_KEY=your_secret_access_key
• For an EC2 instance, specify an IAM role and then give your EC2 instance access to that role. See IAM
Roles for Amazon EC2 in the Amazon EC2 User Guide for Linux Instances for a detailed discussion about
how this works.
Once you have set your AWS credentials using one of these methods, they will be loaded automatically
by the AWS SDK for Java by using the default credential provider chain. For further information about
working with AWS credentials in your Java applications, see Working with AWS Credentials (p. 14).
You can use similar techniques to setting credentials to set your default AWS region:
• Set the AWS Region in the AWS config file on your local system, located at:
• ~/.aws/config on Linux, macOS, or Unix
• C:\Users\USERNAME\.aws\config on Windows
[default]
region = your_aws_region
Substitute your desired AWS Region (for example, "us-west-2") for your_aws_region.
• Set the AWS_REGION environment variable.
export AWS_REGION=your_aws_region
set AWS_REGION=your_aws_region
7
AWS SDK for Java Developer Guide
Configure the SDK as a Maven dependency
mvn -B archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DgroupId=org.example.basicapp \
-DartifactId=myapp
Replace org.example.basicapp with the full package namespace of your application, and myapp with the
name of your project (this will become the name of the directory for your project).
By default, Maven creates a project template for you using the quickstart archetype, which is a good
starting place for many projects. There are more archetypes available; visit the Maven archetypes page
for a list of archetypes packaged with Maven. You can choose a particular archetype to use by adding the
-DarchetypeArtifactId argument to the archetype:generate command. For example:
mvn archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DarchetypeArtifactId=maven-archetype-webapp \
-DgroupId=org.example.webapp \
-DartifactId=mywebapp
Note
Much more information about creating and configuring Maven projects is provided in the Maven
Getting Started Guide.
To use the BOM, add a <dependencyManagement> section to your application's pom.xml file, adding
aws-java-sdk-bom as a dependency and specifying the version of the SDK you want to use:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-bom</artifactId>
<version>1.11.106</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
To view the latest version of the AWS SDK for Java BOM that is available on Maven Central, visit: https://
mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-bom. You can also use this page to see which
modules (dependencies) are managed by the BOM that you can include within the <dependencies>
section of your project's pom.xml file.
You can now select individual modules from the SDK that you use in your application. Because you
already declared the SDK version in the BOM, you don't need to specify the version number for each
component.
8
AWS SDK for Java Developer Guide
Build your project
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-dynamodb</artifactId>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.106</version>
</dependency>
</dependencies>
mvn package
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:1.0.3.RELEASE"
9
AWS SDK for Java Developer Guide
Using the SDK with Gradle
}
}
dependencyManagement {
imports {
mavenBom 'com.amazonaws:aws-java-sdk-bom:1.11.228'
}
}
3. Specify the SDK modules that you'll be using in the dependencies section
dependencies {
compile 'com.amazonaws:aws-java-sdk-s3'
testCompile group: 'junit', name: 'junit', version: '4.11'
}
Gradle will automatically resolve the correct version of your SDK dependencies using the information
from the BOM.
group 'aws.test'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:1.0.3.RELEASE"
}
}
dependencyManagement {
imports {
mavenBom 'com.amazonaws:aws-java-sdk-bom:1.11.228'
}
}
dependencies {
compile 'com.amazonaws:aws-java-sdk-s3'
testCompile group: 'junit', name: 'junit', version: '4.11'
}
Note
For more detail about specifying SDK dependencies using the BOM, see Using the SDK with
Apache Maven (p. 7).
10
AWS SDK for Java Developer Guide
Best Practices for AWS Development
with the AWS SDK for Java
For service-specific programming information and examples (for Amazon EC2, Amazon S3, Amazon SWF,
etc.), see AWS SDK for Java Code Examples (p. 33).
Topics
• Best Practices for AWS Development with the AWS SDK for Java (p. 11)
• Creating Service Clients (p. 12)
• Working with AWS Credentials (p. 14)
• AWS Region Selection (p. 17)
• Exception Handling (p. 19)
• Asynchronous Programming (p. 20)
• Logging AWS SDK for Java Calls (p. 23)
• Client Networking Configuration (p. 25)
• Access Control Policies (p. 27)
• Setting the JVM TTL for DNS Name Lookups (p. 29)
• Enabling Metrics for the AWS SDK for Java (p. 29)
Amazon S3
Avoid ResetExceptions
When you upload objects to Amazon S3 by using streams (either through an AmazonS3 client or
TransferManager), you might encounter network connectivity or timeout issues. By default, the AWS SDK
for Java attempts to retry failed transfers by marking the input stream before the start of a transfer and
then resetting it before retrying.
If the stream doesn't support mark and reset, the SDK throws a ResetException when there are transient
failures and retries are enabled.
Best Practice
We recommend that you use streams that support mark and reset operations.
The most reliable way to avoid a ResetException is to provide data by using a File or FileInputStream,
which the AWS SDK for Java can handle without being constrained by mark and reset limits.
11
AWS SDK for Java Developer Guide
Creating Service Clients
If the stream isn't a FileInputStream but does support mark and reset, you can set the mark limit by
using the setReadLimit method of RequestClientOptions. Its default value is 128 KB. Setting the read
limit value to one byte greater than the size of stream will reliably avoid a ResetException.
For example, if the maximum expected size of a stream is 100,000 bytes, set the read limit to 100,001
(100,000 + 1) bytes. The mark and reset will always work for 100,000 bytes or less. Be aware that this
might cause some streams to buffer that number of bytes into memory.
Each AWS service has a service interface with methods for each action in the service API. For example,
the service interface for Amazon DynamoDB is named AmazonDynamoDB. Each service interface has a
corresponding client builder you can use to construct an implementation of the service interface. The
client builder class for DynamoDB is named AmazonDynamoDBClientBuilder.
Once you have a builder, you can customize the client's properties by using many fluent setters in the
builder API. For example, you can set a custom region and a custom credentials provider, as follows.
Note
The fluent withXXX methods return the builder object so that you can chain the method calls
for convenience and for more readable code. After you configure the properties you want, you
can call the build method to create the client. Once a client is created, it's immutable and any
calls to setRegion or setEndpoint will fail.
A builder can create multiple clients with the same configuration. When you're writing your application,
be aware that the builder is mutable and not thread-safe.
The following code uses the builder as a factory for client instances.
The builder also exposes fluent setters for ClientConfiguration' and RequestMetricCollector, and a
custom list of RequestHandler2.
12
AWS SDK for Java Developer Guide
Creating Async Clients
In addition to the configuration options that the synchronous (or sync) client builder supports, the
async client enables you to set a custom ExecutorFactory to change the ExecutorService that the
async client uses. ExecutorFactory is a functional interface, so it interoperates with Java 8 lambda
expressions and method references.
Using DefaultClient
Both the sync and async client builders have another factory method named defaultClient.
This method creates a service client with the default configuration, using the default provider chain
to load credentials and the AWS Region. If credentials or the region can't be determined from the
environment that the application is running in, the call to defaultClient fails. See Working with AWS
Credentials (p. 14) and AWS Region Selection (p. 17) for more information about how credentials
and region are determined.
Client Lifecycle
Service clients in the SDK are thread-safe and, for best performance, you should treat them as long-lived
objects. Each client has its own connection pool resource that is shut down when the client is garbage
13
AWS SDK for Java Developer Guide
Working with AWS Credentials
collected. To explicitly shut down a client, call the shutdown method. After calling shutdown, all client
resources are released and the client is unusable.
Important
For security, we strongly recommend that you use IAM users instead of the root account for AWS
access. For more information, see IAM Best Practices in the IAM User Guide.
You can create a credentials file by using the aws configure command provided by the AWS CLI,
or you can create it by editing the file with a text editor. For information about the credentials file
format, see AWS Credentials File Format (p. 16).
4. Amazon ECS container credentials– loaded from the Amazon ECS if the environment variable
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI is set. The AWS SDK for Java uses the
ContainerCredentialsProvider to load these credentials.
5. Instance profile credentials– used on EC2 instances, and delivered through the Amazon EC2
metadata service. The AWS SDK for Java uses the InstanceProfileCredentialsProvider to load these
credentials.
Note
Instance profile credentials are used only if AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
is not set. See EC2ContainerCredentialsProviderWrapper for more information.
14
AWS SDK for Java Developer Guide
Using the Default Credential Provider Chain
Setting Credentials
To be able to use AWS credentials, they must be set in at least one of the preceding locations. For
information about setting credentials, see the following topics:
• To specify credentials in the environment or in the default credential profiles file, see Set up AWS
Credentials and Region for Development (p. 6).
• To set Java system properties, see the System Properties tutorial on the official Java Tutorials website.
• To set up and use instance profile credentials with your EC2 instances, see Using IAM Roles to Grant
Access to AWS Resources on Amazon EC2 (p. 56).
You can use the AWS Profile environment variable to change the profile loaded by the SDK.
For example, on Linux, macOS, or Unix you would run the following command to change the profile to
myProfile.
export AWS_PROFILE="myProfile"
set AWS_PROFILE="myProfile"
Setting the AWS_PROFILE environment variable affects credential loading for all officially supported
AWS SDKs and Tools (including the AWS CLI and the AWS CLI for PowerShell). To change only the profile
for a Java application, you can use the system property aws.profile instead.
Note
The environment variable takes precedence over the system property.
You can use this feature to temporarily change the location where the AWS SDK for Java looks for
your credentials file (for example, by setting this variable with the command line). Or you can set the
environment variable in your user or system environment to change it for the user or systemwide.
export AWS_CREDENTIAL_PROFILES_FILE=path/to/credentials_file
15
AWS SDK for Java Developer Guide
Specifying a Credential Provider or Provider Chain
set AWS_CREDENTIAL_PROFILES_FILE=path/to/credentials_file
[default]
aws_access_key_id={YOUR_ACCESS_KEY_ID}
aws_secret_access_key={YOUR_SECRET_ACCESS_KEY}
[profile2]
aws_access_key_id={YOUR_ACCESS_KEY_ID}
aws_secret_access_key={YOUR_SECRET_ACCESS_KEY}
The profile name is specified in square brackets (for example, [default]), followed by the configurable
fields in that profile as key-value pairs. You can have multiple profiles in your credentials file, which
can be added or edited using aws configure --profile PROFILE_NAME to select the profile to
configure.
Loading Credentials
After you set credentials, you can load them by using the default credential provider chain.
To do this, you instantiate an AWS Service client without explicitly providing credentials to the builder, as
follows.
You provide an instance of a credentials provider or provider chain to a client builder that takes an
AWSCredentialsProvider interface as input. The following example shows how to use environment
credentials specifically.
For the full list of AWS SDK for Java-supplied credential providers and provider chains, see All Known
Implementing Classes in AWSCredentialsProvider.
Note
You can use this technique to supply credential providers or provider chains that you create by
using your own credential provider that implements the AWSCredentialsProvider interface,
or by subclassing the AWSCredentialsProviderChain class.
16
AWS SDK for Java Developer Guide
Explicitly Specifying Credentials
1. Instantiate a class that provides the AWSCredentials interface, such as BasicAWSCredentials, and
supply it with the AWS access key and secret key you will use for the connection.
2. Create an AWSStaticCredentialsProvider with the AWSCredentials object.
3. Configure the client builder with the AWSStaticCredentialsProvider and build the client.
When using temporary credentials obtained from STS (p. 141), create a BasicSessionCredentials object,
passing it the STS-supplied credentials and session token.
AmazonS3 s3 = AmazonS3ClientBuilder.standard()
.withCredentials(new
AWSStaticCredentialsProvider(sessionCredentials)
.build();
More Info
• Sign Up for AWS and Create an IAM User (p. 3)
• Set up AWS Credentials and Region for Development (p. 6)
• Using IAM Roles to Grant Access to AWS Resources on Amazon EC2 (p. 56)
Region.getRegion(Regions.US_WEST_2)
.isServiceSupported(AmazonDynamoDB.ENDPOINT_PREFIX);
17
AWS SDK for Java Developer Guide
Choosing a Region
See the Regions class documentation for the regions you can specify, and use the endpoint prefix of
the service to query. Each service's endpoint prefix is defined in the service interface. For example, the
DynamoDB endpoint prefix is defined in AmazonDynamoDB.
Choosing a Region
Beginning with version 1.4 of the AWS SDK for Java, you can specify a region name and the SDK will
automatically choose an appropriate endpoint for you. To choose the endpoint yourself, see Choosing a
Specific Endpoint (p. 18).
To explicitly set a region, we recommend that you use the Regions enum. This is an enumeration of all
publicly available regions. To create a client with a region from the enum, use the following code.
If the region you are attempting to use isn't in the Regions enum, you can set the region using a string
that represents the name of the region.
Note
After you build a client with the builder, it's immutable and the region cannot be changed. If you
are working with multiple AWS Regions for the same service, you should create multiple clients
—one per region.
For example, to configure the Amazon EC2 client to use the EU (Ireland) Region, use the following code.
See Regions and Endpoints for the current list of regions and their corresponding endpoints for all AWS
services.
When running on Amazon EC2 or Lambda, you might want to configure clients to use the same region
that your code is running on. This decouples your code from the environment it's running in and makes it
easier to deploy your application to multiple regions for lower latency or redundancy.
You must use client builders to have the SDK automatically detect the region your code is running in.
18
AWS SDK for Java Developer Guide
Exception Handling
To use the default credential/region provider chain to determine the region from the environment, use
the client builder's defaultClient method.
If you don't explicitly set a region using the withRegion methods, the SDK consults the default region
provider chain to try and determine the region to use.
1. Any explicit region set by using withRegion or setRegion on the builder itself takes precedence
over anything else.
2. The AWS_REGION environment variable is checked. If it's set, that region is used to configure the
client.
Note
This environment variable is set by the Lambda container.
3. The SDK checks the AWS shared configuration file (usually located at ~/.aws/config). If the region
property is present, the SDK uses it.
• The AWS_CONFIG_FILE environment variable can be used to customize the location of the shared
config file.
• The AWS_PROFILE environment variable or the aws.profile system property can be used to
customize the profile that is loaded by the SDK.
4. The SDK attempts to use the Amazon EC2 instance metadata service to determine the region of the
currently running Amazon EC2 instance.
5. If the SDK still hasn't found a region by this point, client creation fails with an exception.
When developing AWS applications, a common approach is to use the shared configuration file (described
in Using the Default Credential Provider Chain (p. 14)) to set the region for local development, and
rely on the default region provider chain to determine the region when running on AWS infrastructure.
This greatly simplifies client creation and keeps your application portable.
Exception Handling
Understanding how and when the AWS SDK for Java throws exceptions is important to building high-
quality applications using the SDK. The following sections describe the different cases of exceptions that
are thrown by the SDK and how to handle them appropriately.
• To allow developers fine-grained control over the errors they want to handle without forcing them to
handle exceptional cases they aren't concerned about (and making their code overly verbose)
19
AWS SDK for Java Developer Guide
AmazonServiceException (and Subclasses)
In general, checked exceptions work well on small scales, but can become troublesome as applications
grow and become more complex.
For more information about the use of checked and unchecked exceptions, see:
When you encounter an AmazonServiceException, you know that your request was successfully sent
to the AWS service but couldn't be successfully processed. This can be because of errors in the request's
parameters or because of issues on the service side.
AmazonServiceException also includes information about whether the failed request was the caller's
fault (a request with illegal values) or the AWS service's fault (an internal service error).
AmazonClientException
AmazonClientException indicates that a problem occurred inside the Java client code, either while trying
to send a request to AWS or while trying to parse a response from AWS. An AmazonClientException
is generally more severe than an AmazonServiceException, and indicates a major problem that is
preventing the client from making service calls to AWS services. For example, the AWS SDK for Java
throws an AmazonClientException if no network connection is available when you try to call an
operation on one of the clients.
Asynchronous Programming
You can use either synchronous or asynchronous methods to call operations on AWS services.
Synchronous methods block your thread's execution until the client receives a response from the service.
Asynchronous methods return immediately, giving control back to the calling thread without waiting for
a response.
Because an asynchronous method returns before a response is available, you need a way to get the
response when it's ready. The AWS SDK for Java provides two ways: Future objects and callback methods.
20
AWS SDK for Java Developer Guide
Java Futures
Java Futures
Asynchronous methods in the AWS SDK for Java return a Future object that contains the results of the
asynchronous operation in the future.
Call the Future isDone() method to see if the service has provided a response object yet. When the
response is ready, you can get the response object by calling the Future get() method. You can use
this mechanism to periodically poll for the asynchronous operation's results while your application
continues to work on other things.
Here is an example of an asynchronous operation that calls a Lambda function, receiving a Future that
can hold an InvokeResult object. The InvokeResult object is retrieved only after isDone() is true.
import com.amazonaws.services.lambda.AWSLambdaAsyncClient;
import com.amazonaws.services.lambda.model.InvokeRequest;
import com.amazonaws.services.lambda.model.InvokeResult;
import java.nio.ByteBuffer;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
try {
InvokeResult res = future_res.get();
if (res.getStatusCode() == 200) {
System.out.println("\nLambda function returned:");
ByteBuffer response_payload = res.getPayload();
System.out.println(new String(response_payload.array()));
}
else {
System.out.format("Received a non-OK response from AWS: %d\n",
res.getStatusCode());
}
}
catch (InterruptedException | ExecutionException e) {
System.err.println(e.getMessage());
System.exit(1);
}
21
AWS SDK for Java Developer Guide
Asynchronous Callbacks
System.exit(0);
}
}
Asynchronous Callbacks
In addition to using the Java Future object to monitor the status of asynchronous requests, the SDK
also enables you to implement a class that uses the AsyncHandler interface. AsyncHandler provides
two methods that are called depending on how the request completed: onSuccess and onError.
The major advantage of the callback interface approach is that it frees you from having to poll the
Future object to find out when the request has completed. Instead, your code can immediately start its
next activity, and rely on the SDK to call your handler at the right time.
import com.amazonaws.services.lambda.AWSLambdaAsync;
import com.amazonaws.services.lambda.AWSLambdaAsyncClientBuilder;
import com.amazonaws.services.lambda.model.InvokeRequest;
import com.amazonaws.services.lambda.model.InvokeResult;
import com.amazonaws.handlers.AsyncHandler;
import java.nio.ByteBuffer;
import java.util.concurrent.Future;
22
AWS SDK for Java Developer Guide
Best Practices
System.out.print(".");
}
}
}
Best Practices
Callback Execution
Your implementation of AsyncHandler is executed inside the thread pool owned by the asynchronous
client. Short, quickly executed code is most appropriate inside your AsyncHandler implementation.
Long-running or blocking code inside your handler methods can cause contention for the thread pool
used by the asynchronous client, and can prevent the client from executing requests. If you have a long-
running task that needs to begin from a callback, have the callback run its task in a new thread or in a
thread pool managed by your application.
For example, you could provide an ExecutorService implementation that uses a custom
ThreadFactory to control how threads in the pool are named, or to log additional information about
thread usage.
Supported logging systems include the Java Logging Framework and Apache Log4j, among others.
This topic shows you how to use Log4j. You can use the SDK's logging functionality without making any
changes to your application code.
23
AWS SDK for Java Developer Guide
Setting the Classpath
Log4j uses a configuration file, log4j.properties. Example configuration files are shown below. Copy this
configuration file to a directory on your classpath. The Log4j JAR and the log4j.properties file don't have
to be in the same directory.
The log4j.properties configuration file specifies properties such as logging level, where logging output
is sent (for example, to a file or to the console), and the format of the output. The logging level is
the granularity of output that the logger generates. Log4j supports the concept of multiple logging
hierarchies. The logging level is set independently for each hierarchy. The following two logging
hierarchies are available in the AWS SDK for Java:
• log4j.logger.com.amazonaws
• log4j.logger.org.apache.http.wire
<path id="aws.java.sdk.classpath">
<fileset dir="../../third-party" includes="**/*.jar"/>
<fileset dir="../../lib" includes="**/*.jar"/>
<pathelement location="."/>
</path>
If you're using the Eclipse IDE, you can set the classpath by opening the menu and navigating to Project |
Properties | Java Build Path.
The following log4j.properties file sets the rootLogger to WARN, which causes warning and error
messages from all loggers in the "com.amazonaws" hierarchy to be included. Alternatively, you can
explicitly set the com.amazonaws logger to WARN.
log4j.rootLogger=WARN, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
# Or you can explicitly enable WARN and ERROR messages for the AWS Java clients
log4j.logger.com.amazonaws=WARN
24
AWS SDK for Java Developer Guide
Verbose Wire Logging
The following log4j.properties file enables a summary of requests and responses, including AWS request
IDs.
log4j.rootLogger=WARN, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
# Turn on DEBUG logging in com.amazonaws.request to log
# a summary of requests/responses with AWS request IDs
log4j.logger.com.amazonaws.request=DEBUG
The following log4j.properties file turns on full wire logging in Apache HttpClient 4 and should only be
turned on temporarily because it can have a significant performance impact on your application.
log4j.rootLogger=WARN, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
# Log all HTTP content (headers, parameters, content, etc) for
# all requests and responses. Use caution with this since it can
# be very expensive to log such verbose data!
log4j.logger.org.apache.http.wire=DEBUG
25
AWS SDK for Java Developer Guide
Proxy Configuration
Proxy Configuration
When constructing a client object, you can pass in an optional ClientConfiguration object to customize
the client's configuration.
If you connect to the Internet through a proxy server, you'll need to configure your proxy server settings
(proxy host, port, and username/password) through the ClientConfiguration object.
Each of the configurable values has a default value defined by a constant. For a list of the constant
values for ClientConfiguration, see Constant Field Values in the AWS SDK for Java API Reference.
Local Address
To set the local address that the HTTP client will bind to, use ClientConfiguration.setLocalAddress.
Maximum Connections
You can set the maximum allowed number of open HTTP connections by using the
ClientConfiguration.setMaxConnections method.
Proxy Options
If you use a proxy with your HTTP connections, you might need to set certain options related to HTTP
proxies.
• Connection Timeout
The connection timeout is the amount of time (in milliseconds) that the HTTP connection will wait to
establish a connection before giving up. The default is 50,000 ms.
By default, the SDK will attempt to reuse HTTP connections as long as possible. In failure situations
where a connection is established to a server that has been brought out of service, having a finite TTL
can help with application recovery. For example, setting a 15 minute TTL will ensure that even if you
have a connection established to a server that is experiencing issues, you'll reestablish a connection to
a new server within 15 minutes.
26
AWS SDK for Java Developer Guide
TCP Socket Buffer Size Hints
The default maximum retry count for retriable errors is 3. You can set a different value by using the
ClientConfiguration.setMaxErrorRetry method.
Optimal TCP buffer sizes for an application are highly dependent on network and operating system
configuration and capabilities. For example, most modern operating systems provide auto-tuning logic
for TCP buffer sizes.This can have a big impact on performance for TCP connections that are held open
long enough for the auto-tuning to optimize buffer sizes.
Large buffer sizes (e.g., 2 MB) allow the operating system to buffer more data in memory without
requiring the remote server to acknowledge receipt of that information, and so can be particularly useful
when the network has high latency.
This is only a hint, and the operating system might not to honor it. When using this option, users should
always check the operating system's configured limits and defaults. Most operating systems have a
maximum TCP buffer size limit configured, and won't let you go beyond that limit unless you explicitly
raise the maximum TCP buffer size limit.
Many resources are available to help with configuring TCP buffer sizes and operating system-specific TCP
settings, including the following:
Where:
• A is the principal– The AWS account that is making a request to access or modify one of your AWS
resources.
• B is the action– The way in which your AWS resource is being accessed or modified, such as sending a
message to an Amazon SQS queue, or storing an object in an Amazon S3 bucket.
• C is the resource– The AWS entity that the principal wants to access, such as an Amazon SQS queue, or
an object stored in Amazon S3.
• D is a set of conditions– The optional constraints that specify when to allow or deny access for the
principal to access your resource. Many expressive conditions are available, some specific to each
service. For example, you can use date conditions to allow access to your resources only after or before
a specific time.
27
AWS SDK for Java Developer Guide
Amazon S3 Example
Amazon S3 Example
The following example demonstrates a policy that allows anyone access to read all the objects in a
bucket, but restricts access to uploading objects to that bucket to two specific AWS accounts (in addition
to the bucket owner's account).
AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
s3.setBucketPolicy(myBucketName, policy.toJson());
Condition endpointCondition =
SNSConditionFactory.newEndpointCondition("*@mycompany.com");
28
AWS SDK for Java Developer Guide
Setting the JVM TTL for DNS Name Lookups
Because AWS resources use DNS name entries that occasionally change, we recommend that you
configure your JVM with a TTL value of no more than 60 seconds. This ensures that when a resource's
IP address changes, your application will be able to receive and use the resource's new IP address by
requerying the DNS.
On some Java configurations, the JVM default TTL is set so that it will never refresh DNS entries until
the JVM is restarted. Thus, if the IP address for an AWS resource changes while your application is still
running, it won't be able to use that resource until you manually restart the JVM and the cached IP
information is refreshed. In this case, it's crucial to set the JVM's TTL so that it will periodically refresh its
cached IP information.
Note
The default TTL can vary according to the version of your JVM and whether a security manager
is installed. Many JVMs provide a default TTL less than 60 seconds. If you're using such a JVM
and not using a security manager, you can ignore the remainder of this topic.
• globally, for all applications that use the JVM. Set networkaddress.cache.ttl in the
$JAVA_HOME/jre/lib/security/java.security file:
networkaddress.cache.ttl=60
• for your application only, set networkaddress.cache.ttl in your application's initialization code:
java.security.Security.setProperty("networkaddress.cache.ttl" , "60");
-Dcom.amazonaws.sdk.enableDefaultMetrics=credentialFile=/path/aws.properties
You need to specify the path to your credential file so that the SDK can upload the gathered datapoints
to CloudWatch for later analysis.
29
AWS SDK for Java Developer Guide
Available Metric Types
Note
If you are accessing AWS from an Amazon EC2 instance using the Amazon EC2 instance
metadata service, you don’t need to specify a credential file. In this case, you need only specify:
-Dcom.amazonaws.sdk.enableDefaultMetrics
All metrics captured by the SDK for Java are under the namespace AWSSDK/Java, and are uploaded
to the CloudWatch default region (us-east-1). To change the region, specify it by using the
cloudwatchRegion attribute in the system property. For example, to set the CloudWatch region to us-
west-2, use:
-Dcom.amazonaws.sdk.enableDefaultMetrics=credentialFile=/path/
aws.properties,cloudwatchRegion=us-west-2
Once you enable the feature, every time there is a service request to AWS from the AWS SDK for Java,
metric data points will be generated, queued for statistical summary, and uploaded asynchronously
to CloudWatch about once every minute. Once metrics have been uploaded, you can visualize them
using the AWS Management Console and set alarms on potential problems such as memory leakage, file
descriptor leakage, and so on.
Covers areas such as the latency of the HTTP request/response, number of requests, exceptions, and
retries.
30
AWS SDK for Java Developer Guide
Available Metric Types
Include AWS service-specific data, such as the throughput and byte count for S3 uploads and
downloads.
Machine Metrics
Cover the runtime environment, including heap memory, number of threads, and open file
descriptors.
31
AWS SDK for Java Developer Guide
More Information
If you want to exclude Machine Metrics, add excludeMachineMetrics to the system property:
-Dcom.amazonaws.sdk.enableDefaultMetrics=credentialFile=/path/
aws.properties,excludeMachineMetrics
More Information
• See the amazonaws/metrics package summary for a full list of the predefined core metric types.
• Learn about working with CloudWatch using the AWS SDK for Java in CloudWatch Examples Using the
AWS SDK for Java (p. 35).
32
AWS SDK for Java Developer Guide
SDK Code Samples
Topics
• AWS SDK for Java Code Samples (p. 33)
• CloudWatch Examples Using the AWS SDK for Java (p. 35)
• DynamoDB Examples Using the AWS SDK for Java (p. 42)
• Amazon EC2 Examples Using the AWS SDK for Java (p. 52)
• IAM Examples Using the AWS SDK for Java (p. 91)
• Amazon S3 Examples Using the AWS SDK for Java (p. 104)
• Amazon SQS Examples Using the AWS SDK for Java (p. 132)
• Getting Temporary Credentials with AWS STS (p. 141)
• Amazon SWF Examples Using the AWS SDK for Java (p. 144)
You can also view the latest samples on the AWS SDK for Java GitHub repository, in the src/samples
directory.
Prerequisites
Before running any of the AWS SDK for Java samples, you need to set your AWS credentials in
the environment or with the AWS CLI, as specified in Set up AWS Credentials and Region for
Development (p. 6). The samples use the default credential provider chain whenever possible. So by
33
AWS SDK for Java Developer Guide
Building and Running the Samples Using the Eclipse IDE
setting your credentials in this way, you can avoid the risky practice of inserting your AWS credentials in
files within the source code directory (where they may inadvertently be checked in and shared publicly).
1. Change to the directory containing the sample's code. For example, if you're in the root directory of
the AWS SDK download and want to run the AwsConsoleApp sample, you would type:
cd samples/AwsConsoleApp
2. Build and run the sample with Ant. The default build target performs both actions, so you can just
enter:
ant
===========================================
===========================================
You have access to 4 Availability Zones.
You have 23 Amazon S3 bucket(s), containing 44 objects with a total size of 154767691
bytes.
Prerequisites
After installing the AWS Toolkit for Eclipse, we recommend configuring the Toolkit with your security
credentials. You can do this anytime by choosing Preferences from the Window menu in Eclipse, and
then choosing the AWS Toolkit section.
1. Open Eclipse.
2. Create a new AWS Java project. In Eclipse, on the File menu, choose New, and then click Project. The
New Project wizard opens.
3. Expand the AWS category, then choose AWS Java Project.
4. Choose Next. The project settings page is displayed.
34
AWS SDK for Java Developer Guide
Amazon CloudWatch Examples
5. Enter a name in the Project Name box. The AWS SDK for Java Samples group displays the samples
available in the SDK, as described previously.
6. Select the samples you want to include in your project by selecting each check box.
7. Enter your AWS credentials. If you've already configured the AWS Toolkit for Eclipse with your
credentials, this is automatically filled in.
8. Choose Finish. The project is created and added to the Project Explorer.
1. Choose the sample .java file you want to run. For example, for the Amazon S3 sample, choose
S3Sample.java.
2. Choose Run from the Run menu.
1. Right-click the project in Project Explorer, point to Build Path, and then choose Add Libraries.
2. Choose AWS Java SDK, choose Next, and then follow the remaining on-screen instructions.
Amazon CloudWatch monitors your Amazon Web Services (AWS) resources and the applications you run
on AWS in real time. You can use CloudWatch to collect and track metrics, which are variables you can
measure for your resources and applications. CloudWatch alarms send notifications or automatically
make changes to the resources you are monitoring based on rules that you define.
For more information about CloudWatch, see the Amazon CloudWatch User Guide.
Note
The examples include only the code needed to demonstrate each technique. The complete
example code is available on GitHub. From there, you can download a single source file or clone
the repository locally to get all the examples to build and run.
Topics
• Getting Metrics from CloudWatch (p. 35)
• Publishing Custom Metric Data (p. 36)
• Working with CloudWatch Alarms (p. 37)
• Using Alarm Actions in CloudWatch (p. 39)
• Sending Events to CloudWatch (p. 40)
35
AWS SDK for Java Developer Guide
Publishing Custom Metric Data
Imports
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.ListMetricsRequest;
import com.amazonaws.services.cloudwatch.model.ListMetricsResult;
import com.amazonaws.services.cloudwatch.model.Metric;
Code
final AmazonCloudWatch cw =
AmazonCloudWatchClientBuilder.defaultClient();
while(!done) {
ListMetricsResult response = cw.listMetrics(request);
request.setNextToken(response.getNextToken());
if(response.getNextToken() == null) {
done = true;
}
}
The metrics are returned in a ListMetricsResult by calling its getMetrics method. The results may be
paged. To retrieve the next batch of results, call setNextToken on the original request object with
the return value of the ListMetricsResult object's getNextToken method, and pass the modified
request object back to another call to listMetrics.
More Information
• ListMetrics in the Amazon CloudWatch API Reference.
Imports
36
AWS SDK for Java Developer Guide
Working with CloudWatch Alarms
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.Dimension;
import com.amazonaws.services.cloudwatch.model.MetricDatum;
import com.amazonaws.services.cloudwatch.model.PutMetricDataRequest;
import com.amazonaws.services.cloudwatch.model.PutMetricDataResult;
import com.amazonaws.services.cloudwatch.model.StandardUnit;
Code
final AmazonCloudWatch cw =
AmazonCloudWatchClientBuilder.defaultClient();
More Information
• Using Amazon CloudWatch Metrics in the Amazon CloudWatch User Guide.
• AWS Namespaces in the Amazon CloudWatch User Guide.
• PutMetricData in the Amazon CloudWatch API Reference.
Imports
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.ComparisonOperator;
import com.amazonaws.services.cloudwatch.model.Dimension;
import com.amazonaws.services.cloudwatch.model.PutMetricAlarmRequest;
import com.amazonaws.services.cloudwatch.model.PutMetricAlarmResult;
import com.amazonaws.services.cloudwatch.model.StandardUnit;
import com.amazonaws.services.cloudwatch.model.Statistic;
Code
final AmazonCloudWatch cw =
AmazonCloudWatchClientBuilder.defaultClient();
37
AWS SDK for Java Developer Guide
Working with CloudWatch Alarms
List Alarms
To list the CloudWatch alarms that you have created, call the AmazonCloudWatchClient's
describeAlarms method with a DescribeAlarmsRequest that you can use to set options for the result.
Imports
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.DescribeAlarmsRequest;
import com.amazonaws.services.cloudwatch.model.DescribeAlarmsResult;
import com.amazonaws.services.cloudwatch.model.MetricAlarm;
Code
final AmazonCloudWatch cw =
AmazonCloudWatchClientBuilder.defaultClient();
while(!done) {
request.setNextToken(response.getNextToken());
if(response.getNextToken() == null) {
done = true;
}
}
The list of alarms can be obtained by calling getMetricAlarms on the DescribeAlarmsResult that is
returned by describeAlarms.
38
AWS SDK for Java Developer Guide
Using Alarm Actions in CloudWatch
The results may be paged. To retrieve the next batch of results, call setNextToken on the original
request object with the return value of the DescribeAlarmsResult object's getNextToken method,
and pass the modified request object back to another call to describeAlarms.
Note
You can also retrieve alarms for a specific metric by using the AmazonCloudWatchClient's
describeAlarmsForMetric method. Its use is similar to describeAlarms.
Delete Alarms
To delete CloudWatch alarms, call the AmazonCloudWatchClient's deleteAlarms method with a
DeleteAlarmsRequest containing one or more names of alarms that you want to delete.
Imports
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.DeleteAlarmsRequest;
import com.amazonaws.services.cloudwatch.model.DeleteAlarmsResult;
Code
final AmazonCloudWatch cw =
AmazonCloudWatchClientBuilder.defaultClient();
More Information
• Creating Amazon CloudWatch Alarms in the Amazon CloudWatch User Guide
• PutMetricAlarm in the Amazon CloudWatch API Reference
• DescribeAlarms in the Amazon CloudWatch API Reference
• DeleteAlarms in the Amazon CloudWatch API Reference
Imports
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
39
AWS SDK for Java Developer Guide
Sending Events to CloudWatch
import com.amazonaws.services.cloudwatch.model.EnableAlarmActionsRequest;
import com.amazonaws.services.cloudwatch.model.EnableAlarmActionsResult;
Code
final AmazonCloudWatch cw =
AmazonCloudWatchClientBuilder.defaultClient();
Imports
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.DisableAlarmActionsRequest;
import com.amazonaws.services.cloudwatch.model.DisableAlarmActionsResult;
Code
final AmazonCloudWatch cw =
AmazonCloudWatchClientBuilder.defaultClient();
More Information
• Create Alarms to Stop, Terminate, Reboot, or Recover an Instance in the Amazon CloudWatch User
Guide
• PutMetricAlarm in the Amazon CloudWatch API Reference
• EnableAlarmActions in the Amazon CloudWatch API Reference
• DisableAlarmActions in the Amazon CloudWatch API Reference
Add Events
To add custom CloudWatch events, call the AmazonCloudWatchEventsClient's putEvents method with
a PutEventsRequest object that contains one or more PutEventsRequestEntry objects that provide details
40
AWS SDK for Java Developer Guide
Sending Events to CloudWatch
about each event. You can specify several parameters for the entry such as the source and type of the
event, resources associated with the event, and so on.
Note
You can specify a maximum of 10 events per call to putEvents.
Imports
import com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEvents;
import com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEventsClientBuilder;
import com.amazonaws.services.cloudwatchevents.model.PutEventsRequest;
import com.amazonaws.services.cloudwatchevents.model.PutEventsRequestEntry;
import com.amazonaws.services.cloudwatchevents.model.PutEventsResult;
Code
Add Rules
To create or update a rule, call the AmazonCloudWatchEventsClient's putRule method with a
PutRuleRequest with the name of the rule and optional parameters such as the event pattern, IAM role
to associate with the rule, and a scheduling expression that describes how often the rule is run.
Imports
import com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEvents;
import com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEventsClientBuilder;
import com.amazonaws.services.cloudwatchevents.model.PutRuleRequest;
import com.amazonaws.services.cloudwatchevents.model.PutRuleResult;
import com.amazonaws.services.cloudwatchevents.model.RuleState;
Code
41
AWS SDK for Java Developer Guide
Amazon DynamoDB Examples
Add Targets
Targets are the resources that are invoked when a rule is triggered. Example targets include Amazon EC2
instances, Lambda functions, Kinesis streams, Amazon ECS tasks, Step Functions state machines, and
built-in targets.
Imports
import com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEvents;
import com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEventsClientBuilder;
import com.amazonaws.services.cloudwatchevents.model.PutTargetsRequest;
import com.amazonaws.services.cloudwatchevents.model.PutTargetsResult;
import com.amazonaws.services.cloudwatchevents.model.Target;
Code
More Information
• Adding Events with PutEvents in the Amazon CloudWatch Events User Guide
• Schedule Expressions for Rules in the Amazon CloudWatch Events User Guide
• Event Types for CloudWatch Events in the Amazon CloudWatch Events User Guide
• Events and Event Patterns in the Amazon CloudWatch Events User Guide
• PutEvents in the Amazon CloudWatch Events API Reference
• PutTargets in the Amazon CloudWatch Events API Reference
• PutRule in the Amazon CloudWatch Events API Reference
Topics
• Working with Tables in DynamoDB (p. 43)
• Working with Items in DynamoDB (p. 47)
• Managing Tomcat Session State with DynamoDB (p. 50)
42
AWS SDK for Java Developer Guide
Working with Tables in DynamoDB
A primary key can be simple, consisting of a single partition (HASH) key, or composite, consisting of a
partition and a sort (RANGE) key.
Each key value has an associated data type, enumerated by the ScalarAttributeType class. The key
value can be binary (B), numeric (N), or a string (S). For more information, see Naming Rules and Data
Types in the Amazon DynamoDB Developer Guide.
• Provisioned throughput values that define the number of reserved read/write capacity units for the
table.
Note
Amazon DynamoDB pricing is based on the provisioned throughput values that you set on
your tables, so reserve only as much capacity as you think you'll need for your table.
Provisioned throughput for a table can be modified at any time, so you can adjust capacity if
your needs change.
Create a Table
Use the DynamoDB client's createTable method to create a new DynamoDB table. You need to
construct table attributes and a table schema, both of which are used to identify the primary key of your
table. You must also supply initial provisioned throughput values and a table name.
Note
If a table with the name you chose already exists, an AmazonServiceException is thrown.
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.CreateTableResult;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
Code
43
AWS SDK for Java Developer Guide
Working with Tables in DynamoDB
.withProvisionedThroughput(new ProvisionedThroughput(
new Long(10), new Long(10)))
.withTableName(table_name);
try {
CreateTableResult result = ddb.createTable(request);
System.out.println(result.getTableDescription().getTableName());
} catch (AmazonServiceException e) {
System.err.println(e.getErrorMessage());
System.exit(1);
}
Code
List Tables
You can list the tables in a particular region by calling the DynamoDB client's listTables method.
Note
If the named table doesn't exist for your account and region, a ResourceNotFoundException is
thrown.
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.ListTablesRequest;
import com.amazonaws.services.dynamodbv2.model.ListTablesResult;
Code
ListTablesRequest request;
44
AWS SDK for Java Developer Guide
Working with Tables in DynamoDB
while(more_tables) {
try {
if (last_name == null) {
request = new ListTablesRequest().withLimit(10);
}
else {
request = new ListTablesRequest()
.withLimit(10)
.withExclusiveStartTableName(last_name);
}
if (table_names.size() > 0) {
for (String cur_name : table_names) {
System.out.format("* %s\n", cur_name);
}
} else {
System.out.println("No tables found!");
System.exit(0);
}
last_name = table_list.getLastEvaluatedTableName();
if (last_name == null) {
more_tables = false;
}
By default, up to 100 tables are returned per call—use getLastEvaluatedTableName on the returned
ListTablesResult object to get the last table that was evaluated. You can use this value to start the listing
after the last returned value of the previous listing.
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughputDescription;
import com.amazonaws.services.dynamodbv2.model.TableDescription;
Code
try {
TableDescription table_info =
ddb.describeTable(table_name).getTable();
if (table_info != null) {
System.out.format("Table name : %s\n",
table_info.getTableName());
45
AWS SDK for Java Developer Guide
Working with Tables in DynamoDB
ProvisionedThroughputDescription throughput_info =
table_info.getProvisionedThroughput();
System.out.println("Throughput");
System.out.format(" Read Capacity : %d\n",
throughput_info.getReadCapacityUnits().longValue());
System.out.format(" Write Capacity: %d\n",
throughput_info.getWriteCapacityUnits().longValue());
List<AttributeDefinition> attributes =
table_info.getAttributeDefinitions();
System.out.println("Attributes");
for (AttributeDefinition a : attributes) {
System.out.format(" %s (%s)\n",
a.getAttributeName(), a.getAttributeType());
}
}
} catch (AmazonServiceException e) {
System.err.println(e.getErrorMessage());
System.exit(1);
}
Imports
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.AmazonServiceException;
Code
try {
ddb.updateTable(table_name, table_throughput);
} catch (AmazonServiceException e) {
System.err.println(e.getErrorMessage());
System.exit(1);
}
46
AWS SDK for Java Developer Guide
Working with Items in DynamoDB
Delete a Table
Call the DynamoDB client's deleteTable method and pass it the table's name.
Note
If the named table doesn't exist for your account and region, a ResourceNotFoundException is
thrown.
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
Code
try {
ddb.deleteTable(table_name);
} catch (AmazonServiceException e) {
System.err.println(e.getErrorMessage());
System.exit(1);
}
More Info
• Guidelines for Working with Tables in the Amazon DynamoDB Developer Guide
• Working with Tables in DynamoDB in the Amazon DynamoDB Developer Guide
You can use the returned GetItemResult object's getItem() method to retrieve a Map of key (String)
and value (AttributeValue) pairs that are associated with the item.
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.GetItemRequest;
import java.util.HashMap;
import java.util.Map;
47
AWS SDK for Java Developer Guide
Working with Items in DynamoDB
Code
HashMap<String,AttributeValue> key_to_get =
new HashMap<String,AttributeValue>();
try {
Map<String,AttributeValue> returned_item =
ddb.getItem(request).getItem();
if (returned_item != null) {
Set<String> keys = returned_item.keySet();
for (String key : keys) {
System.out.format("%s: %s\n",
key, returned_item.get(key).toString());
}
} else {
System.out.format("No item found with the key %s!\n", name);
}
} catch (AmazonServiceException e) {
System.err.println(e.getErrorMessage());
System.exit(1);
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException;
import java.util.ArrayList;
Code
48
AWS SDK for Java Developer Guide
Working with Items in DynamoDB
HashMap<String,AttributeValue> item_values =
new HashMap<String,AttributeValue>();
try {
ddb.putItem(table_name, item_values);
} catch (ResourceNotFoundException e) {
System.err.format("Error: The table \"%s\" can't be found.\n", table_name);
System.err.println("Be sure that it exists and that you've typed its name correctly!");
System.exit(1);
} catch (AmazonServiceException e) {
System.err.println(e.getMessage());
System.exit(1);
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.AttributeAction;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.AttributeValueUpdate;
import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException;
import java.util.ArrayList;
Code
HashMap<String,AttributeValue> item_key =
new HashMap<String,AttributeValue>();
HashMap<String,AttributeValueUpdate> updated_values =
new HashMap<String,AttributeValueUpdate>();
try {
49
AWS SDK for Java Developer Guide
Managing Tomcat Session State with DynamoDB
More Info
• Guidelines for Working with Items in the Amazon DynamoDB Developer Guide
• Working with Items in DynamoDB in the Amazon DynamoDB Developer Guide
DynamoDB, which is a NoSQL database store from AWS, avoids these drawbacks by providing an
effective solution for sharing session state across web servers.
50
AWS SDK for Java Developer Guide
Managing Tomcat Session State with DynamoDB
1. The AwsAccessKey and AwsSecretKey attributes of the Manager element explicitly provide
credentials.
2. The AwsCredentialsFile attribute on the Manager element specifies a properties file from which
to load credentials.
For more information about customizing Elastic Beanstalk environments, see AWS Elastic Beanstalk
Environment Configuration in the AWS Elastic Beanstalk Developer Guide.
If you deploy to Elastic Beanstalk with the AWS Toolkit for Eclipse, you can have the toolkit set up
the session manager for you; use the New AWS Java Web Project wizard and choose DynamoDB for
session management. The AWS Toolkit for Eclipse configures the required files and puts them in the
.ebextensions directory in the WebContent directory of your project. If you have problems finding
this directory, be sure you aren't hiding files that begin with a period.
When your application starts, it looks for a DynamoDB table named, by default, Tomcat_SessionState.
The table should have a string hash key named "sessionId" (case-sensitive), no range key, and the desired
values for ReadCapacityUnits and WriteCapacityUnits.
We recommend that you create this table before running your application for the first time. If you don't
create the table, however, the extension creates it during initialization. See the context.xml options
in the next section for a list of attributes that configure how the session-state table is created when it
doesn't exist.
Note
For information about working with DynamoDB tables and provisioned throughput, see the
Amazon DynamoDB Developer Guide.
51
AWS SDK for Java Developer Guide
Amazon EC2 Examples
After the application is configured and the table is created, you can use sessions with any other session
provider.
Troubleshooting
If you encounter issues with the session manager, the first place to look is in catalina.out. If you have
access to the Tomcat installation, you can go directly to this log file and look for any error messages
from the session manager. If you're using Elastic Beanstalk, you can view the environment logs with the
AWS Management Console or the AWS Toolkit for Eclipse.
Limitations
The session manager doesn't support session locking. Therefore, applications that use many concurrent
AJAX calls to manipulate session data may not be appropriate for use with the session manager, due to
race conditions on session data writes and saves back to the data store.
Topics
• Tutorial: Starting an EC2 Instance (p. 53)
• Using IAM Roles to Grant Access to AWS Resources on Amazon EC2 (p. 56)
• Tutorial: Amazon EC2 Spot Instances (p. 60)
• Tutorial: Advanced Amazon EC2 Spot Request Management (p. 68)
52
AWS SDK for Java Developer Guide
Tutorial: Starting an EC2 Instance
Topics
• Prerequisites (p. 4)
• Create an Amazon EC2 Security Group (p. 53)
• Create a Key Pair (p. 54)
• Run an Amazon EC2 Instance (p. 55)
Prerequisites
Before you begin, be sure that you have created an AWS account and that you have set up your AWS
credentials. For more information, see Getting Started (p. 3).
You create a security group for use in either EC2-Classic or EC2-VPC. For more information about EC2-
Classic and EC2-VPC, see Supported Platforms in the Amazon EC2 User Guide for Linux Instances.
For more information about creating a security group using the Amazon EC2 console, see Amazon EC2
Security Groups in the Amazon EC2 User Guide for Linux Instances.
1. Create and initialize a CreateSecurityGroupRequest instance. Use the withGroupName method to set
the security group name, and the withDescription method to set the security group description, as
follows:
The security group name must be unique within the AWS region in which you initialize your Amazon
EC2 client. You must use US-ASCII characters for the security group name and description.
2. Pass the request object as a parameter to the createSecurityGroup method. The method returns a
CreateSecurityGroupResult object, as follows:
CreateSecurityGroupResult createSecurityGroupResult =
amazonEC2Client.createSecurityGroup(csgr);
53
AWS SDK for Java Developer Guide
Tutorial: Starting an EC2 Instance
If you attempt to create a security group with the same name as an existing security group,
createSecurityGroup throws an exception.
By default, a new security group does not allow any inbound traffic to your Amazon EC2 instance. To
allow inbound traffic, you must explicitly authorize security group ingress. You can authorize ingress for
individual IP addresses, for a range of IP addresses, for a specific protocol, and for TCP/UDP ports.
1. Create and initialize an IpPermission instance. Use the withIpv4Ranges method to set the range of IP
addresses to authorize ingress for, and use the withIpProtocol method to set the IP protocol. Use the
withFromPort and withToPort methods to specify range of ports to authorize ingress for, as follows:
IpPermission ipPermission =
new IpPermission();
All the conditions that you specify in the IpPermission object must be met in order for ingress to
be allowed.
Specify the IP address using CIDR notation. If you specify the protocol as TCP/UDP, you must provide
a source port and a destination port. You can authorize ports only if you specify TCP or UDP.
2. Create and initialize an AuthorizeSecurityGroupIngressRequest instance. Use the withGroupName
method to specify the security group name, and pass the IpPermission object you initialized
earlier to the withIpPermissions method, as follows:
AuthorizeSecurityGroupIngressRequest authorizeSecurityGroupIngressRequest =
new AuthorizeSecurityGroupIngressRequest();
authorizeSecurityGroupIngressRequest.withGroupName("JavaSecurityGroup")
.withIpPermissions(ipPermission);
amazonEC2Client.authorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest);
54
AWS SDK for Java Developer Guide
Tutorial: Starting an EC2 Instance
used when launching other instances. For more information, see Amazon EC2 Key Pairs in the Amazon
EC2 User Guide for Linux Instances.
1. Create and initialize a CreateKeyPairRequest instance. Use the withKeyName method to set the key
pair name, as follows:
createKeyPairRequest.withKeyName(keyName);
Important
Key pair names must be unique. If you attempt to create a key pair with the same key name
as an existing key pair, you'll get an exception.
2. Pass the request object to the createKeyPair method. The method returns a CreateKeyPairResult
instance, as follows:
CreateKeyPairResult createKeyPairResult =
amazonEC2Client.createKeyPair(createKeyPairRequest);
3. Call the result object's getKeyPair method to obtain a KeyPair object. Call the KeyPair object's
getKeyMaterial method to obtain the unencrypted PEM-encoded private key, as follows:
keyPair = createKeyPairResult.getKeyPair();
1. Create and initialize a RunInstancesRequest instance. Make sure that the AMI, key pair, and security
group that you specify exist in the region that you specified when you created the client object.
RunInstancesRequest runInstancesRequest =
new RunInstancesRequest();
runInstancesRequest.withImageId("ami-4b814f22")
.withInstanceType("m1.small")
.withMinCount(1)
.withMaxCount(1)
.withKeyName("my-key-pair")
.withSecurityGroups("my-security-group");
withImageId
The ID of the AMI. For a list of public AMIs provided by Amazon, see Amazon Machine Images.
55
AWS SDK for Java Developer Guide
Using IAM Roles to Grant Access
to AWS Resources on Amazon EC2
withInstanceType
An instance type that is compatible with the specified AMI. For more information, see Instance
Types in the Amazon EC2 User Guide for Linux Instances.
withMinCount
The minimum number of EC2 instances to launch. If this is more instances than Amazon EC2 can
launch in the target Availability Zone, Amazon EC2 launches no instances.
withMaxCount
The maximum number of EC2 instances to launch. If this is more instances than Amazon EC2
can launch in the target Availability Zone, Amazon EC2 launches the largest possible number of
instances above MinCount. You can launch between 1 and the maximum number of instances
you're allowed for the instance type. For more information, see How many instances can I run in
Amazon EC2 in the Amazon EC2 General FAQ.
withKeyName
The name of the EC2 key pair. If you launch an instance without specifying a key pair, you can't
connect to it. For more information, see Create a Key Pair (p. 54).
withSecurityGroups
One or more security groups. For more information, see Create an Amazon EC2 Security
Group (p. 53).
2. Launch the instances by passing the request object to the runInstances method. The method returns
a RunInstancesResult object, as follows:
After your instance is running, you can connect to it using your key pair. For more information, see
Connect to Your Linux Instance. in the Amazon EC2 User Guide for Linux Instances.
This topic provides information about how to use IAM roles with Java SDK applications running on
Amazon EC2. For more information about IAM instances, see IAM Roles for Amazon EC2 in the Amazon
EC2 User Guide for Linux Instances.
56
AWS SDK for Java Developer Guide
Using IAM Roles to Grant Access
to AWS Resources on Amazon EC2
The final step in the default provider chain is available only when running your application on an
Amazon EC2 instance, but provides the greatest ease of use and best security when working with
Amazon EC2 instances. You can also pass an InstanceProfileCredentialsProvider instance directly to
the client constructor to get instance profile credentials without proceeding through the entire default
provider chain.
For example:
AmazonS3 s3 = AmazonS3ClientBuilder.standard()
.withCredentials(new InstanceProfileCredentialsProvider(false))
.build();
When using this approach, the SDK retrieves temporary AWS credentials that have the same
permissions as those associated with the IAM role associated with the Amazon EC2 instance
in its instance profile. Although these credentials are temporary and would eventually expire,
InstanceProfileCredentialsProvider periodically refreshes them for you so that the obtained
credentials continue to allow access to AWS.
Important
The automatic credentials refresh happens only when you use the default client constructor,
which creates its own InstanceProfileCredentialsProvider as part of the default
provider chain, or when you pass an InstanceProfileCredentialsProvider instance
directly to the client constructor. If you use another method to obtain or pass instance profile
credentials, you are responsible for checking for and refreshing expired credentials.
If the client constructor can't find credentials using the credentials provider chain, it will throw an
AmazonClientException.
• To launch an Amazon EC2 instance using the console, follow the directions in Getting Started with
Amazon EC2 Linux Instances in the Amazon EC2 User Guide for Linux Instances.
57
AWS SDK for Java Developer Guide
Using IAM Roles to Grant Access
to AWS Resources on Amazon EC2
When you reach the Review Instance Launch page, select Edit instance details. In IAM role, choose
the IAM role that you created previously. Complete the procedure as directed.
Note
You'll need to create or use an existing security group and key pair to connect to the instance.
• To launch an Amazon EC2 instance with an IAM role using the AWS SDK for Java, see Run an Amazon
EC2 Instance (p. 55).
Next, copy the AWS SDK for Java libraries into your newly-created directory. If you downloaded the AWS
SDK for Java to your ~/Downloads directory, you can copy them using the following commands:
cp -r ~/Downloads/aws-java-sdk-{1.7.5}/lib .
cp -r ~/Downloads/aws-java-sdk-{1.7.5}/third-party .
Open a new file, call it GetS3Object.java, and add the following code:
import java.io.*;
import com.amazonaws.auth.*;
import com.amazonaws.services.s3.*;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
try {
System.out.println("Downloading an object");
S3Object s3object = s3Client.getObject(
new GetObjectRequest(bucketName, key));
displayTextInputStream(s3object.getObjectContent());
}
catch(AmazonServiceException ase) {
System.err.println("Exception was thrown by the service");
}
catch(AmazonClientException ace) {
System.err.println("Exception was thrown by the client");
}
}
58
AWS SDK for Java Developer Guide
Using IAM Roles to Grant Access
to AWS Resources on Amazon EC2
Open a new file, call it build.xml, and add the following lines:
<target name="build">
<javac debug="true"
includeantruntime="false"
srcdir="."
destdir="."
classpathref="aws.java.sdk.classpath"/>
</target>
Build and run the modified program. Note that there are no credentials are stored in the
program. Therefore, unless you have your AWS credentials specified already, the code will throw
AmazonServiceException. For example:
$ ant
Buildfile: /path/to/my/GetS3ObjectApp/build.xml
build:
[javac] Compiling 1 source file to /path/to/my/GetS3ObjectApp
run:
[java] Downloading an object
[java] AmazonServiceException
BUILD SUCCESSFUL
Note
Depending on the Linux distribution that you used, the user name might be "ec2-
user", "root", or "ubuntu". To get the public DNS name of your instance, open the
59
AWS SDK for Java Developer Guide
Tutorial: Amazon EC2 Spot Instances
EC2 console and look for the Public DNS value in the Description tab (for example,
ec2-198-51-100-1.compute-1.amazonaws.com).
If ant is not available on your instance, install it using the following command:
ant run
The program will write the contents of your Amazon S3 object to your command window.
Spot Instances can significantly lower your Amazon EC2 costs for batch processing, scientific research,
image processing, video encoding, data and web crawling, financial analysis, and testing. Additionally,
Spot Instances give you access to large amounts of additional capacity in situations where the need for
that capacity is not urgent.
To use Spot Instances, place a Spot Instance request specifying the maximum price you are willing to pay
per instance hour; this is your bid. If your bid exceeds the current Spot Price, your request is fulfilled and
60
AWS SDK for Java Developer Guide
Tutorial: Amazon EC2 Spot Instances
your instances will run until either you choose to terminate them or the Spot Price increases above your
bid (whichever is sooner).
• You will often pay less per hour than your bid. Amazon EC2 adjusts the Spot Price periodically as
requests come in and available supply changes. Everyone pays the same Spot Price for that period
regardless of whether their bid was higher. Therefore, you might pay less than your bid, but you will
never pay more than your bid.
• If you're running Spot Instances and your bid no longer meets or exceeds the current Spot Price, your
instances will be terminated. This means that you will want to make sure that your workloads and
applications are flexible enough to take advantage of this opportunistic capacity.
Spot Instances perform exactly like other Amazon EC2 instances while running, and like other Amazon
EC2 instances, Spot Instances can be terminated when you no longer need them. If you terminate
your instance, you pay for any partial hour used (as you would for On-Demand or Reserved Instances).
However, if the Spot Price goes above your bid and your instance is terminated by Amazon EC2, you will
not be charged for any partial hour of usage.
This tutorial shows how to use AWS SDK for Java to do the following.
Prerequisites
To use this tutorial you must have the AWS SDK for Java installed, as well as having met its basic
installation prerequisites. See Set up the AWS SDK for Java (p. 4) for more information.
Note
We recommend that you use the credentials of an IAM user to provide these values. For more
information, see Sign Up for AWS and Create an IAM User (p. 3).
Now that you have configured your settings, you can get started using the code in the example.
61
AWS SDK for Java Developer Guide
Tutorial: Amazon EC2 Spot Instances
To enable access to the group, we create an ipPermission object with the IP address range set to the
CIDR representation of the subnet for the local computer; the "/10" suffix on the IP address indicates the
subnet for the specified IP address. We also configure the ipPermission object with the TCP protocol
and port 22 (SSH). The final step is to call ec2.authorizeSecurityGroupIngress with the name of
our security group and the ipPermission object.
// Get the IP of the current host, so that we can limit the Security
// Group by default to the ip range associated with your subnet.
try {
InetAddress addr = InetAddress.getLocalHost();
// Get IP Address
ipAddr = addr.getHostAddress()+"/10";
} catch (UnknownHostException e) {
}
try {
// Authorize the ports to the used.
AuthorizeSecurityGroupIngressRequest ingressRequest =
new AuthorizeSecurityGroupIngressRequest("GettingStartedGroup",ipPermissions);
ec2.authorizeSecurityGroupIngress(ingressRequest);
} catch (AmazonServiceException ase) {
// Ignore because this likely means the zone has
// already been authorized.
System.out.println(ase.getMessage());
}
You can view this entire code sample in the CreateSecurityGroupApp.java code sample. Note you
only need to run this application once to create a new security group.
62
AWS SDK for Java Developer Guide
Tutorial: Amazon EC2 Spot Instances
You can also create the security group using the AWS Toolkit for Eclipse. See Managing Security Groups
from AWS Explorer for more information.
There are several instance types to choose from; go to Amazon EC2 Instance Types for a complete list.
For this tutorial, we will use t1.micro, the cheapest instance type available. Next, we will determine
the type of AMI we would like to use. We'll use ami-8c1fece5, the most up-to-date Amazon Linux
AMI available when we wrote this tutorial. The latest AMI may change over time, but you can always
determine the latest version AMI by following these steps:
1. Log into the AWS Management Console, click the EC2 tab, and, from the EC2 Console Dashboard,
attempt to launch an instance.
There are many ways to approach bidding for Spot instances; to get a broad overview of the various
approaches you should view the Bidding for Spot Instances video. However, to get started, we'll describe
three common strategies: bid to ensure cost is less than on-demand pricing; bid based on the value of
the resulting computation; bid so as to acquire computing capacity as quickly as possible.
63
AWS SDK for Java Developer Guide
Tutorial: Amazon EC2 Spot Instances
• Reduce Cost below On-Demand You have a batch processing job that will take a number of hours or
days to run. However, you are flexible with respect to when it starts and when it completes. You want
to see if you can complete it for less cost than with On-Demand Instances. You examine the Spot Price
history for instance types using either the AWS Management Console or the Amazon EC2 API. For
more information, go to Viewing Spot Price History. After you've analyzed the price history for your
desired instance type in a given Availability Zone, you have two alternative approaches for your bid:
• You could bid at the upper end of the range of Spot Prices (which are still below the On-Demand
price), anticipating that your one-time Spot request would most likely be fulfilled and run for
enough consecutive compute time to complete the job.
• Or, you could bid at the lower end of the price range, and plan to combine many instances launched
over time through a persistent request. The instances would run long enough--in aggregate--to
complete the job at an even lower total cost. (We will explain how to automate this task later in this
tutorial.)
• Pay No More than the Value of the Result You have a data processing job to run. You understand the
value of the job's results well enough to know how much they are worth in terms of computing costs.
After you've analyzed the Spot Price history for your instance type, you choose a bid price at which the
cost of the computing time is no more than the value of the job's results. You create a persistent bid
and allow it to run intermittently as the Spot Price fluctuates at or below your bid.
• Acquire Computing Capacity Quickly You have an unanticipated, short-term need for additional
capacity that is not available through On-Demand Instances. After you've analyzed the Spot Price
history for your instance type, you bid above the highest historical price to provide a high likelihood
that your request will be fulfilled quickly and continue computing until it completes.
After you choose your bid price, you are ready to request a Spot Instance. For the purposes of this
tutorial, we will bid the On-Demand price ($0.03) to maximize the chances that the bid will be fulfilled.
You can determine the types of available instances and the On-Demand prices for instances by going
to Amazon EC2 Pricing page. To request a Spot Instance, you simply need to build your request with
the parameters you chose earlier. We start by creating a RequestSpotInstanceRequest object. The
request object requires the number of instances you want to start and the bid price. Additionally, you
need to set the LaunchSpecification for the request, which includes the instance type, AMI ID, and
security group you want to use. Once the request is populated, you call the requestSpotInstances
method on the AmazonEC2Client object. The following example shows how to request a Spot Instance.
64
AWS SDK for Java Developer Guide
Tutorial: Amazon EC2 Spot Instances
Running this code will launch a new Spot Instance Request. There are other options you can use to
configure your Spot Requests. To learn more, please visit Tutorial: Advanced Amazon EC2 Spot Request
Management (p. 68) or the RequestSpotInstances class in the AWS SDK for Java API Reference.
Note
You will be charged for any Spot Instances that are actually launched, so make sure that you
cancel any requests and terminate any instances you launch to reduce any associated fees.
The request ID created in Step 2 is embedded in the response to our requestSpotInstances request.
The following example code shows how to gather request IDs from the requestSpotInstances
response and use them to populate an ArrayList.
// Add all of the request ids to the hashset, so we can determine when they hit the
// active state.
for (SpotInstanceRequest requestResponse : requestResponses) {
System.out.println("Created Spot Request:
"+requestResponse.getSpotInstanceRequestId());
spotInstanceRequestIds.add(requestResponse.getSpotInstanceRequestId());
}
To monitor your request ID, call the describeSpotInstanceRequests method to determine the state
of the request. Then loop until the request is not in the "open" state. Note that we monitor for a state
of not "open", rather a state of, say, "active", because the request can go straight to "closed" if there is
a problem with your request arguments. The following code example provides the details of how to
accomplish this task.
do {
65
AWS SDK for Java Developer Guide
Tutorial: Amazon EC2 Spot Instances
try {
// Retrieve all of the requests we want to monitor.
DescribeSpotInstanceRequestsResult describeResult =
ec2.describeSpotInstanceRequests(describeRequest);
List<SpotInstanceRequest> describeResponses =
describeResult.getSpotInstanceRequests();
try {
// Sleep for 60 seconds.
Thread.sleep(60*1000);
} catch (Exception e) {
// Do nothing because it woke up early.
}
} while (anyOpen);
After running this code, your Spot Instance Request will have completed or will have failed with an error
that will be output to the screen. In either case, we can proceed to the next step to clean up any active
requests and terminate any running instances.
try {
// Cancel requests.
CancelSpotInstanceRequestsRequest cancelRequest =
new CancelSpotInstanceRequestsRequest(spotInstanceRequestIds);
66
AWS SDK for Java Developer Guide
Tutorial: Amazon EC2 Spot Instances
ec2.cancelSpotInstanceRequests(cancelRequest);
} catch (AmazonServiceException e) {
// Write out any exceptions that may have occurred.
System.out.println("Error cancelling instances");
System.out.println("Caught Exception: " + e.getMessage());
System.out.println("Reponse Status Code: " + e.getStatusCode());
System.out.println("Error Code: " + e.getErrorCode());
System.out.println("Request ID: " + e.getRequestId());
}
To terminate any outstanding instances, you will need the instance ID associated with the request that
started them. The following code example takes our original code for monitoring the instances and adds
an ArrayList in which we store the instance ID associated with the describeInstance response.
// Create a variable that will track whether there are any requests
// still in the open state.
boolean anyOpen;
// Initialize variables.
ArrayList<String> instanceIds = new ArrayList<String>();
do {
// Create the describeRequest with all of the request ids to
// monitor (e.g. that we started).
DescribeSpotInstanceRequestsRequest describeRequest = new
DescribeSpotInstanceRequestsRequest();
describeRequest.setSpotInstanceRequestIds(spotInstanceRequestIds);
try {
// Retrieve all of the requests we want to monitor.
DescribeSpotInstanceRequestsResult describeResult =
ec2.describeSpotInstanceRequests(describeRequest);
List<SpotInstanceRequest> describeResponses =
describeResult.getSpotInstanceRequests();
try {
// Sleep for 60 seconds.
Thread.sleep(60*1000);
} catch (Exception e) {
67
AWS SDK for Java Developer Guide
Tutorial: Advanced Amazon EC2 Spot Request Management
Using the instance IDs, stored in the ArrayList, terminate any running instances using the following
code snippet.
try {
// Terminate instances.
TerminateInstancesRequest terminateRequest = new
TerminateInstancesRequest(instanceIds);
ec2.terminateInstances(terminateRequest);
} catch (AmazonServiceException e) {
// Write out any exceptions that may have occurred.
System.out.println("Error terminating instances");
System.out.println("Caught Exception: " + e.getMessage());
System.out.println("Reponse Status Code: " + e.getStatusCode());
System.out.println("Error Code: " + e.getErrorCode());
System.out.println("Request ID: " + e.getRequestId());
}
We also create a GettingStartedApp class, which has a main method where we perform the high level
function calls. Specifically, we initialize the Requests object described previously. We submit the Spot
Instance request. Then we wait for the Spot request to reach the "Active" state. Finally, we clean up the
requests and instances.
The complete source code for this example can be viewed or downloaded at GitHub.
Congratulations! You have just completed the getting started tutorial for developing Spot Instance
software with the AWS SDK for Java.
Next Steps
Proceed with Tutorial: Advanced Amazon EC2 Spot Request Management (p. 68).
Prerequisites
To use this tutorial you must have the AWS SDK for Java installed, as well as having met its basic
installation prerequisites. See Set up the AWS SDK for Java (p. 4) for more information.
68
AWS SDK for Java Developer Guide
Tutorial: Advanced Amazon EC2 Spot Request Management
Note
We recommend that you use the credentials of an IAM user to provide these values. For more
information, see Sign Up for AWS and Create an IAM User (p. 3).
Now that you have configured your settings, you can get started using the code in the example.
To enable access to the group, we create an ipPermission object with the IP address range set to the
CIDR representation of the subnet for the local computer; the "/10" suffix on the IP address indicates the
subnet for the specified IP address. We also configure the ipPermission object with the TCP protocol
and port 22 (SSH). The final step is to call ec2.authorizeSecurityGroupIngress with the name of
our security group and the ipPermission object.
(The following code is the same as what we used in the first tutorial.)
// Get the IP of the current host, so that we can limit the Security Group
69
AWS SDK for Java Developer Guide
Tutorial: Advanced Amazon EC2 Spot Request Management
try {
// Authorize the ports to the used.
AuthorizeSecurityGroupIngressRequest ingressRequest =
new AuthorizeSecurityGroupIngressRequest(
"GettingStartedGroup",ipPermissions);
ec2.authorizeSecurityGroupIngress(ingressRequest);
}
catch (AmazonServiceException ase) {
// Ignore because this likely means the zone has already
// been authorized.
System.out.println(ase.getMessage());
}
You can view this entire code sample in the advanced.CreateSecurityGroupApp.java code sample.
Note you only need to run this application once to create a new security group.
Note
You can also create the security group using the AWS Toolkit for Eclipse. See Managing Security
Groups from AWS Explorer in the AWS Toolkit for Eclipse User Guide for more information.
(The following code is the same as what we used in the first tutorial.)
70
AWS SDK for Java Developer Guide
Tutorial: Advanced Amazon EC2 Spot Request Management
71
AWS SDK for Java Developer Guide
Tutorial: Advanced Amazon EC2 Spot Request Management
// Set the valid end time to be two minutes and two hours from now.
cal.add(Calendar.HOUR, 2);
requestRequest.setValidUntil(cal.getTime());
72
AWS SDK for Java Developer Guide
Tutorial: Advanced Amazon EC2 Spot Request Management
If you want to ensure your Spot instances are all launched and terminated together, then you have
the option to leverage a launch group. A launch group is a label that groups a set of bids together. All
instances in a launch group are started and terminated together. Note, if instances in a launch group
have already been fulfilled, there is no guarantee that new instances launched with the same launch
group will also be fulfilled. An example of how to set a Launch Group is shown in the following code
example.
If you want to ensure that all instances within a request are launched in the same Availability Zone, and
you don't care which one, you can leverage Availability Zone groups. An Availability Zone group is a
label that groups a set of instances together in the same Availability Zone. All instances that share an
Availability Zone group and are fulfilled at the same time will start in the same Availability Zone. An
example of how to set an Availability Zone group follows.
73
AWS SDK for Java Developer Guide
Tutorial: Advanced Amazon EC2 Spot Request Management
requestRequest.setSpotPrice("0.03");
requestRequest.setInstanceCount(Integer.valueOf(5));
You can specify an Availability Zone that you want for your Spot Instances. The following code example
shows you how to set an Availability Zone.
74
AWS SDK for Java Developer Guide
Tutorial: Advanced Amazon EC2 Spot Request Management
Lastly, you can specify a placement group if you are using High Performance Computing (HPC) Spot
instances, such as cluster compute instances or cluster GPU instances. Placement groups provide you
with lower latency and high-bandwidth connectivity between the instances. An example of how to set a
placement group follows.
// Set up the placement group to use with whatever name you desire.
// For this demo we will just use "ADVANCED-DEMO-PLACEMENT-GROUP".
SpotPlacement placement = new SpotPlacement();
placement.setGroupName("ADVANCED-DEMO-PLACEMENT-GROUP");
launchSpecification.setPlacement(placement);
All of the parameters shown in this section are optional. It is also important to realize that most of
these parameters—with the exception of whether your bid is one-time or persistent—can reduce the
likelihood of bid fulfillment. So, it is important to leverage these options only if you need them. All
of the preceding code examples are combined into one long code sample, which can be found in the
com.amazonaws.codesamples.advanced.InlineGettingStartedCodeSampleApp.java class.
In the added code, we create a BlockDeviceMapping object and set its associated Elastic Block Storage
(EBS) to an EBS object that we've configured to not be deleted if the Spot Instance is terminated.
We then add this BlockDeviceMapping to the ArrayList of mappings that we include in the launch
specification.
75
AWS SDK for Java Developer Guide
Tutorial: Advanced Amazon EC2 Spot Request Management
Assuming you wanted to re-attach this volume to your instance on startup, you can also use the block
device mapping settings. Alternatively, if you attached a non-root partition, you can specify the Amazon
EBS volumes you want to attach to your Spot instance after it resumes. You do this simply by specifying
a snapshot ID in your EbsBlockDevice and alternative device name in your BlockDeviceMapping
objects. By leveraging block device mappings, it can be easier to bootstrap your instance.
76
AWS SDK for Java Developer Guide
Tutorial: Advanced Amazon EC2 Spot Request Management
Using the root partition to checkpoint your critical data is a great way to manage the potential for
interruption of your instances. For more methods on managing the potential of interruption, please visit
the Managing Interruption video.
Tagging requests
To add tags to your spot requests, you need to tag them after they have been requested. The return
value from requestSpotInstances() provides you with a RequestSpotInstancesResult object that you
can use to get the spot request IDs for tagging:
// Add the request ids to the hashset, so we can determine when they hit the
// active state.
for (SpotInstanceRequest requestResponse : requestResponses) {
System.out.println("Created Spot Request:
"+requestResponse.getSpotInstanceRequestId());
spotInstanceRequestIds.add(requestResponse.getSpotInstanceRequestId());
}
Once you have the IDs, you can tag the requests by adding their IDs to a CreateTagsRequest and calling
the EC2 client's createTags() method:
Tagging instances
Similarly to spot requests themselves, you can only tag an instance once it has been created, which will
happen once the spot request has been met (it is no longer in the open state).
77
AWS SDK for Java Developer Guide
Tutorial: Advanced Amazon EC2 Spot Request Management
You can check the status of your requests by calling the EC2 client's
describeSpotInstanceRequests() method with a DescribeSpotInstanceRequestsRequest object.
The returned DescribeSpotInstanceRequestsResult object contains a list of SpotInstanceRequest objects
that you can use to query the status of your spot requests and obtain their instance IDs once they are no
longer in the open state.
Once the spot request is no longer open, you can retrieve its instance ID from the
SpotInstanceRequest object by calling its getInstanceId() method.
do {
DescribeSpotInstanceRequestsRequest describeRequest =
new DescribeSpotInstanceRequestsRequest();
describeRequest.setSpotInstanceRequestIds(spotInstanceRequestIds);
try {
// Get the requests to monitor
DescribeSpotInstanceRequestsResult describeResult =
ec2.describeSpotInstanceRequests(describeRequest);
List<SpotInstanceRequest> describeResponses =
describeResult.getSpotInstanceRequests();
try {
Thread.sleep(60*1000); // sleep 60s.
}
catch (Exception e) {
// Do nothing if the thread woke up early.
}
} while (anyOpen);
78
AWS SDK for Java Developer Guide
Tutorial: Advanced Amazon EC2 Spot Request Management
try {
CancelSpotInstanceRequestsRequest cancelRequest = new
CancelSpotInstanceRequestsRequest(spotInstanceRequestIds);
ec2.cancelSpotInstanceRequests(cancelRequest);
} catch (AmazonServiceException e) {
System.out.println("Error cancelling instances");
System.out.println("Caught Exception: " + e.getMessage());
System.out.println("Reponse Status Code: " + e.getStatusCode());
System.out.println("Error Code: " + e.getErrorCode());
System.out.println("Request ID: " + e.getRequestId());
}
try {
TerminateInstancesRequest terminateRequest = new
TerminateInstancesRequest(instanceIds);
ec2.terminateInstances(terminateRequest);
} catch (AmazonServiceException e) {
System.out.println("Error terminating instances");
System.out.println("Caught Exception: " + e.getMessage());
System.out.println("Reponse Status Code: " + e.getStatusCode());
System.out.println("Error Code: " + e.getErrorCode());
System.out.println("Request ID: " + e.getRequestId());
}
The complete source code for this example can be viewed or downloaded at GitHub.
Congratulations! You've completed the Advanced Request Features tutorial for developing Spot Instance
software with the AWS SDK for Java.
79
AWS SDK for Java Developer Guide
Managing Amazon EC2 Instances
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.InstanceType;
import com.amazonaws.services.ec2.model.RunInstancesRequest;
import com.amazonaws.services.ec2.model.RunInstancesResult;
Code
Starting an Instance
To start an Amazon EC2 instance, call the AmazonEC2Client's startInstances method, providing it
with a StartInstancesRequest containing the ID of the instance to start.
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.StartInstancesRequest;
Code
ec2.startInstances(request);
Stopping an Instance
To stop an Amazon EC2 instance, call the AmazonEC2Client's stopInstances method, providing it with
a StopInstancesRequest containing the ID of the instance to stop.
80
AWS SDK for Java Developer Guide
Managing Amazon EC2 Instances
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.StopInstancesRequest;
Code
ec2.stopInstances(request);
Rebooting an Instance
To reboot an Amazon EC2 instance, call the AmazonEC2Client's rebootInstances method, providing it
with a RebootInstancesRequest containing the ID of the instance to reboot.
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.RebootInstancesRequest;
import com.amazonaws.services.ec2.model.RebootInstancesResult;
Code
Describing Instances
To list your instances, create a DescribeInstancesRequest and call the AmazonEC2Client's
describeInstances method. It will return a DescribeInstancesResult object that you can use to list the
Amazon EC2 instances for your account and region.
Instances are grouped by reservation. Each reservation corresponds to the call to startInstances that
launched the instance. To list your instances, you must first call the DescribeInstancesResult class'
getReservations' method, and then call :methodname:`getInstances on each returned
Reservation object.
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
81
AWS SDK for Java Developer Guide
Managing Amazon EC2 Instances
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.Reservation;
Code
while(!done) {
DescribeInstancesRequest request = new DescribeInstancesRequest();
DescribeInstancesResult response = ec2.describeInstances(request);
request.setNextToken(response.getNextToken());
if(response.getNextToken() == null) {
done = true;
}
}
Results are paged; you can get further results by passing the value returned from the result object's
getNextToken method to your original request object's setNextToken method, then using the same
request object in your next call to describeInstances.
Monitoring an Instance
You can monitor various aspects of your Amazon EC2 instances, such as CPU and network utilization,
available memory, and disk space remaining. To learn more about instance monitoring, see Monitoring
Amazon EC2 in the Amazon EC2 User Guide for Linux Instances.
To start monitoring an instance, you must create a MonitorInstancesRequest with the ID of the instance
to monitor, and pass it to the AmazonEC2Client's monitorInstances method.
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.MonitorInstancesRequest;
Code
82
AWS SDK for Java Developer Guide
Using Elastic IP Addresses in Amazon EC2
ec2.monitorInstances(request);
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.UnmonitorInstancesRequest;
Code
ec2.unmonitorInstances(request);
More Information
• RunInstances in the Amazon EC2 API Reference
• DescribeInstances in the Amazon EC2 API Reference
• StartInstances in the Amazon EC2 API Reference
• StopInstances in the Amazon EC2 API Reference
• RebootInstances in the Amazon EC2 API Reference
• DescribeInstances in the Amazon EC2 API Reference
• MonitorInstances in the Amazon EC2 API Reference
• UnmonitorInstances in the Amazon EC2 API Reference
The returned AllocateAddressResult contains an allocation ID that you can use to associate the address
with an instance, by passing the allocation ID and instance ID in a AssociateAddressRequest to the
AmazonEC2Client's associateAddress method.
83
AWS SDK for Java Developer Guide
Using Elastic IP Addresses in Amazon EC2
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.AllocateAddressRequest;
import com.amazonaws.services.ec2.model.AllocateAddressResult;
import com.amazonaws.services.ec2.model.AssociateAddressRequest;
import com.amazonaws.services.ec2.model.AssociateAddressResult;
import com.amazonaws.services.ec2.model.DomainType;
Code
AllocateAddressResult allocate_response =
ec2.allocateAddress(allocate_request);
AssociateAddressRequest associate_request =
new AssociateAddressRequest()
.withInstanceId(instance_id)
.withAllocationId(allocation_id);
AssociateAddressResult associate_response =
ec2.associateAddress(associate_request);
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.Address;
import com.amazonaws.services.ec2.model.DescribeAddressesResult;
Code
84
AWS SDK for Java Developer Guide
Using Regions and Availability Zones
address.getNetworkInterfaceId());
}
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.ReleaseAddressRequest;
import com.amazonaws.services.ec2.model.ReleaseAddressResult;
Code
After you release an Elastic IP address, it is released to the AWS IP address pool and might be unavailable
to you afterward. Be sure to update your DNS records and any servers or devices that communicate
with the address. If you attempt to release an Elastic IP address that you already released, you'll get an
AuthFailure error if the address is already allocated to another AWS account.
If you are using EC2-Classic or a default VPC, then releasing an Elastic IP address automatically
disassociates it from any instance that it's associated with. To disassociate an Elastic IP address without
releasing it, use the AmazonEC2Client's disassociateAddress method.
If you are using a non-default VPC, you must use disassociateAddress to disassociate the Elastic IP
address before you try to release it. Otherwise, Amazon EC2 returns an error (InvalidIPAddress.InUse).
More Information
• Elastic IP Addresses in the Amazon EC2 User Guide for Linux Instances
• AllocateAddress in the Amazon EC2 API Reference
• DescribeAddresses in the Amazon EC2 API Reference
• ReleaseAddress in the Amazon EC2 API Reference
85
AWS SDK for Java Developer Guide
Using Regions and Availability Zones
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DescribeRegionsResult;
import com.amazonaws.services.ec2.model.Region;
Code
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DescribeRegionsResult;
import com.amazonaws.services.ec2.model.Region;
Code
DescribeAvailabilityZonesResult zones_response =
ec2.describeAvailabilityZones();
More Information
• Regions and Availability Zones in the Amazon EC2 User Guide for Linux Instances
86
AWS SDK for Java Developer Guide
Working with Amazon EC2 Key Pairs
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.CreateKeyPairRequest;
import com.amazonaws.services.ec2.model.CreateKeyPairResult;
Code
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DescribeKeyPairsResult;
import com.amazonaws.services.ec2.model.KeyPairInfo;
Code
87
AWS SDK for Java Developer Guide
Working with Security Groups in Amazon EC2
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
import com.amazonaws.services.ec2.model.DeleteKeyPairResult;
Code
More Information
• Amazon EC2 Key Pairs in the Amazon EC2 User Guide for Linux Instances
• CreateKeyPair in the Amazon EC2 API Reference
• DescribeKeyPairs in the Amazon EC2 API Reference
• DeleteKeyPair in the Amazon EC2 API Reference
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
import com.amazonaws.services.ec2.model.CreateSecurityGroupResult;
Code
88
AWS SDK for Java Developer Guide
Working with Security Groups in Amazon EC2
.withVpcId(vpc_id);
CreateSecurityGroupResult create_response =
ec2.createSecurityGroup(create_request);
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
import com.amazonaws.services.ec2.model.CreateSecurityGroupResult;
Code
AuthorizeSecurityGroupIngressResult auth_response =
ec2.authorizeSecurityGroupIngress(auth_request);
89
AWS SDK for Java Developer Guide
Working with Security Groups in Amazon EC2
access the list of security groups by calling its getSecurityGroups method, which returns a list of
SecurityGroupInfo objects.
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
import com.amazonaws.services.ec2.model.DescribeSecurityGroupsResult;
Code
if (args.length != 1) {
System.out.println(USAGE);
System.exit(1);
}
Imports
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DeleteSecurityGroupRequest;
import com.amazonaws.services.ec2.model.DeleteSecurityGroupResult;
Code
More Information
• Amazon EC2 Security Groups in the Amazon EC2 User Guide for Linux Instances
• Authorizing Inbound Traffic for Your Linux Instances in the Amazon EC2 User Guide for Linux Instances
• CreateSecurityGroup in the Amazon EC2 API Reference
• DescribeSecurityGroups in the Amazon EC2 API Reference
• DeleteSecurityGroup in the Amazon EC2 API Reference
90
AWS SDK for Java Developer Guide
AWS Identity and Access Management (IAM) Examples
AWS Identity and Access Management (IAM) enables you to securely control access to AWS services
and resources for your users. Using IAM, you can create and manage AWS users and groups, and use
permissions to allow and deny their access to AWS resources. For a complete guide to IAM, visit the IAM
User Guide.
Note
The examples include only the code needed to demonstrate each technique. The complete
example code is available on GitHub. From there, you can download a single source file or clone
the repository locally to get all the examples to build and run.
Topics
• Managing IAM Access Keys (p. 91)
• Managing IAM Users (p. 94)
• Using IAM Account Aliases (p. 96)
• Working with IAM Policies (p. 98)
• Working with IAM Server Certificates (p. 101)
CreateAccessKeyRequest has two constructors — one that takes a user name and another with
no parameters. If you use the version that takes no parameters, you must set the user name using the
withUserName setter method before passing it to the createAccessKey method.
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.CreateAccessKeyRequest;
import com.amazonaws.services.identitymanagement.model.CreateAccessKeyResult;
Code
91
AWS SDK for Java Developer Guide
Managing IAM Access Keys
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.AccessKeyMetadata;
import com.amazonaws.services.identitymanagement.model.ListAccessKeysRequest;
import com.amazonaws.services.identitymanagement.model.ListAccessKeysResult;
Code
while (!done) {
request.setMarker(response.getMarker());
if (!response.getIsTruncated()) {
done = true;
}
}
The results of listAccessKeys are paged (with a default maximum of 100 records per call). You can
call getIsTruncated on the returned ListAccessKeysResult object to see if the query returned fewer
results then are available. If so, then call setMarker on the ListAccessKeysRequest and pass it back
to the next invocation of listAccessKeys.
You can then use the returned GetAccessKeyLastUsedResult object to retrieve the key's last used time.
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
92
AWS SDK for Java Developer Guide
Managing IAM Access Keys
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.GetAccessKeyLastUsedRequest;
import com.amazonaws.services.identitymanagement.model.GetAccessKeyLastUsedResult;
Code
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.UpdateAccessKeyRequest;
import com.amazonaws.services.identitymanagement.model.UpdateAccessKeyResult;
Code
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
93
AWS SDK for Java Developer Guide
Managing IAM Users
import com.amazonaws.services.identitymanagement.model.DeleteAccessKeyRequest;
import com.amazonaws.services.identitymanagement.model.DeleteAccessKeyResult;
Code
More Information
• CreateAccessKey in the IAM API Reference
• ListAccessKeys in the IAM API Reference
• GetAccessKeyLastUsed in the IAM API Reference
• UpdateAccessKey in the IAM API Reference
• DeleteAccessKey in the IAM API Reference
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.CreateUserRequest;
import com.amazonaws.services.identitymanagement.model.CreateUserResult;
Code
Listing Users
To list the IAM users for your account, create a new ListUsersRequest and pass it to the
AmazonIdentityManagementClient's listUsers method. You can retrieve the list of users by calling
getUsers on the returned ListUsersResponse object.
94
AWS SDK for Java Developer Guide
Managing IAM Users
The list of users returned by listUsers is paged. You can check to see there are more results to retrieve
by calling the response object's getIsTruncated method. If it returns true, then call the request
object's setMarker() method, passing it the return value of the response object's getMarker()
method.
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.ListUsersRequest;
import com.amazonaws.services.identitymanagement.model.ListUsersResult;
import com.amazonaws.services.identitymanagement.model.User;
Code
while(!done) {
ListUsersResult response = iam.listUsers(request);
request.setMarker(response.getMarker());
if(!response.getIsTruncated()) {
done = true;
}
}
Updating a User
To update a user, call the AmazonIdentityManagementClient object's updateUser method, which takes
a UpdateUserRequest object that you can use to change the user's name or path.
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.UpdateUserRequest;
import com.amazonaws.services.identitymanagement.model.UpdateUserResult;
Code
95
AWS SDK for Java Developer Guide
Using IAM Account Aliases
Deleting a User
To delete a user, call the AmazonIdentityManagementClient's deleteUser request with a
UpdateUserRequest object set with the user name to delete.
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.DeleteConflictException;
import com.amazonaws.services.identitymanagement.model.DeleteUserRequest;
Code
try {
iam.deleteUser(request);
} catch (DeleteConflictException e) {
System.out.println("Unable to delete user. Verify user is not" +
" associated with any resources");
throw e;
}
More Information
• IAM Users in the IAM User Guide
• Managing IAM Users in the IAM User Guide
• CreateUser in the IAM API Reference
• ListUsers in the IAM API Reference
• UpdateUser in the IAM API Reference
• DeleteUser in the IAM API Reference
Imports
96
AWS SDK for Java Developer Guide
Using IAM Account Aliases
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.CreateAccountAliasRequest;
import com.amazonaws.services.identitymanagement.model.CreateAccountAliasResult;
Code
imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.ListAccountAliasesResult;
code
imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.DeleteAccountAliasRequest;
97
AWS SDK for Java Developer Guide
Working with IAM Policies
import com.amazonaws.services.identitymanagement.model.DeleteAccountAliasResult;
Code
More Information
• Your AWS Account ID and Its Alias in the IAM User Guide
• CreateAccountAlias in the IAM API Reference
• ListAccountAliases in the IAM API Reference
• DeleteAccountAlias in the IAM API Reference
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.CreatePolicyRequest;
import com.amazonaws.services.identitymanagement.model.CreatePolicyResult;
Code
IAM policy documents are JSON strings with a well-documented syntax. Here is an example that provides
access to make particular requests to DynamoDB.
98
AWS SDK for Java Developer Guide
Working with IAM Policies
Getting a Policy
To retrieve an existing policy, call the AmazonIdentityManagementClient's getPolicy method,
providing the policy's ARN within a GetPolicyRequest object.
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.GetPolicyRequest;
import com.amazonaws.services.identitymanagement.model.GetPolicyResult;
Code
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.AttachRolePolicyRequest;
import com.amazonaws.services.identitymanagement.model.AttachedPolicy;
Code
99
AWS SDK for Java Developer Guide
Working with IAM Policies
AttachRolePolicyRequest attach_request =
new AttachRolePolicyRequest()
.withRoleName(role_name)
.withPolicyArn(POLICY_ARN);
iam.attachRolePolicy(attach_request);
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.ListAttachedRolePoliciesRequest;
import com.amazonaws.services.identitymanagement.model.ListAttachedRolePoliciesResult;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
Code
ListAttachedRolePoliciesRequest request =
new ListAttachedRolePoliciesRequest()
.withRoleName(role_name);
while(!done) {
ListAttachedRolePoliciesResult response =
iam.listAttachedRolePolicies(request);
matching_policies.addAll(
response.getAttachedPolicies()
.stream()
.filter(p -> p.getPolicyName().equals(role_name))
.collect(Collectors.toList()));
if(!response.getIsTruncated()) {
done = true;
}
request.setMarker(response.getMarker());
100
AWS SDK for Java Developer Guide
Working with IAM Server Certificates
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.DetachRolePolicyRequest;
import com.amazonaws.services.identitymanagement.model.DetachRolePolicyResult;
Code
More Information
• Overview of IAM Policies in the IAM User Guide.
• AWS IAM Policy Reference in the IAM User Guide.
• CreatePolicy in the IAM API Reference
• GetPolicy in the IAM API Reference
• AttachRolePolicy in the IAM API Reference
• ListAttachedRolePolicies in the IAM API Reference
• DetachRolePolicy in the IAM API Reference
We recommend that you use ACM to provision, manage, and deploy your server certificates. With ACM
you can request a certificate, deploy it to your AWS resources, and let ACM handle certificate renewals
for you. Certificates provided by ACM are free. For more information about ACM , see the ACM User
Guide.
101
AWS SDK for Java Developer Guide
Working with IAM Server Certificates
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.GetServerCertificateRequest;
import com.amazonaws.services.identitymanagement.model.GetServerCertificateResult;
Code
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.ListServerCertificatesRequest;
import com.amazonaws.services.identitymanagement.model.ListServerCertificatesResult;
import com.amazonaws.services.identitymanagement.model.ServerCertificateMetadata;
Code
while(!done) {
ListServerCertificatesResult response =
iam.listServerCertificates(request);
for(ServerCertificateMetadata metadata :
response.getServerCertificateMetadataList()) {
System.out.printf("Retrieved server certificate %s",
metadata.getServerCertificateName());
}
102
AWS SDK for Java Developer Guide
Working with IAM Server Certificates
request.setMarker(response.getMarker());
if(!response.getIsTruncated()) {
done = true;
}
}
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.UpdateServerCertificateRequest;
import com.amazonaws.services.identitymanagement.model.UpdateServerCertificateResult;
Code
UpdateServerCertificateRequest request =
new UpdateServerCertificateRequest()
.withServerCertificateName(cur_name)
.withNewServerCertificateName(new_name);
UpdateServerCertificateResult response =
iam.updateServerCertificate(request);
Imports
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.DeleteServerCertificateRequest;
import com.amazonaws.services.identitymanagement.model.DeleteServerCertificateResult;
Code
DeleteServerCertificateRequest request =
new DeleteServerCertificateRequest()
.withServerCertificateName(cert_name);
103
AWS SDK for Java Developer Guide
Amazon S3 Examples
DeleteServerCertificateResult response =
iam.deleteServerCertificate(request);
More Information
• Working with Server Certificates in the IAM User Guide
• GetServerCertificate in the IAM API Reference
• ListServerCertificates in the IAM API Reference
• UpdateServerCertificate in the IAM API Reference
• DeleteServerCertificate in the IAM API Reference
• ACM User Guide
Topics
• Creating, Listing, and Deleting Amazon S3 Buckets (p. 104)
• Performing Operations on Amazon S3 Objects (p. 108)
• Managing Amazon S3 Access Permissions for Buckets and Objects (p. 112)
• Managing Access to Amazon S3 Buckets Using Bucket Policies (p. 114)
• Using TransferManager for Amazon S3 Operations (p. 117)
• Configuring an Amazon S3 Bucket as a Website (p. 124)
• Using Amazon S3 Client-Side Encryption (p. 126)
We recommend that you enable the AbortIncompleteMultipartUpload lifecycle rule on your Amazon S3
buckets.
This rule directs Amazon S3 to abort multipart uploads that don't complete within a specified number of
days after being initiated. When the set time limit is exceeded, Amazon S3 aborts the upload and then
deletes the incomplete upload data.
For more information, see Lifecycle Configuration for a Bucket with Versioning in the Amazon S3 User
Guide.
</admonition>
104
AWS SDK for Java Developer Guide
Creating, Listing, and Deleting Amazon S3 Buckets
Note
These code examples assume that you understand the material in Using the AWS SDK for
Java (p. 11) and have configured default AWS credentials using the information in Set up AWS
Credentials and Region for Development (p. 6).
Create a Bucket
Use the AmazonS3 client's createBucket method. The new Bucket is returned. The createBucket
method will raise an exception if the bucket already exists.
Note
To check whether a bucket already exists before attempting to create one with the same
name, call the doesBucketExist method. It will return true if the bucket exists, and false
otherwise.
Imports
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.AmazonS3Exception;
import com.amazonaws.services.s3.model.Bucket;
import java.util.List;
Code
List Buckets
Use the AmazonS3 client's listBucket method. If successful, a list of Bucket is returned.
Imports
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;
import java.util.List;
Code
105
AWS SDK for Java Developer Guide
Creating, Listing, and Deleting Amazon S3 Buckets
Delete a Bucket
Before you can delete an Amazon S3 bucket, you must ensure that the bucket is empty or an error will
result. If you have a versioned bucket, you must also delete any versioned objects associated with the
bucket.
Note
The complete example includes each of these steps in order, providing a complete solution for
deleting an Amazon S3 bucket and its contents.
Topics
• Remove Objects from an Unversioned Bucket Before Deleting It (p. 106)
• Remove Objects from a Versioned Bucket Before Deleting It (p. 107)
• Delete an Empty Bucket (p. 108)
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import java.util.Iterator;
Code
106
AWS SDK for Java Developer Guide
Creating, Listing, and Deleting Amazon S3 Buckets
Using a pattern similar to the one used when removing objects within a bucket, remove versioned
objects by using the AmazonS3 client's listVersions method to list any versioned objects, and then
deleteVersion to delete each one.
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ListVersionsRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.amazonaws.services.s3.model.S3VersionSummary;
import com.amazonaws.services.s3.model.VersionListing;
import java.util.Iterator;
Code
if (version_listing.isTruncated()) {
version_listing = s3.listNextBatchOfVersions(
version_listing);
107
AWS SDK for Java Developer Guide
Performing Operations on Amazon S3 Objects
} else {
break;
}
}
} catch (AmazonServiceException e) {
System.err.println(e.getErrorMessage());
System.exit(1);
}
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
Code
Topics
• Upload an Object (p. 108)
• List Objects (p. 109)
• Download an Object (p. 109)
• Copy, Move, or Rename Objects (p. 110)
• Delete an Object (p. 111)
• Delete Multiple Objects at Once (p. 111)
Upload an Object
Use the AmazonS3 client's putObject method, supplying a bucket name, key name, and file to upload.
The bucket must exist, or an error will result.
108
AWS SDK for Java Developer Guide
Performing Operations on Amazon S3 Objects
Imports
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.AmazonServiceException;
Code
List Objects
To get a list of objects within a bucket, use the AmazonS3 client's listObjects method, supplying the
name of a bucket.
The listObjects method returns an ObjectListing object that provides information about the objects
in the bucket. To list the object names (keys), use the getObjectSummaries method to get a List of
S3ObjectSummary objects, each of which represents a single object in the bucket. Then call its getKey
method to retrieve the object's name.
Imports
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import java.util.List;
Code
Download an Object
Use the AmazonS3 client's getObject method, passing it the name of a bucket and object to download.
If successful, the method returns an S3Object. The specified bucket and object key must exist, or an error
will result.
You can get the object's contents by calling getObjectContent on the S3Object. This returns an
S3ObjectInputStream that behaves as a standard Java InputStream object.
109
AWS SDK for Java Developer Guide
Performing Operations on Amazon S3 Objects
The following example downloads an object from S3 and saves its contents to a file (using the same
name as the object's key).
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
Code
Imports
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.AmazonServiceException;
Code
110
AWS SDK for Java Developer Guide
Performing Operations on Amazon S3 Objects
} catch (AmazonServiceException e) {
System.err.println(e.getErrorMessage());
System.exit(1);
}
Delete an Object
Use the AmazonS3 client's deleteObject method, passing it the name of a bucket and object to delete.
The specified bucket and object key must exist, or an error will result.
Imports
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.AmazonServiceException;
Code
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.DeleteObjectsRequest;
Code
111
AWS SDK for Java Developer Guide
Managing Amazon S3 Access
Permissions for Buckets and Objects
Imports
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.model.AccessControlList;
import com.amazonaws.services.s3.model.Grant;
import java.util.List;
Code
Imports
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
112
AWS SDK for Java Developer Guide
Managing Amazon S3 Access
Permissions for Buckets and Objects
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.model.AccessControlList;
import com.amazonaws.services.s3.model.EmailAddressGrantee;
import com.amazonaws.services.s3.model.Permission;
Code
Note
You can provide the grantee's unique identifier directly using the Grantee class, or use the
EmailAddressGrantee class to set the grantee by email, as we've done here.
Imports
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.model.AccessControlList;
import com.amazonaws.services.s3.model.Grant;
import java.util.List;
Code
113
AWS SDK for Java Developer Guide
Managing Access to Amazon S3
Buckets Using Bucket Policies
Imports
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.model.AccessControlList;
import com.amazonaws.services.s3.model.EmailAddressGrantee;
import com.amazonaws.services.s3.model.Permission;
Code
Note
You can provide the grantee's unique identifier directly using the Grantee class, or use the
EmailAddressGrantee class to set the grantee by email, as we've done here.
More Information
• GET Bucket acl in the Amazon S3 API Reference
• PUT Bucket acl in the Amazon S3 API Reference
• GET Object acl in the Amazon S3 API Reference
• PUT Object acl in the Amazon S3 API Reference
114
AWS SDK for Java Developer Guide
Managing Access to Amazon S3
Buckets Using Bucket Policies
• Setting the policy directly by using the setBucketPolicy overload that takes a bucket name and
policy text (in JSON format)
Imports
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.AmazonServiceException;
Code
By using the Policy class, you don't have to be concerned about correctly formatting your text string.
To get the JSON policy text from the Policy class, use its toJson method.
Imports
import com.amazonaws.auth.policy.Policy;
import com.amazonaws.auth.policy.Principal;
import com.amazonaws.auth.policy.Resource;
import com.amazonaws.auth.policy.Statement;
import com.amazonaws.auth.policy.actions.S3Actions;
import java.io.IOException;
Code
The Policy class also provides a fromJson method that can attempt to build a policy using a passed-
in JSON string. The method validates it to ensure that the text can be transformed into a valid policy
structure, and will fail with an IllegalArgumentException if the policy text is invalid.
115
AWS SDK for Java Developer Guide
Managing Access to Amazon S3
Buckets Using Bucket Policies
bucket_policy = Policy.fromJson(file_text.toString());
} catch (IllegalArgumentException e) {
System.out.format("Invalid policy text in file: \"%s\"",
policy_file);
System.out.println(e.getMessage());
}
You can use this technique to prevalidate a policy that you read in from a file or other means.
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.BucketPolicy;
Code
If the named bucket doesn't exist, if you don't have access to it, or if it has no bucket policy, an
AmazonServiceException is thrown.
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
Code
116
AWS SDK for Java Developer Guide
Using TransferManager for Amazon S3 Operations
This method succeeds even if the bucket doesn't already have a policy. If you specify a bucket name that
doesn't exist or if you don't have access to the bucket, an AmazonServiceException is thrown.
More Info
• Access Policy Language Overview in the Amazon S3 Developer Guide
• Bucket Policy Examples in the Amazon S3 Developer Guide
We recommend that you enable the AbortIncompleteMultipartUpload lifecycle rule on your Amazon S3
buckets.
This rule directs Amazon S3 to abort multipart uploads that don't complete within a specified number of
days after being initiated. When the set time limit is exceeded, Amazon S3 aborts the upload and then
deletes the incomplete upload data.
For more information, see Lifecycle Configuration for a Bucket with Versioning in the Amazon S3 User
Guide.
</admonition>
Note
These code examples assume that you understand the material in Using the AWS SDK for
Java (p. 11) and have configured default AWS credentials using the information in Set up AWS
Credentials and Region for Development (p. 6).
Topics
• Upload a Single File (p. 117)
• Upload a List of Files (p. 118)
• Upload a Directory (p. 119)
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.transfer.TransferManager;
117
AWS SDK for Java Developer Guide
Using TransferManager for Amazon S3 Operations
import com.amazonaws.services.s3.transfer.Upload;
import java.io.File;
Code
The upload method returns immediately, providing an Upload object to use to check the transfer state
or to wait for it to complete.
See Wait for a Transfer to Complete (p. 121) for information about using waitForCompletion to
successfully complete a transfer before calling TransferManager's shutdownNow method. While waiting
for the transfer to complete, you can poll or listen for updates about its status and progress. See Get
Transfer Status and Progress (p. 122) for more information.
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.MultipleFileUpload;
import java.io.File;
import java.util.ArrayList;
Code
118
AWS SDK for Java Developer Guide
Using TransferManager for Amazon S3 Operations
See Wait for a Transfer to Complete (p. 121) for information about using waitForCompletion to
successfully complete a transfer before calling TransferManager's shutdownNow method. While waiting
for the transfer to complete, you can poll or listen for updates about its status and progress. See Get
Transfer Status and Progress (p. 122) for more information.
The MultipleFileUpload object returned by uploadFileList can be used to query the transfer state
or progress. See Poll the Current Progress of a Transfer (p. 122) and Get Transfer Progress with a
ProgressListener (p. 123) for more information.
You can also use MultipleFileUpload's getSubTransfers method to get the individual
Upload objects for each file being transferred. For more information, see Get the Progress of
Subtransfers (p. 123).
Upload a Directory
You can use TransferManager's uploadDirectory method to upload an entire directory of files, with
the option to copy files in subdirectories recursively. You provide an Amazon S3 bucket name, an S3 key
prefix, a File object representing the local directory to copy, and a boolean value indicating whether you
want to copy subdirectories recursively (true or false).
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.Upload;
import com.amazonaws.services.s3.transfer.MultipleFileUpload;
import java.io.File;
Code
See Wait for a Transfer to Complete (p. 121) for information about using waitForCompletion to
successfully complete a transfer before calling TransferManager's shutdownNow method. While waiting
for the transfer to complete, you can poll or listen for updates about its status and progress. See Get
Transfer Status and Progress (p. 122) for more information.
The MultipleFileUpload object returned by uploadFileList can be used to query the transfer state
or progress. See Poll the Current Progress of a Transfer (p. 122) and Get Transfer Progress with a
ProgressListener (p. 123) for more information.
119
AWS SDK for Java Developer Guide
Using TransferManager for Amazon S3 Operations
You can also use MultipleFileUpload's getSubTransfers method to get the individual
Upload objects for each file being transferred. For more information, see Get the Progress of
Subtransfers (p. 123).
Topics
• Download a Single File (p. 120)
• Download a Directory (p. 120)
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.Download;
import java.io.File;
Code
See Wait for a Transfer to Complete (p. 121) for information about using waitForCompletion to
successfully complete a transfer before calling TransferManager's shutdownNow method. While waiting
for the transfer to complete, you can poll or listen for updates about its status and progress. See Get
Transfer Status and Progress (p. 122) for more information.
Download a Directory
To download a set of files that share a common key prefix (analagous to a directory on a file system)
from Amazon S3, use the TransferManagerdownloadDirectory method. The method takes the
Amazon S3 bucket name containing the objects you want to download, the object prefix shared by all
of the objects, and a File object that represents the directory to download the files into on your local
system. If the named directory doesn't exist yet, it will be created.
120
AWS SDK for Java Developer Guide
Using TransferManager for Amazon S3 Operations
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.MultipleFileDownload;
import java.io.File;
Code
See Wait for a Transfer to Complete (p. 121) for information about using waitForCompletion to
successfully complete a transfer before calling TransferManager's shutdownNow method. While waiting
for the transfer to complete, you can poll or listen for updates about its status and progress. See Get
Transfer Status and Progress (p. 122) for more information.
Copy Objects
To copy an object from one S3 bucket to another, use the TransferManagercopy method.
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.transfer.Copy;
import com.amazonaws.services.s3.transfer.TransferManager;
Code
121
AWS SDK for Java Developer Guide
Using TransferManager for Amazon S3 Operations
try {
xfer.waitForCompletion();
} catch (AmazonServiceException e) {
System.err.println("Amazon service error: " + e.getMessage());
System.exit(1);
} catch (AmazonClientException e) {
System.err.println("Amazon client error: " + e.getMessage());
System.exit(1);
} catch (InterruptedException e) {
System.err.println("Transfer interrupted: " + e.getMessage());
System.exit(1);
}
You get progress of transfers if you poll for events before calling waitForCompletion, implement
a polling mechanism on a separate thread, or receive progress updates asynchronously using a
ProgressListener.
Class Returned by
Copy copy
Download download
MultipleFileDownload downloadDirectory
Upload upload
All of these classes implement the Transfer interface. Transfer provides useful methods to get the
progress of a transfer, pause or resume the transfer, and get the transfer's current or final status.
Topics
• Poll the Current Progress of a Transfer (p. 122)
• Get Transfer Progress with a ProgressListener (p. 123)
• Get the Progress of Subtransfers (p. 123)
Imports
import com.amazonaws.services.s3.transfer.TransferProgress;
Code
122
AWS SDK for Java Developer Guide
Using TransferManager for Amazon S3 Operations
do {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
return;
}
TransferProgress progress = xfer.getProgress();
long so_far = progress.getBytesTransferred();
long total = progress.getTotalBytesToTransfer();
double pct = progress.getPercentTransferred();
} while (xfer.isDone() == false);
A ProgressListener requires only one method, progressChanged, which takes a ProgressEvent object.
You can use the object to get the total bytes of the operation by calling its getBytes method, and the
number of bytes transferred so far by calling getBytesTransferred.
Imports
import com.amazonaws.AmazonServiceException;
import com.amazonaws.event.ProgressEvent;
import com.amazonaws.event.ProgressListener;
import com.amazonaws.services.s3.transfer.Upload;
import java.io.File;
Code
Imports
123
AWS SDK for Java Developer Guide
Configuring an Amazon S3 Bucket as a Website
import com.amazonaws.services.s3.transfer.Upload;
import com.amazonaws.services.s3.transfer.MultipleFileUpload;
import java.util.ArrayList;
import java.util.Collection;
Code
More Info
• Object Keys in the Amazon S3 Developer Guide
Imports
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.BucketWebsiteConfiguration;
import com.amazonaws.AmazonServiceException;
Code
if (index_doc == null) {
website_config = new BucketWebsiteConfiguration();
} else if (error_doc == null) {
website_config = new BucketWebsiteConfiguration(index_doc);
} else {
website_config = new BucketWebsiteConfiguration(index_doc, error_doc);
}
124
AWS SDK for Java Developer Guide
Configuring an Amazon S3 Bucket as a Website
System.out.format(
"Failed to set website configuration for bucket '%s'!\n",
bucket_name);
System.err.println(e.getErrorMessage());
System.exit(1);
}
Note
Setting a website configuration does not modify the access permissions for your bucket. To
make your files visible on the web, you will also need to set a bucket policy that allows public
read access to the files in the bucket. For more information, see Managing Access to Amazon S3
Buckets Using Bucket Policies (p. 114).
Imports
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.BucketWebsiteConfiguration;
import com.amazonaws.AmazonServiceException;
Code
Imports
125
AWS SDK for Java Developer Guide
Using Amazon S3 Client-Side Encryption
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.AmazonServiceException;
Code
More Information
• PUT Bucket website in the Amazon S3 API Reference
• GET Bucket website in the Amazon S3 API Reference
• DELETE Bucket website in the Amazon S3 API Reference
Topics
• Amazon S3 Client-Side Encryption with Client Master Keys (p. 126)
• Amazon S3 Client-Side Encryption with AWS KMS Managed Keys (p. 129)
For information about cryptography support across all AWS SDKs, see AWS SDK Support for Amazon S3
Client-Side Encryption in the Amazon Web Services General Reference.
126
AWS SDK for Java Developer Guide
Using Amazon S3 Client-Side Encryption
You can choose from three encryption modes when enabling client-side Amazon S3 encryption:
encryption-only, authenticated, and strict authenticated. The following sections show how to enable
each type. To learn which algorithms each mode uses, see the CryptoMode definition.
Required Imports
Import the following classes for these examples.
Imports
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.AmazonS3Encryption;
import com.amazonaws.services.s3.AmazonS3EncryptionClientBuilder;
import com.amazonaws.services.s3.model.CryptoConfiguration;
import com.amazonaws.services.s3.model.CryptoMode;
import com.amazonaws.services.s3.model.EncryptionMaterials;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.StaticEncryptionMaterialsProvider;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
Encryption-Only Mode
Encryption-only is the default mode, if no CryptoMode is specified. To enable encryption, you must pass
a key to the EncryptionMaterials constructor. The example below uses the KeyGenerator Java class
generate a symmetric private key.
Code
To use an asymmetric key or a key pair, simply pass the key pair to the same EncryptionMaterials class.
The example below uses the KeyPairGenerator class to generate a key pair.
Code
Call the putObject method on the Amazon S3 encryption client to upload objects.
127
AWS SDK for Java Developer Guide
Using Amazon S3 Client-Side Encryption
Code
You can retrieve the object using the same client. This example calls the getObjectAsString method
to retrieve the string that was stored.
Code
System.out.println(s3Encryption.getObjectAsString(BUCKET_NAME, ENCRYPTED_KEY));
Code
The AuthenticatedEncryption mode can retrieve unencrypted objects and objects encrypted with
EncryptionOnly mode. The following example shows the Amazon S3 encryption client retrieving an
unencrypted object.
Code
128
AWS SDK for Java Developer Guide
Using Amazon S3 Client-Side Encryption
System.out.println(s3Encryption.getObjectAsString(BUCKET_NAME, NON_ENCRYPTED_KEY));
Code
Code
129
AWS SDK for Java Developer Guide
Using Amazon S3 Client-Side Encryption
this client will be encrypted. Any objects you get from Amazon S3 using this client are automatically
decrypted.
Note
The following examples demonstrate how to use the Amazon S3 client-side encryption with
AWS KMS managed keys. To learn how to use encryption with your own keys, see Amazon S3
Client-Side Encryption with Client Master Keys (p. 126).
You can choose from three encryption modes when enabling client-side Amazon S3 encryption:
encryption-only, authenticated, and strict authenticated. The following sections show how to enable
each type. To learn which algorithms each mode uses, see the CryptoMode definition.
Required Imports
Import the following classes for these examples.
Imports
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.AmazonS3Encryption;
import com.amazonaws.services.s3.AmazonS3EncryptionClientBuilder;
import com.amazonaws.services.s3.model.CryptoConfiguration;
import com.amazonaws.services.s3.model.CryptoMode;
import com.amazonaws.services.s3.model.EncryptionMaterials;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.KMSEncryptionMaterialsProvider;
import com.amazonaws.services.s3.model.StaticEncryptionMaterialsProvider;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
Encryption-Only Mode
Encryption-only is the default mode, if no CryptoMode is specified. To use an AWS KMS managed key
for encryption, pass the AWS KMS key ID or alias to the KMSEncryptionMaterialsProvider constructor.
Code
Call the putObject method on the Amazon S3 encryption client to upload objects.
Code
You can retrieve the object using the same client. This example calls the getObjectAsString method
to retrieve the string that was stored.
130
AWS SDK for Java Developer Guide
Using Amazon S3 Client-Side Encryption
Code
System.out.println(s3Encryption.getObjectAsString(BUCKET_NAME, ENCRYPTED_KEY));
Code
The AuthenticatedEncryption mode can retrieve unencrypted objects and objects encrypted with
EncryptionOnly mode. The following example shows the Amazon S3 encryption client retrieving an
unencrypted object.
Code
131
AWS SDK for Java Developer Guide
Amazon SQS Examples
Note
To use client-side authenticated encryption, you must include the latest Bouncy Castle jar file in
the classpath of your application.
Code
Code
Topics
• Working with Amazon SQS Message Queues (p. 133)
• Sending, Receiving, and Deleting Amazon SQS Messages (p. 135)
132
AWS SDK for Java Developer Guide
Working with Amazon SQS Message Queues
• Enabling Long Polling for Amazon SQS Message Queues (p. 137)
• Setting Visibility Timeout in Amazon SQS (p. 138)
• Using Dead Letter Queues in Amazon SQS (p. 140)
This topic describes how to create, list, delete, and get the URL of an Amazon SQS queue by using the
AWS SDK for Java.
Create a Queue
Use the AmazonSQS client's createQueue method, providing a CreateQueueRequest object that
describes the queue parameters.
Imports
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.AmazonSQSException;
import com.amazonaws.services.sqs.model.CreateQueueRequest;
Code
try {
sqs.createQueue(create_request);
} catch (AmazonSQSException e) {
if (!e.getErrorCode().equals("QueueAlreadyExists")) {
throw e;
}
}
You can use the simplified form of createQueue, which needs only a queue name, to create a standard
queue.
Listing Queues
To list the Amazon SQS queues for your account, call the AmazonSQS client's listQueues method.
Imports
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
133
AWS SDK for Java Developer Guide
Working with Amazon SQS Message Queues
import com.amazonaws.services.sqs.model.ListQueuesResult;
Code
Using the listQueues overload without any parameters returns all queues. You can filter the returned
results by passing it a ListQueuesRequest object.
Imports
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.ListQueuesRequest;
Code
Imports
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
Code
Delete a Queue
Provide the queue's URL (p. 134) to the AmazonSQS client's deleteQueue method.
Imports
import com.amazonaws.services.sqs.AmazonSQS;
134
AWS SDK for Java Developer Guide
Sending, Receiving, and Deleting Amazon SQS Messages
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
Code
More Info
• How Amazon SQS Queues Work in the Amazon SQS Developer Guide
• CreateQueue in the Amazon SQS API Reference
• GetQueueUrl in the Amazon SQS API Reference
• ListQueues in the Amazon SQS API Reference
• DeleteQueues in the Amazon SQS API Reference
Send a Message
Add a single message to an Amazon SQS queue by calling the AmazonSQS client's sendMessage
method. Provide a SendMessageRequest object that contains the queue's URL (p. 134), message body,
and optional delay value (in seconds).
Imports
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.SendMessageRequest;
Code
Imports
135
AWS SDK for Java Developer Guide
Sending, Receiving, and Deleting Amazon SQS Messages
import com.amazonaws.services.sqs.model.SendMessageBatchRequest;
import com.amazonaws.services.sqs.model.SendMessageBatchRequestEntry;
Code
Receive Messages
Retrieve any messages that are currently in the queue by calling the AmazonSQS client's
receiveMessage method, passing it the queue's URL. Messages are returned as a list of Message
objects.
Imports
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.AmazonSQSException;
import com.amazonaws.services.sqs.model.SendMessageBatchRequest;
Code
Code
More Info
• How Amazon SQS Queues Work in the Amazon SQS Developer Guide
• SendMessage in the Amazon SQS API Reference
• SendMessageBatch in the Amazon SQS API Reference
• ReceiveMessage in the Amazon SQS API Reference
• DeleteMessage in the Amazon SQS API Reference
136
AWS SDK for Java Developer Guide
Enabling Long Polling for Amazon SQS Message Queues
Long polling helps reduce your cost of using Amazon SQS by reducing the number of empty responses
when there are no messages available to return in reply to a ReceiveMessage request sent to an Amazon
SQS queue and eliminating false empty responses.
Note
You can set a long polling frequency from 1–20 seconds.
Imports
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.AmazonSQSException;
import com.amazonaws.services.sqs.model.CreateQueueRequest;
Code
try {
sqs.createQueue(create_request);
} catch (AmazonSQSException e) {
if (!e.getErrorCode().equals("QueueAlreadyExists")) {
throw e;
}
}
Imports
import com.amazonaws.services.sqs.model.SetQueueAttributesRequest;
Code
137
AWS SDK for Java Developer Guide
Setting Visibility Timeout in Amazon SQS
Imports
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
Code
More Info
• Amazon SQS Long Polling in the Amazon SQS Developer Guide
• CreateQueue in the Amazon SQS API Reference
• ReceiveMessage in the Amazon SQS API Reference
• SetQueueAttributes in the Amazon SQS API Reference
138
AWS SDK for Java Developer Guide
Setting Visibility Timeout in Amazon SQS
Imports
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
Code
// Get the receipt handle for the first message in the queue.
String receipt = sqs.receiveMessage(queue_url)
.getMessages()
.get(0)
.getReceiptHandle();
Imports
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.ChangeMessageVisibilityBatchRequestEntry;
import java.util.ArrayList;
import java.util.List;
Code
List<ChangeMessageVisibilityBatchRequestEntry> entries =
new ArrayList<ChangeMessageVisibilityBatchRequestEntry>();
entries.add(new ChangeMessageVisibilityBatchRequestEntry(
"unique_id_msg1",
sqs.receiveMessage(queue_url)
.getMessages()
.get(0)
.getReceiptHandle())
.withVisibilityTimeout(timeout));
entries.add(new ChangeMessageVisibilityBatchRequestEntry(
"unique_id_msg2",
sqs.receiveMessage(queue_url)
.getMessages()
.get(0)
.getReceiptHandle())
.withVisibilityTimeout(timeout + 200));
sqs.changeMessageVisibilityBatch(queue_url, entries);
139
AWS SDK for Java Developer Guide
Using Dead Letter Queues in Amazon SQS
More Info
• Visibility Timeout in the Amazon SQS Developer Guide
• SetQueueAttributes in the Amazon SQS API Reference
• GetQueueAttributes in the Amazon SQS API Reference
• ReceiveMessage in the Amazon SQS API Reference
• ChangeMessageVisibility in the Amazon SQS API Reference
• ChangeMessageVisibilityBatch in the Amazon SQS API Reference
• A dead letter queue must be the same type of queue (FIFO or standard) as the source queue.
• A dead letter queue must be created using the same AWS account and region as the source queue.
Here we create two identical Amazon SQS queues, one of which will serve as the dead letter queue:
Imports
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.AmazonSQSException;
Code
140
AWS SDK for Java Developer Guide
Getting Temporary Credentials with AWS STS
To set the redrive policy for your source queue, call the AmazonSQS class' setQueueAttributes
method with a SetQueueAttributesRequest object for which you've set the RedrivePolicy attribute
with your JSON redrive policy.
Imports
import com.amazonaws.services.sqs.model.GetQueueAttributesRequest;
import com.amazonaws.services.sqs.model.GetQueueAttributesResult;
import com.amazonaws.services.sqs.model.SetQueueAttributesRequest;
Code
sqs.setQueueAttributes(request);
More Info
• Using Amazon SQS Dead Letter Queues in the Amazon SQS Developer Guide
• SetQueueAttributes in the Amazon SQS API Reference
141
AWS SDK for Java Developer Guide
(Optional) Activate and use an AWS STS region
Note
Activating a region is optional; by default, temporary security credentials are obtained from
the global endpoint sts.amazonaws.com. However, to reduce latency and to enable you to build
redundancy into your requests by using additional endpoints if an AWS STS request to the
first endpoint fails, you can activate regions that are geographically closer to your services or
applications that use the credentials.
1. Sign in as an IAM user with permissions to perform IAM administration tasks "iam:*" for the
account for which you want to activate AWS STS in a new region.
2. Open the IAM console and in the navigation pane click Account Settings.
3. Expand the STS Regions list, find the region that you want to use, and then click Activate.
After this, you can direct calls to the STS endpoint that is associated with that region.
Note
For more information about activating STS regions and for a list of the available AWS STS
endpoints, see Activating and Deactivating AWS STS in an AWS Region in the IAM User Guide.
When creating the client with no arguments, the default credential provider chain is used to retrieve
credentials. You can provide a specific credential provider if you want. For more information, see
Providing AWS Credentials in the AWS SDK for Java.
2. Optional; requires that you have activated the region) Set the endpoint for the STS client:
sts_client.setEndpoint("sts-endpoint.amazonaws.com");
142
AWS SDK for Java Developer Guide
Use the temporary credentials to access AWS resources
session_token_request.setDurationSeconds(7200); // optional.
The duration of temporary credentials can range from 900 seconds (15 minutes) to 129600 seconds
(36 hours) for IAM users. If a duration isn't specified, then 43200 seconds (12 hours) is used by
default.
For a root AWS account, the valid range of temporary credentials is from 900 to 3600 seconds (1
hour), with a default value of 3600 seconds if no duration is specified.
Important
It is strongly recommended, from a security standpoint, that you use IAM users instead of the
root account for AWS access. For more information, see IAM Best Practices in the IAM User
Guide.
4. Call getSessionToken on the STS client to get a session token, using the
GetSessionTokenRequest object:
GetSessionTokenResult session_token_result =
sts_client.getSessionToken(session_token_request);
The session credentials provide access only for the duration that was specified by the
GetSessionTokenRequest object. Once the credentials expire, you will need to call
getSessionToken again to obtain a new session token for continued access to AWS.
AmazonS3 s3 = AmazonS3ClientBuilder.standard()
.withCredentials(new
AWSStaticCredentialsProvider(sessionCredentials)
.build();
You can now use the AmazonS3 object to make Amazon S3 requests.
143
AWS SDK for Java Developer Guide
Amazon SWF Examples
There are two ways to work with Amazon SWF using the AWS SDK for Java, by using the SWF client
object, or by using the AWS Flow Framework for Java. The AWS Flow Framework for Java is more difficult
to configure initially, since it makes heavy use of annotations and relies on additional libraries such as
AspectJ and the Spring Framework. However, for large or complex projects, you will save coding time by
using the AWS Flow Framework for Java. For more information, see the AWS Flow Framework for Java
Developer Guide.
This section provides examples of programming Amazon SWF by using the AWS SDK for Java client
directly.
Topics
• Amazon SWF Basics (p. 144)
• Building a Simple Amazon SWF Application (p. 145)
• Lambda Tasks (p. 158)
• Shutting Down Activity and Workflow Workers Gracefully (p. 161)
• Registering Domains (p. 163)
• Listing Domains (p. 164)
Dependencies
Basic Amazon SWF applications will require the following dependencies, which are included with the
AWS SDK for Java:
• aws-java-sdk-1.11.*.jar
• commons-logging-1.1.*.jar
• httpclient-4.3.*.jar
• httpcore-4.3.*.jar
• jackson-annotations-2.5.*.jar
• jackson-core-2.5.*.jar
• jackson-databind-2.5.*.jar
• joda-time-2.8.*.jar
144
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
Note
the version numbers of these packages will differ depending on the version of the SDK that you
have, but the versions that are supplied with the SDK have been tested for compatibility, and are
the ones you should use.
AWS Flow Framework for Java applications require additonal setup, and additional dependencies. See
the AWS Flow Framework for Java Developer Guide for more information about using the framework.
Imports
In general, you can use the following imports for code development:
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder;
It's a good practice to import only the classes you require, however. You will likely end up specifying
particular classes in the com.amazonaws.services.simpleworkflow.model workspace:
import com.amazonaws.services.simpleworkflow.model.PollForActivityTaskRequest;
import com.amazonaws.services.simpleworkflow.model.RespondActivityTaskCompletedRequest;
import com.amazonaws.services.simpleworkflow.model.RespondActivityTaskFailedRequest;
import com.amazonaws.services.simpleworkflow.model.TaskList;
If you are using the AWS Flow Framework for Java, you will import classes from the
com.amazonaws.services.simpleworkflow.flow workspace. For example:
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
import com.amazonaws.services.simpleworkflow.flow.ActivityWorker;
Note
The AWS Flow Framework for Java has additional requirements beyond those of the base AWS
SDK for Java. For more information, see the AWS Flow Framework for Java Developer Guide.
While this seems very simple on the surface, Amazon SWF applications consist of a number of parts
working together:
145
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
Behind the scenes, Amazon SWF orchestrates the operation of these components, coordinating their flow
from the AWS cloud, passing data between them, handling timeouts and heartbeat notifications, and
logging workflow execution history.
Prerequisites
Development environment
The development environment used in this tutorial consists of:
Note
If you use a different build system than Maven, you can still create a project using the
appropriate steps for your environment and use the the concepts provided here to follow along.
More information about configuring and using the AWS SDK for Java with various build systems
is provided in Getting Started (p. 3).
Likewise, but with more effort, the steps shown here can be implemented using any of the AWS
SDKs with support for Amazon SWF.
All of the necessary external dependencies are included with the AWS SDK for Java, so there's nothing
additional to download.
AWS access
To access Amazon Web Services (AWS), you must have an active AWS account. For information about
signing up for AWS and creating an IAM user (recommended over using root account credentials), see
Sign Up for AWS and Create an IAM User (p. 3).
This tutorial uses the terminal (command-line) to run the example code, and expects that you have
your AWS credentials and configuration accessible to the SDK. The easiest way to do this is to use the
environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. You should also set the
AWS_REGION to the region you want to use.
For example, on Linux, macOS, or Unix, set the variables this way:
export AWS_ACCESS_KEY_ID=your_access_key_id
export AWS_SECRET_ACCESS_KEY=your_secret_access_key
146
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
export AWS_REGION=us-east-1
set AWS_ACCESS_KEY_ID=your_access_key_id
set AWS_SECRET_ACCESS_KEY=your_secret_access_key
set AWS_REGION=us-east-1
Important
Substitute your own access key, secret access key and region information for the example values
shown here.
For more information about configuring your credentials for the SDK, see Set up AWS
Credentials and Region for Development (p. 6).
This will create a new project with a standard maven project structure:
helloswf
### pom.xml
### src
### main
# ### java
# ### example
# ### swf
# ### hello
# ### App.java
### test
### ...
You can ignore or delete the test directory and all it contains, we won't be using it for this tutorial.
You can also delete App.java, since we'll be replacing it with new classes.
2. Edit the project's pom.xml file and add the aws-java-sdk-simpleworkflow module by adding a
dependency for it within the <dependencies> block.
ependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-simpleworkflow</artifactId>
<version>1.11.245</version>
</dependency>
dependencies>
3. Make sure that Maven builds your project with JDK 1.7+ support. Add the following to your project
(either before or after the <dependencies> block) in pom.xml:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
147
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
<target>1.8</target>
</configuration>
</plugin>
</plugins>
• HelloTypes.java—contains the project's domain, activity and workflow type data, shared with the
other components. It also handles registering these types with SWF.
• ActivityWorker.java—contains the activity worker, which polls for activity tasks and runs activities in
response.
• WorkflowWorker.java—contains the workflow worker (decider), which polls for decision tasks and
schedules new activities.
• WorkflowStarter.java—contains the workflow starter, which starts a new workflow execution, which
will cause SWF to start generating decision and workflow tasks for your workers to consume.
package aws.example.helloswf;
3. Add import declarations for the AmazonSimpleWorkflowClient class and for multiple classes in the
com.amazonaws.services.simpleworkflow.model namespace. To simplify things, we'll use:
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder;
import com.amazonaws.services.simpleworkflow.model.*;
1. Open your text editor and create the file HelloTypes.java, adding a package declaration and
imports according to the common steps (p. 148).
2. Declare the HelloTypes class and provide it with values to use for your registered activity and
workflow types:
148
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
4. Add a new function to register a SWF domain. A domain is a logical container for a number of related
SWF activity and workflow types. SWF components can only communicate with each other if they
exist within the same domain.
When you register a domain, you provide it with a name (any set of 1 – 256 characters excluding
:, /, |, control characters or the literal string 'arn') and a retention period, which is the number
of days that Amazon SWF will keep your workflow's execution history data after a workflow
execution has completed. The maximum workflow execution retention period is 90 days. See
RegisterDomainRequest for more information.
If a domain with that name already exists, a DomainAlreadyExistsException is raised. Because we're
unconcerned if the domain has already been created, we can ignore the exception.
Note
This code demonstrates a common pattern when working with AWS SDK for Java methods,
data for the method is supplied by a class in the simpleworkflow.model namespace, which
you instantiate and populate using the chainable .with* methods.
5. Add a function to register a new activity type. An activity represents a unit of work in your workflow.
An activity type is identified by a name and a version, which are used to uniquely identify the activity
from any others in the domain that it's registered in. Activities also contain a number of optional
149
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
parameters, such as the default task-list used to receive tasks and data from SWF and a number of
different timeouts that you can use to place constraints upon how long different parts of the activity
execution can take. See RegisterActivityTypeRequest for more information.
Note
All timeout values are specified in seconds. See Amazon SWF Timeout Types for a full
description of how timeouts affect your workflow executions.
If the activity type that you're trying to register already exists, an TypeAlreadyExistsException is raised.
6. Add a function to register a new workflow type. A workflow, also known as a decider represents the
logic of your workflow's execution.
Similar to activity types, workflow types are identified by a name and a version and also have
configurable timeouts. See RegisterWorkflowTypeRequest for more information.
If the workflow type that you're trying to register already exists, an TypeAlreadyExistsException is
raised.
7. Finally, make the class executable by providing it a main method, which will register the domain, the
activity type, and the workflow type in turn:
You can build (p. 156) and run (p. 157) the application now to run the registration script, or continue
with coding the activity and workflow workers. Once the domain, workflow and activity have been
registered, you won't need to run this again—these types persist until you deprecate them yourself.
The activity worker is the bit of code that polls for activity tasks that are generated by Amazon SWF in
response to workflow decisions. When it receives an activity task, it runs the corresponding activity and
returns a success/failure response back to the workflow.
150
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
1. Open your text editor and create the file ActivityWorker.java, adding a package declaration and
imports according to the common steps (p. 148).
2. Add the ActivityWorker class to the file, and give it a data member to hold a SWF client that we'll
use to interact with Amazon SWF:
The activity simply takes a string, combines it into a greeting and returns the result. Although there is
little chance that this activity will raise an exception, it's a good idea to design activities that can raise
an error if something goes wrong.
4. Add a main method that we'll use as the activity task polling method. We'll start it by adding some
code to poll the task list for activity tasks:
The activity receives tasks from Amazon SWF by calling the SWF client's pollForActivityTask
method, specifying the domain and task list to use in the passed-in PollForActivityTaskRequest.
Once a task is received, we retrieve a unique identifier for it by calling the task's getTaskToken
method.
5. Next, write some code to process the tasks that come in. Add the following to your main method,
right after the code that polls for the task and retrieves its task token.
if (task_token != null) {
String result = null;
Throwable error = null;
try {
System.out.println("Executing the activity task with input '" +
task.getInput() + "'.");
result = sayHello(task.getInput());
} catch (Throwable th) {
error = th;
}
if (error == null) {
System.out.println("The activity task succeeded with result '"
151
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
+ result + "'.");
swf.respondActivityTaskCompleted(
new RespondActivityTaskCompletedRequest()
.withTaskToken(task_token)
.withResult(result));
} else {
System.out.println("The activity task failed with the error '"
+ error.getClass().getSimpleName() + "'.");
swf.respondActivityTaskFailed(
new RespondActivityTaskFailedRequest()
.withTaskToken(task_token)
.withReason(error.getClass().getSimpleName())
.withDetails(error.getMessage()));
}
}
If the task token is not null, then we can start running the activity method (sayHello), providing it
with the input data that was sent with the task.
If the task succeeded (no error was generated), then the worker responds to SWF by calling the SWF
client's respondActivityTaskCompleted method with a RespondActivityTaskCompletedRequest
object containing the task token and the activity's result data.
On the other hand, if the task failed, then we respond by calling the respondActivityTaskFailed
method with a RespondActivityTaskFailedRequest object, passing it the task token and information
about the error.
Note
This activity will not shut down gracefully if killed. Although it is beyond the scope of this
tutorial, an alternative implementation of this activity worker is provided in the accompanying
topic, Shutting Down Activity and Workflow Workers Gracefully (p. 161).
When the workflow worker receives a task, it makes some sort of decision (usually whether to schedule a
new activity or not) and takes an appropriate action (such as scheduling the activity).
1. Open your text editor and create the file WorkflowWorker.java, adding a package declaration and
imports according to the common steps (p. 148).
2. Add a few additional imports to the file:
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
3. Declare the WorkflowWorker class, and create an instance of the AmazonSimpleWorkflowClient class
used to access SWF methods.
4. Add the main method. The method loops continuously, polling for decision tasks using the SWF
client's pollForDecisionTask method. The PollForDecisionTaskRequest provides the details.
152
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
while (true) {
System.out.println(
"Polling for a decision task from the tasklist '" +
HelloTypes.TASKLIST + "' in the domain '" +
HelloTypes.DOMAIN + "'.");
Once a task is received, we call its getTaskToken method, which returns a string that can be
used to identify the task. If the returned token is not null, then we process it further in the
executeDecisionTask method, passing it the task token and the list of HistoryEvent objects sent
with the task.
5. Add the executeDecisionTask method, taking the task token (a String) and the HistoryEvent
list.
We also set up some data members to keep track of things such as:
• A list of Decision objects used to report the results of processing the task.
• A String to hold workflow input provided by the "WorkflowExecutionStarted" event
• a count of the scheduled and open (running) activities to avoid scheduling the same activity when it
has already been scheduled or is currently running.
• a boolean to indicate that the activity has completed.
• A String to hold the activity results, for returning it as our workflow result.
6. Next, add some code to executeDecisionTask to process the HistoryEvent objects that were
sent with the task, based on the event type reported by the getEventType method.
153
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
workflow_input =
event.getWorkflowExecutionStartedEventAttributes()
.getInput();
break;
case "ActivityTaskScheduled":
scheduled_activities++;
break;
case "ScheduleActivityTaskFailed":
scheduled_activities--;
break;
case "ActivityTaskStarted":
scheduled_activities--;
open_activities++;
break;
case "ActivityTaskCompleted":
open_activities--;
activity_completed = true;
result = event.getActivityTaskCompletedEventAttributes()
.getResult();
break;
case "ActivityTaskFailed":
open_activities--;
break;
case "ActivityTaskTimedOut":
open_activities--;
break;
}
}
System.out.println("]");
The other event types can be used if your workflow requires them. See the HistoryEvent class
description for information about each event type.
Note
Strings in switch statements were introduced in Java 7. If you're using an earlier version
of Java, you can make use of the EventType class to convert the String returned by
history_event.getType() to an enum value and then back to a String if necessary:
EventType et = EventType.fromValue(event.getEventType());
7. After the switch statement, add more code to respond with an appropriate decision based on the
task that was received.
if (activity_completed) {
decisions.add(
new Decision()
.withDecisionType(DecisionType.CompleteWorkflowExecution)
.withCompleteWorkflowExecutionDecisionAttributes(
new CompleteWorkflowExecutionDecisionAttributes()
.withResult(result)));
} else {
if (open_activities == 0 && scheduled_activities == 0) {
154
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
ScheduleActivityTaskDecisionAttributes attrs =
new ScheduleActivityTaskDecisionAttributes()
.withActivityType(new ActivityType()
.withName(HelloTypes.ACTIVITY)
.withVersion(HelloTypes.ACTIVITY_VERSION))
.withActivityId(UUID.randomUUID().toString())
.withInput(workflow_input);
decisions.add(
new Decision()
.withDecisionType(DecisionType.ScheduleActivityTask)
.withScheduleActivityTaskDecisionAttributes(attrs));
} else {
// an instance of HelloActivity is already scheduled or running. Do nothing,
another
// task will be scheduled once the activity completes, fails or times out
}
}
• If the activity hasn't been scheduled yet, we respond with a ScheduleActivityTask decision,
which provides information in a ScheduleActivityTaskDecisionAttributes structure about the activity
that Amazon SWF should schedule next, also including any data that Amazon SWF should send to
the activity.
• If the activity was completed, then we consider the entire workflow completed
and respond with a CompletedWorkflowExecution decision, filling in a
CompleteWorkflowExecutionDecisionAttributes structure to provide details about the completed
workflow. In this case, we return the result of the activity.
In either case, the decision information is added to the Decision list that was declared at the top of
the method.
8. Complete the decision task by returning the list of Decision objects collected while processing the
task. Add this code at the end of the executeDecisionTask method that we've been writing:
swf.respondDecisionTaskCompleted(
new RespondDecisionTaskCompletedRequest()
.withTaskToken(taskToken)
.withDecisions(decisions));
The SWF client's respondDecisionTaskCompleted method takes the task token that identifies the
task as well as the list of Decision objects.
1. Open your text editor and create the file WorkflowStarter.java, adding a package declaration and
imports according to the common steps (p. 148).
2. Add the WorkflowStarter class:
155
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
The WorkflowStarter class consists of a single method, main, which takes an optional argument
passed on the command-line as input data for the workflow.
The Run object that startWorkflowExecution returns provides a run ID, a value that can be used
to identify this particular workflow execution in Amazon SWF's history of your workflow executions.
Note
The run ID is generated by Amazon SWF, and is not the same as the workflow execution name
that you pass in when starting the workflow execution.
mvn package
156
AWS SDK for Java Developer Guide
Building a Simple Amazon SWF Application
export CLASSPATH='target/helloswf-1.0.jar:/path/to/sdk/lib/*:/path/to/sdk/third-party/lib/
*'
java example.swf.hello.HelloTypes
or use the java command's -cp option to set the classpath while running each applications.
The style that you use is up to you. If you had no trouble building the code, buth then try to run the
examples and get a series of "NoClassDefFound" errors, it is likely because the classpath is set incorrectly.
After building, and if you've set the CLASSPATH (p. 157), you can run the registration code by executing
the command:
echo 'If there are arguments to the class, put them in quotes after the class name.'
exit 1
If you're running these commands in separate windows, omit the final & operator from each line.
fi
Note
If you want to provide your own input data, which will be passed first to the workflow and then
to the activity, add it to the command-line. For example:
157
AWS SDK for Java Developer Guide
Lambda Tasks
Once you begin the workflow execution, you should start seeing output delivered by both workers and
by the workflow execution itself. When the workflow finally completes, its output will be printed to the
screen.
Lambda Tasks
As an alternative to, or in conjunction with, Amazon SWF activities, you can use Lambda functions to
represent units of work in your workflows, and schedule them similarly to activities.
This topic focuses on how to implement Amazon SWF Lambda tasks using the AWS SDK for Java. For
more information about Lambda tasks in general, see AWS Lambda Tasks in the Amazon SWF Developer
Guide.
You will need the Amazon Resource Name (ARN) of this IAM role when you register a workflow that will
use Lambda tasks.
Here's a simple Lambda function that could be used in place of the activity in Building a Simple Amazon
SWF Application (p. 145).
• This version is written in JavaScript, which can be entered directly using the AWS Management
Console:
158
AWS SDK for Java Developer Guide
Lambda Tasks
• Here is the same function written in Java, which you could also deploy and run on Lambda:
package example.swf.hellolambda;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.util.json.JSONException;
import com.amazonaws.util.json.JSONObject;
Note
To learn more about deploying Java functions to Lambda, see Creating a Deployment Package
(Java) in the AWS Lambda Developer Guide. You will also want to look at the section titled
Programming Model for Authoring Lambda Functions in Java.
Lambda functions take an event or input object as the first parameter, and a context object as the second,
which provides information about the request to run the Lambda function. This particular function
expects input to be in JSON, with a who field set to the name used to create the greeting.
159
AWS SDK for Java Developer Guide
Lambda Tasks
ScheduleLambdaFunctionDecisionAttributes attrs =
new ScheduleLambdaFunctionDecisionAttributes()
.withId("HelloFunction (Lambda task example)")
.withName(function_arn)
.withInput(workflow_input);
decisions.add(
You can also provide optional input for the Lambda function and set its start to close timeout value,
which is the number of seconds that the Lambda function is allowed to run before generating a
LambdaFunctionTimedOut event.
Note
This code uses the AWSLambdaClient to retrieve the ARN of the Lambda function, given the
function name. You can use this technique to avoid hard-coding the full ARN (which includes
your AWS account ID) in your code.
160
AWS SDK for Java Developer Guide
Shutting Down Activity and Workflow Workers Gracefully
case ScheduleLambdaFunctionFailed:
scheduled_functions--;
break;
case LambdaFunctionStarted:
scheduled_functions--;
running_functions++;
break;
case LambdaFunctionCompleted:
running_functions--;
function_completed = true;
result = event.getLambdaFunctionCompletedEventAttributes()
.getResult();
break;
case LambdaFunctionFailed:
running_functions--;
break;
case LambdaFunctionTimedOut:
running_functions--;
break;
LambdaFunctionCompleted:
running_functions--;
Worker classes are designed to run continuously, polling for tasks sent by Amazon SWF in order to
run activities or return decisions. Once a poll request is made, Amazon SWF records the poller and will
attempt to assign a task to it.
If the workflow worker is terminated during a long poll, Amazon SWF may still try to send a task to the
terminated worker, resulting in a lost task (until the task times out).
One way to handle this situation is to wait for all long poll requests to return before the worker
terminates.
In this topic, we'll rewrite the activity worker from helloswf, using Java's shutdown hooks to attempt a
graceful shutdown of the activity worker.
package aws.example.helloswf;
161
AWS SDK for Java Developer Guide
Shutting Down Activity and Workflow Workers Gracefully
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder;
import com.amazonaws.services.simpleworkflow.model.ActivityTask;
import com.amazonaws.services.simpleworkflow.model.PollForActivityTaskRequest;
import com.amazonaws.services.simpleworkflow.model.RespondActivityTaskCompletedRequest;
import com.amazonaws.services.simpleworkflow.model.RespondActivityTaskFailedRequest;
import com.amazonaws.services.simpleworkflow.model.TaskList;
if (taskToken != null) {
String result = null;
Throwable error = null;
try {
System.out.println("Executing the activity task with input '"
+ task.getInput() + "'.");
result = executeActivityTask(task.getInput());
162
AWS SDK for Java Developer Guide
Registering Domains
}
catch (Throwable th) {
error = th;
}
if (error == null) {
System.out.println("The activity task succeeded with result '"
+ result + "'.");
swf.respondActivityTaskCompleted(
new RespondActivityTaskCompletedRequest()
.withTaskToken(taskToken)
.withResult(result));
}
else {
System.out.println("The activity task failed with the error '"
+ error.getClass().getSimpleName() + "'.");
swf.respondActivityTaskFailed(
new RespondActivityTaskFailedRequest()
.withTaskToken(taskToken)
.withReason(error.getClass().getSimpleName())
.withDetails(error.getMessage()));
}
}
}
}
}
In this version, the polling code that was in the main function in the original version has been moved
into its own method, pollAndExecute.
The main function now uses a CountDownLatch in conjunction with a shutdown hook to cause the
thread to wait for up to 60 seconds after its termination is requested before letting the thread shut
down.
Registering Domains
Every workflow and activity in Amazon SWF needs a domain to run in.
1. Create a new RegisterDomainRequest object, providing it with at least the domain name and
workflow execution retention period (these parameters are both required).
2. Call the AmazonSimpleWorkflowClient.registerDomain method with the RegisterDomainRequest
object.
3. Catch the DomainAlreadyExistsException if the domain you're requesting already exists (in which
case, no action is usually required).
163
AWS SDK for Java Developer Guide
Listing Domains
}
}
Listing Domains
You can list the Amazon SWF domains associated with your account and AWS region by registration type.
1. Create a ListDomainsRequest object, and specify the registration status of the domains that you're
interested in—this is required.
2. Call AmazonSimpleWorkflowClient.listDomains with the ListDomainRequest object. Results are
provided in a DomainInfos object.
3. Call getDomainInfos on the returned object to get a list of DomainInfo objects.
4. Call getName on each DomainInfo object to get its name.
164
AWS SDK for Java Developer Guide
Document History
This topic describes important changes to the AWS SDK for Java Developer Guide over the course of its
history.
Nov 2, 2017
Added cryptography examples for Amazon S3 encryption client, including new topics: Using Amazon
S3 Client-Side Encryption (p. 126) and Amazon S3 Client-Side Encryption with AWS KMS Managed
Keys (p. 129) and Amazon S3 Client-Side Encryption with Client Master Keys (p. 126).
Apr 14, 2017
Made a number of updates to the Amazon S3 Examples Using the AWS SDK for Java (p. 104) section,
including new topics: Managing Amazon S3 Access Permissions for Buckets and Objects (p. 112) and
Configuring an Amazon S3 Bucket as a Website (p. 124).
Apr 04, 2017
A new topic, Enabling Metrics for the AWS SDK for Java (p. 29) describes how to generate
application and SDK performance metrics for the AWS SDK for Java.
Apr 03, 2017
Added new CloudWatch examples to the CloudWatch Examples Using the AWS SDK for Java (p. 35)
section: Getting Metrics from CloudWatch (p. 35), Publishing Custom Metric Data (p. 36), Working
with CloudWatch Alarms (p. 37), Using Alarm Actions in CloudWatch (p. 39), and Sending Events to
CloudWatch (p. 40)
Mar 27, 2017
Added more Amazon EC2 examples to the Amazon EC2 Examples Using the AWS SDK for Java (p. 52)
section: Managing Amazon EC2 Instances (p. 80), Using Elastic IP Addresses in Amazon EC2 (p. 83),
Using Regions and Availability Zones (p. 85), Working with Amazon EC2 Key Pairs (p. 87), and
Working with Security Groups in Amazon EC2 (p. 88).
Mar 21, 2017
Added a new set of IAM examples to the IAM Examples Using the AWS SDK for Java (p. 91) section:
Managing IAM Access Keys (p. 91), Managing IAM Users (p. 94), Using IAM Account Aliases (p. 96),
Working with IAM Policies (p. 98), and Working with IAM Server Certificates (p. 101)
Mar 13, 2017
Added three new topics to the Amazon SQS section: Enabling Long Polling for Amazon SQS Message
Queues (p. 137), Setting Visibility Timeout in Amazon SQS (p. 138), and Using Dead Letter Queues in
Amazon SQS (p. 140).
Jan 26, 2017
Added a new Amazon S3 topic, Using TransferManager for Amazon S3 Operations (p. 117), and a
new Best Practices for AWS Development with the AWS SDK for Java (p. 11) topic in the Using the
AWS SDK for Java (p. 11) section.
Jan 16, 2017
Added a new Amazon S3 topic, Managing Access to Amazon S3 Buckets Using Bucket
Policies (p. 114), and two new Amazon SQS topics, Working with Amazon SQS Message
Queues (p. 133) and Sending, Receiving, and Deleting Amazon SQS Messages (p. 135).
165
AWS SDK for Java Developer Guide
Added new example topics for DynamoDB: Working with Tables in DynamoDB (p. 43) and Working
with Items in DynamoDB (p. 47).
Sep 26, 2016
The topics in the Advanced section have been moved into Using the AWS SDK for Java (p. 11), since
they really are central to using the SDK.
Aug 25, 2016
A new topic, Creating Service Clients (p. 12), has been added to Using the AWS SDK for Java (p. 11),
which demonstrates how to use client builders to simplify the creation of AWS service clients.
The AWS SDK for Java Code Examples (p. 33) section has been updated with new examples for
S3 (p. 104) which are backed by a repository on GitHub that contains the complete example code.
May 02, 2016
A new topic, Asynchronous Programming (p. 20), has been added to the Using the AWS SDK for
Java (p. 11) section, describing how to work with asynchronous client methods that return Future
objects or that take an AsyncHandler.
Apr 26, 2016
The SSL Certificate Requirements topic has been removed, since it is no longer relevant. Support for
SHA-1 signed certificates was deprecated in 2015 and the site that housed the test scripts has been
removed.
Mar 14, 2016
Added a new topic to the Amazon SWF section: Lambda Tasks (p. 158), which describes how to
implement a Amazon SWF workflow that calls Lambda functions as tasks as an alternative to using
traditional Amazon SWF activities.
Mar 04, 2016
The Amazon SWF Examples Using the AWS SDK for Java (p. 144) section has been updated with new
content:
• Amazon SWF Basics (p. 144)– Provides basic information about how to include SWF in your
projects.
• Building a Simple Amazon SWF Application (p. 145)– A new tutorial that provides step-by-step
guidance for Java developers new to Amazon SWF.
• Shutting Down Activity and Workflow Workers Gracefully (p. 161)– Describes how you can
gracefully shut down Amazon SWF worker classes using Java's concurrency classes.
Feb 23, 2016
The source for the AWS SDK for Java Developer Guide has been moved to aws-java-developer-guide.
Dec 28, 2015
Setting the JVM TTL for DNS Name Lookups (p. 29) has been moved from Advanced into Using the
AWS SDK for Java (p. 11), and has been rewritten for clarity.
Using the SDK with Apache Maven (p. 7) has been updated with information about how to include
the SDK's bill of materials (BOM) in your project.
Aug 04, 2015
SSL Certificate Requirements is a new topic in the Getting Started (p. 3) section that describes AWS'
move to SHA256-signed certificates for SSL connections, and how to fix early 1.6 and previous Java
environments to use these certificates, which are required for AWS access after September 30, 2015.
166
AWS SDK for Java Developer Guide
Note
Java 1.7+ is already capable of working with SHA256-signed certificates.
May 14, 2014
The introduction (p. 1) and getting started (p. 3) material has been heavily revised to support the
new guide structure and now includes guidance about how to Set up AWS Credentials and Region
for Development (p. 6).
The discussion of code samples (p. 33) has been moved into its own topic in the Additional
Documentation and Resources (p. 1) section.
Information about how to view the SDK revision history (p. 2) has been moved into the introduction.
May 9, 2014
The overall structure of the AWS SDK for Java documentation has been simplified, and the Getting
Started (p. 3) and Additional Documentation and Resources (p. 1) topics have been updated.
This topic, Document History, tracks changes to the AWS SDK for Java Developer Guide. It is intended
as a companion to the release notes history.
167