AWS Developer Tools Blog
AWS SDK for Java 2.x released
We’re pleased to announce that the AWS SDK for Java 2.x is now generally available and supported for production use.
Version 2.x is a major rewrite of the 1.11.x code base. Built with support for Java 8+, 2.x adds several frequently requested features, like nonblocking I/O, improved start-up performance and automatic iteration over paginated responses. In addition, many aspects of the SDK have been updated with a focus on consistency, immutability, and ease of use.
Moving to version 2.x is easy, because it can be run in the same JVM as 1.11.x. This enables you to take advantage of the features you want from 2.x without having to migrate your entire product. Version 2.x includes most of features currently in 1.11.x, but not all. We’re releasing it immediately so you can take advantage of the new features without needing to wait for features you might not use. See the end of this post for the list of 1.11.x features that haven’t yet made it to 2.x.
Although we’re excited about 2.x, we also want to reassure customers that we will continue to update 1.11.x with new service APIs, new services, bug fixes and security fixes.
New features
Several new features have been added in 2.x, including nonblocking I/O, a pluggable HTTP layer, and HTTP client sharing.
Nonblocking I/O
The AWS SDK for Java 2.x utilizes a new, nonblocking SDK architecture built on Netty to support true nonblocking I/O. The 1.11.x version already has asynchronous variants of service clients, but they are a managed thread pool on top of the synchronous clients, so each request still requires its own thread. 2.x asynchronous clients are nonblocking all the way to the HTTP layer, allowing higher concurrency with a small, fixed number of threads.
The asynchronous clients immediately return a CompletableFuture
of the response, instead of blocking the thread until the response is available. Exceptions are delivered through the future, instead of being thrown by the client method call.
Other asynchronous operations that involve streaming input, like the Amazon S3 PutObject
, are a little different from their nonstreaming counterparts. They use AsyncRequestBody
, an adaptation of the reactive streams interfaces. This ensures that even streaming data to AWS is a nonblocking operation.
Asynchronous operations involving streaming output, like the Amazon S3 GetObject
, use AsyncResponseTransformer
, another adaptation of reactive streams interfaces. This ensures downloading data from AWS is also a nonblocking operation.
Automatic pagination
To maximize availability and minimize latency, many AWS APIs break up a result across multiple “pages” of responses. In 1.11.x, customers had to make multiple manual requests in order to access every page of responses. In 2.x, the SDK can handle this automatically, without requiring you to do the heavy lifting.
For example, the following 2.x code prints all of your Dynamo DB table names in the currently-configured Region.
In 1.11.x, this same behavior requires a large amount of boilerplate code.
Pluggable HTTP layer
The AWS SDK for Java 1.11.x is tightly coupled to the Apache HTTP client in order to invoke AWS APIs. Although this works well in general, there are often benefits to using a client that is more optimized for your runtime environment. Version 2.x continues to ship Apache as the default synchronous HTTP client, but you can replace it with another implementation that better suits your use-case.
When you first add the SDK to your project and create a client, a default HTTP implementation is selected automatically.
There are some cases where the default isn’t optimal. For example, in AWS Lambda, where startup time is one of the biggest latency concerns, you might want to use an HTTP client based on the JVM’s lightweight URLConnection
, instead of Apache’s higher-throughput, but slower-to-start HTTP client.
Version 2.x includes such a URLConnection
HTTP client, and it’s simple to use. First, add url-connection-client
as a new dependency of your application. If you’re using Maven, this is just a new entry in your pom.xml
file.
Then, configure your service in one of the following ways.
Option 1: Specify the HTTP client to use at client creation time.
To use multiple HTTP clients in the same application, you must specify which one you wish to use when you create the client.
Option 2: Change the default HTTP client using a system property at JVM startup.
Select the HTTP client at Java startup by using the software.amazon.awssdk.http.service.impl
system property for synchronous HTTP clients, or software.amazon.awssdk.http.async.service.impl
for asynchronous HTTP clients.
Option 3: Change the default HTTP client using a system property in Java code.
Instead of specifying the system properties listed previously when you start your JVM, you can also specify the system properties at runtime. Be sure to specify the values before you create any clients, or your values won’t be used.
HTTP client sharing
In 1.11.x of the SDK, each AWS service client instance had its own HTTP client with separate connections and resources. This is still the default in 2.x, but now you can share a single HTTP client among multiple AWS clients. This is useful in resource-constrained environments where you might want to share a single pool of connections among multiple AWS services.
Because the HTTP client is no longer tied to a single AWS client, you need to close the HTTP client yourself when you’re done using it.
Improvements
In addition to new features, every API in the SDK has been updated to improve consistency, usability, and thread safety. You can browse our full changelog to find everything, but we highlight the biggest improvements below.
Immutability
Many objects are mutable in 1.11.x, which means that their use requires more care to ensure that they aren’t mutated in a multithreaded environment. In 2.x, all objects used by the SDK are immutable and created using builders. This allows you to use the SDK in concurrent environments without worrying about whether other threads might make unsafe mutations.
All objects follow the same pattern: to create it, call its builder()
method, configure it, and call build()
.
In some circumstances, it might be beneficial to modify an immutable object. Although the immutable objects can’t be modified directly, 2.x makes it easy to create a copy of the immutable object with some values modified.
Although immutability and builders ensure thread safety and provide a consistent pattern for creating objects across 2.x, they add verbosity. For this reason, 2.x exposes optional lambda-style methods that remove much of the ceremony around calling builder()
and build()
.
Choose the one you like most to use in your code base.
Regions
In 1.11.x, multiple classes exist for managing AWS Regions and Region metadata. In 2.x, these have been simplified with the new Region
class.
Streaming API type conversions
In 1.11.x, uploading data to Amazon was done through input streams, with S3 also supporting files and strings. You had to map any other data types to one of these types to send them to Amazon. Version 2.x has been altered to support a large variety of streaming input types, to reduce the effort it takes to communicate with any streaming service.
Version 2.x has similarly expanded the type conversions available when downloading data from Amazon.
Amazon S3 client
To provide SDK support for the many services that AWS owns, the AWS SDKs make extensive use of code generation. In 1.11.x, all service clients are generated, except for the S3 client. This frequently results in a disconnect between how non-Java AWS SDKs and IAM policies refer to an S3 operation (e.g., DeleteBucketReplicationConfiguration
), and how the Java AWS SDK would refer to that same operation (DeleteBucketReplication
). This made creating IAM policies and switching to other SDKs difficult, because the equivalent string was not always well documented.
In 2.x, S3 is generated like every other service, ensuring the operation names, inputs, and outputs will always match those of other SDKs and IAM.
What’s missing in the AWS SDK for Java 2.x
As mentioned, not every feature in 1.11.x has made it to 2.x yet. We recommend using 2.x if you would benefit from the new features and improvements, and using 1.11.x if you would benefit from the features not yet in 2.x. Both versions of the SDK can be used at the same time, allowing you to pick and choose which parts you want to use from each SDK version.
The following 1.11.x features are not in 2.x yet:
- High-level libraries
- Waiters
- SDK metric publishing
- Progress listeners
Further reading
Get started with our AWS SDK for Java 2.x Developer Guide.
See what it takes to migrate your existing 1.11.x application with our 1.11.x to 2.x Migration Guide.
Get an exact list of what’s changed by using the 1.11.x to 2.x Changelog.
Contact us
Check out the 2.x source in GitHub.
Come join the AWS SDK for Java 2.x community chat on Gitter.
Articulate your feature requests or upvote existing ones on the GitHub Issues page.