Azure Java
Azure Java
This article shows you how to use Apache Maven to build applications with the Azure SDK for Java. In this
article, you'll set up a new project with Maven, build projects with Maven, and use the GraalVM native image
tooling to create platform-specific native binaries.
The Azure SDK for Java project includes a Maven archetype that can accelerate the bootstrapping of a new
project. The Azure SDK for Java Maven archetype creates a new application, with files and a directory structure
that follows best practices. In particular, the Azure SDK for Java Maven archetype creates a new Maven project
with the following features:
A dependency on the latest azure-sdk-bom BOM release, which ensures that all Azure SDK for Java
dependencies are aligned, and gives you the best developer experience possible.
Built-in support for GraalVM native image compilation.
Support for generating a new project with a specified set of Azure SDK for Java client libraries.
Integration with the Azure SDK for Java build tooling, which will give build-time analysis of your project to
ensure that many best practices are followed.
Prerequisites
Java Developer Kit, version 8 or later. We recommend version 17 for the best experience.
Apache Maven
mvn archetype:generate \
-DarchetypeGroupId=com.azure.tools \
-DarchetypeArtifactId=azure-sdk-archetype
After you enter this command, a series of prompts will ask for details about your project so the archetype can
generate the right output for you. The following table describes the properties you'll need to provide values for:
Alternately, you can provide these values when you call the archetype command shown earlier. This approach is
useful, for example, for automation purposes). You can specify the values as parameters using the standard
Maven syntax of appending -D to the parameter name, for example:
-DjavaVersion=17 .
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-sdk-bom</artifactId>
<version>{bom_version_to_target}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>{artifactId}</artifactId>
</dependency>
</dependencies>
You can find all releases of the Azure SDK for Java client BOM at azure-sdk-bom. We recommend using the
latest version to take advantage of the newest features of the Azure SDK for Java client libraries.
Using Maven to define project dependencies can make managing your projects simpler. With the Azure SDK
BOM and Azure SDK Maven archetype, you can accelerate your project while being more confident about your
dependency versioning over the long term. We recommend using the BOM to keep dependencies aligned and
up to date.
Include a package not in the BOM
The Azure SDK for Java client BOM includes only Generally Available (GA) libraries. If you want to depend on a
package that is still in beta or on a library version different than the one included in the BOM, you can specify
the Maven dependency version along with the groupId and artifactId in the dependency section. You can
choose to have dependencies that use BOM versions and dependencies with overridden versions in the same
project POM file, as shown in the following example:
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-messaging-eventhubs</artifactId> <!-- Use the dependency version that is in the BOM --
>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-messaging-servicebus</artifactId>
<version>7.4.0</version> <!-- Override the Service Bus dependency version specified in the BOM -->
</dependency>
</dependencies>
If you use the above approach and specify versions directly in your project, you might get dependency version
conflicts. These conflicts arise because different packages may depend on different versions of common
dependencies, and these versions may not be compatible with each other. When conflicts occur, you can
experience undesirable behavior at compile time or runtime. That's why we recommended that you rely on
versions that are in Azure SDK BOM unless strictly necessary.
Next steps
Get started with Azure extensions for IntelliJ and Eclipse
Get started with Azure extensions for IntelliJ and
Eclipse
2/16/2022 • 2 minutes to read • Edit Online
This article walks you through setting up a development environment for Azure development in Java. Microsoft
provides IDE extensions for both IntelliJ and Eclipse to increase productivity when working with the Azure SDK
for Java.
Next steps
Create a Hello World web app for Azure App Service using IntelliJ
Create a Hello World web app for Azure App Service using Eclipse
Get started with cloud development using Java on
Azure
2/16/2022 • 7 minutes to read • Edit Online
This article walks you through setting up a development environment for Azure development in Java. You'll then
create some Azure resources and connect to them to do some basic tasks, like uploading a file or deploying a
web application. When you're finished, you'll be ready to start using Azure services in your own Java
applications.
Prerequisites
An Azure account. If you don't have one, get a free trial.
Azure Cloud Shell or Azure CLI 2.0.
Java 8, which is included in Azure Cloud Shell.
Maven 3, which is included in Azure Cloud Shell.
Set up authentication
Your Java application needs read and create permissions in your Azure subscription to run the sample code in
this tutorial. Create a service principal, and configure your application to run with its credentials. Service
principals provide a way to create a noninteractive account associated with your identity to which you grant only
the privileges your app needs to run.
Create a service principal by using the Azure CLI 2.0, and capture the output:
{
"appId": "a487e0c1-82af-47d9-9a0b-af184eb87646d",
"displayName": "AzureJavaTest",
"name": "http://AzureJavaTest",
"password": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"tenant": "tttttttt-tttt-tttt-tttt-tttttttttttt"
}
For more authentication options, see the Azure Identity client library for Java.
Tooling
Create a new Maven project
NOTE
This article uses the Maven build tool to build and run the sample code. Other build tools, such as Gradle, also work with
the Azure SDK for Java.
Create a Maven project from the command line in a new directory on your system.
mkdir java-azure-test
cd java-azure-test
mvn archetype:generate -DgroupId=com.fabrikam -DartifactId=AzureApp \
-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
This step creates a basic Maven project under the testAzureApp directory. Add the following entries into the
project's pom.xml file to import the libraries used in the sample code in this tutorial.
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.azure.resourcemanager</groupId>
<artifactId>azure-resourcemanager</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-blob</artifactId>
<version>12.8.0</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.2.1.jre8</version>
</dependency>
Add a build entry under the top-level project element to use the maven-exec-plugin to run the samples.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<mainClass>com.fabrikam.AzureApp</mainClass>
</configuration>
</plugin>
</plugins>
</build>
import com.azure.core.credential.TokenCredential;
import com.azure.core.http.policy.HttpLogDetailLevel;
import com.azure.core.management.AzureEnvironment;
import com.azure.core.management.Region;
import com.azure.core.management.profile.AzureProfile;
import com.azure.identity.AzureAuthorityHosts;
import com.azure.identity.EnvironmentCredentialBuilder;
import com.azure.resourcemanager.AzureResourceManager;
import com.azure.resourcemanager.compute.models.KnownLinuxVirtualMachineImage;
import com.azure.resourcemanager.compute.models.VirtualMachine;
import com.azure.resourcemanager.compute.models.VirtualMachineSizeTypes;
try {
TokenCredential credential = new EnvironmentCredentialBuilder()
.authorityHost(AzureAuthorityHosts.AZURE_PUBLIC_CLOUD)
.build();
// If you don't set the tenant ID and subscription ID via environment variables,
// change to create the Azure profile with tenantId, subscriptionId, and Azure environment.
AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
You'll see some REST requests and responses in the console as the SDK makes the underlying calls to the Azure
REST API to configure the VM and its resources. After the program finishes, verify the VM in your subscription
with the Azure CLI 2.0.
az vm list --resource-group sampleVmResourceGroup
After you've verified that the code worked, use the CLI to delete the VM and its resources.
// If you don't set the tenant ID and subscription ID via environment variables,
// change to create the Azure profile with tenantId, subscriptionId, and Azure environment.
AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
Remove the web app and plan from your subscription after you've verified the deployment.
az group delete --name sampleWebResourceGroup
// If you don't set the tenant ID and subscription ID via environment variables,
// change to create the Azure profile with tenantId, subscriptionId, and Azure environment.
AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE);
"encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;";
// Connect to the database, create a table, and insert an entry into it.
Connection conn = DriverManager.getConnection(url);
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println(e.getStackTrace().toString());
}
}
try {
TokenCredential tokenCredential = new EnvironmentCredentialBuilder()
.authorityHost(AzureAuthorityHosts.AZURE_PUBLIC_CLOUD)
.build();
// If you don't set the tenant ID and subscription ID via environment variables,
// change to create the Azure profile with tenantId, subscriptionId, and Azure environment.
AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
You can browse for the helloazure.txt file in your storage account through the Azure portal or with Azure
Storage Explorer.
Clean up the storage account by using the CLI.
This article provides links to the Java libraries, drivers, Spring modules, and related articles available for use with
Azure.
Microsoft’s goal is to empower every developer to achieve more, and our commitment to Java developers is no
exception. Java and Spring developers want to use idiomatic libraries to simplify connections to their preferred
cloud services. These libraries, drivers, and modules let you easily interact with Azure services across data,
messaging, cache, storage, eventing, directory, and secrets management. Use the following table to find the right
library, driver, or module and guides to get started.
Data SQL database SQL Database Use Java and Spring Data: Use Spring Data
JDBC driver JDBC with Azure • JDBC with Azure SQL
SQL Database • JPA Database:
• R2DBC • JDBC
• JPA
• R2DBC
Data MySQL MySQL JDBC Quickstart: Use Spring Data: Use Spring Data
driver Java and JDBC • JDBC with Azure
with Azure • JPA Database for
Database for • R2DBC MySQL:
MySQL • JDBC
• JPA
• R2DBC
Data PostgreSQL PostgreSQL Quickstart: Use Spring Data: Use Spring Data
JDBC driver Java and JDBC • JDBC with Azure
with Azure • JPA Database for
Database for • R2DBC PostgreSQL:
PostgreSQL • JDBC
Flexible Server • JPA
• R2DBC
Data MariaDB MariaDB driver MariaDB drivers Spring Data: Use Spring Data
and • JDBC with Azure
management • JPA Database for
tools compatible • R2DBC MySQL:
with Azure • JDBC
Database for • JPA
MariaDB • R2DBC
Data Cosmos DB - Maven Quickstart: Build Spring Data How to use the
SQL Repository: a Java app to Cosmos DB Spring Boot
com.azure » manage Azure Starter with the
azure-cosmos Cosmos DB SQL Azure Cosmos
API data DB SQL API
JAVA L IB RA RY JAVA GET T IN G SP RIN G GET T IN G
C AT EGO RY A Z URE SERVIC E O R DRIVER STA RT ED SP RIN G M O DUL E STA RT ED
Data Cosmos DB - Datastax Java Quickstart: Build Spring Data for How to use
Cassandra Driver for a Java app to Apache Spring Data
Apache manage Azure Cassandra Apache
Cassandra Cosmos DB Cassandra API
Cassandra API with Azure
data (v4 Driver) Cosmos DB
Cache Redis LETTUCE client Best Practices for • Spring Data Configure a
using Azure Redis Spring Boot
Cache for Redis • Reference Initializer app to
with Lettuce use Redis in the
cloud with Azure
Redis Cache
Messaging Service Bus JMS + AMQP Send messages Spring AMQP How to use
to an Azure Spring Boot
Service Bus topic Starter for Azure
and receive Service Bus JMS
messages from
subscriptions to
the topic
Messaging Service Bus Azure Service Azure Service Spring AMQP How to use
Bus client library Bus Samples Spring Cloud
for Java client library for Azure Stream
Java Binder for Azure
Service Bus
JAVA L IB RA RY JAVA GET T IN G SP RIN G GET T IN G
C AT EGO RY A Z URE SERVIC E O R DRIVER STA RT ED SP RIN G M O DUL E STA RT ED
Eventing Event Hubs Kafka Send and Receive Spring for How to use the
Messages in Java Apache Kafka Spring Boot
using Azure Starter for
Event Hubs for Apache Kafka
Apache Kafka with Azure Event
Ecosystems Hubs
Eventing Event Hubs Azure Event Use Java to send Spring Cloud How to create a
Hubs libraries for events to or Stream Binder for Spring Cloud
Java receive events Event Hubs Stream Binder
from Azure application with
Event Hubs Azure Event
Hubs
Directory Azure Active MSAL Enable Java Azure AD Spring Enable Spring
Directory Servlet apps to Boot Starter Boot Web apps
sign in users on to sign in users
Azure AD on Azure AD
Directory Azure Active MSAL Enable Java Azure AD B2C Enable Spring
Directory B2C Servlet apps to Spring Boot Boot Web apps
sign in users on Starter to sign in users
Azure AD B2C on Azure AD
B2C
Secrets Key Vault Key Vault Secrets Manage secrets Key Vault Secrets Manage secrets
using Key Vault Spring Boot for Spring Boot
Starter apps
Next steps
For all other libraries, see Azure SDK for Java libraries.
Use the Azure SDK for Java
2/16/2022 • 5 minutes to read • Edit Online
The open-source Azure SDK for Java simplifies provisioning, managing, and using Azure resources from Java
application code.
Important details
The Azure libraries are how you communicate with Azure services from Java code that you run either locally
or in the cloud.
The libraries support Java 8 and later, and are tested against both the Java 8 baseline and the latest Java
'long-term support' release.
The libraries include full Java module support, which means that they're fully compliant with the
requirements of a Java module and export all relevant packages for use.
The Azure SDK for Java is composed solely of many individual Java libraries that relate to specific Azure
services. There are no other tools in the "SDK".
There are distinct "management" and "client" libraries (sometimes referred to as "management plane" and
"data plane" libraries). Each set serves different purposes and is used by different kinds of code. For more
information, see the following sections later in this article:
Connect to and use Azure resources with client libraries.
Provision and manage Azure resources with management libraries.
You can find documentation for the libraries in the Azure for Java Reference organized by Azure Service, or
the Java API browser organized by package name.
Other details
The Azure SDK for Java libraries build on top of the underlying Azure REST API, allowing you to use those
APIs through familiar Java paradigms. However, you can always use the REST API directly from Java code, if
you prefer.
You can find the source code for the Azure libraries in the GitHub repository. As an open-source project,
contributions are welcome!
We're currently updating the Azure SDK for Java libraries to share common cloud patterns such as
authentication protocols, logging, tracing, transport protocols, buffered responses, and retries.
This shared functionality is contained in the azure-core library.
For more information on the guidelines we apply to the libraries, see the Java Azure SDK Design Guidelines.
The following code example shows how to create an asynchronous Key Vault KeyAsyncClient :
For more information on working with each client library, see the README.md file located in the library's project
directory in the SDK GitHub repository. You can also find more code snippets in the reference documentation
and the Azure Samples.
The following code example shows how to provision a new virtual machine:
The following code example shows how to get an existing virtual machine:
The following code example shows how to update the virtual machine and add a new data disk:
virtualMachine.update()
.withNewDataDisk(10)
.apply();
For more information on working with each management library, see the README.md file located in the
library's project directory in the SDK GitHub repository. You can also find more code snippets in the reference
documentation and the Azure Samples.
Next steps
Now that you understand what the Azure SDK for Java is, you can take a deep dive into many of the cross-
cutting concepts that exist to make you productive when using the libraries. The following articles provide good
starting points:
HTTP clients and pipelines
Asynchronous programming
Pagination and iteration
Long-running operations
Configure proxies
Configure tracing
HTTP clients and pipelines in the Azure SDK for
Java
2/16/2022 • 5 minutes to read • Edit Online
This article provides an overview of using the HTTP client and pipeline functionality within the Azure SDK for
Java. This functionality provides a consistent, powerful, and flexible experience for developers using all Azure
SDK for Java libraries.
HTTP clients
The Azure SDK for Java is implemented using an HttpClient abstraction. This abstraction enables a pluggable
architecture that accepts multiple HTTP client libraries or custom implementations. However, to simplify
dependency management for most users, all Azure client libraries depend on azure-core-http-netty . As such,
the Netty HTTP client is the default client used in all Azure SDK for Java libraries.
Although Netty is the default HTTP client, the SDK provides three client implementations, depending on which
dependencies you already have in your project. These implementations are for:
Netty
OkHttp
The new HttpClient introduced in JDK 11
Replace the default HTTP client
If you prefer another implementation, you can remove the dependency on Netty by excluding it in the build
configuration files. In a Maven pom.xml file, you exclude the Netty dependency and include another dependency.
The following example shows you how to exclude the Netty dependency from a real dependency on the
azure-security-keyvault-secrets library. Be sure to exclude Netty from all appropriate com.azure libraries, as
shown here:
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-secrets</artifactId>
<version>4.2.2.</version>
<exclusions>
<exclusion>
<groupId>com.azure</groupId>
<artifactId>azure-core-http-netty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-core-http-okhttp</artifactId>
<version>1.3.3</version>
</dependency>
NOTE
If you remove the Netty dependency but provide no implementation in its place, the application will fail to start. An
HttpClient implementation must exist on the classpath.
The following examples show how to build HttpClient instances using Netty, OkHttp, and the JDK 11 HTTP
client. These instances proxy through http://localhost:3128 and authenticate with user example with password
weakPassword.
// Netty
HttpClient httpClient = new NettyAsyncHttpClientBuilder()
.proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost", 3128))
.setCredentials("example", "weakPassword"))
.build();
// OkHttp
HttpClient httpClient = new OkHttpAsyncHttpClientBuilder()
.proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost", 3128))
.setCredentials("example", "weakPassword"))
.build();
// JDK 11 HttpClient
HttpClient client = new JdkAsyncHttpClientBuilder()
.proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost", 3128))
.setCredentials("example", "weakPassword"))
.build();
You can now pass the constructed HttpClient instance into a service client builder for use as the client for
communicating with the service. The following example uses the new HttpClient instance to build an Azure
Storage Blob client.
For management libraries, you can set the HttpClient during Manager configuration.
HTTP pipeline
The HTTP pipeline is one of the key components in achieving consistency and diagnosability in the Java client
libraries for Azure. An HTTP pipeline is composed of:
An HTTP transport
HTTP pipeline policies
You can provide your own custom HTTP pipeline when creating a client. If you don't provide a pipeline, the client
library will create one configured to work with that specific client library.
HTTP transport
The HTTP transport is responsible for establishing the connection to the server, and sending and receiving HTTP
messages. The HTTP transport forms the gateway for the Azure SDK client libraries to interact with Azure
services. As noted earlier in this article, the Azure SDK for Java uses Netty by default for its HTTP transport.
However, the SDK also provides a pluggable HTTP transport so you can use other implementations where
appropriate. The SDK also provides two more HTTP transport implementations for OkHttp and the HTTP client
that ships with JDK 11 and later.
HTTP pipeline policies
A pipeline consists of a sequence of steps executed for each HTTP request-response roundtrip. Each policy has a
dedicated purpose and will act on a request or a response or sometimes both. Because all client libraries have a
standard 'Azure Core' layer, this layer ensures that each policy executes in order in the pipeline. When you send
a request, the policies execute in the order that they're added to the pipeline. When you receive a response from
the service, the policies execute in the reverse order. All policies added to the pipeline execute before you send
the request and after you receive a response. The policy has to decide whether to act on the request, the
response, or both. For example, a logging policy will log the request and response but the authentication policy
is only interested in modifying the request.
The Azure Core framework will provide the policy with the necessary request and response data along with any
necessary context to execute the policy. The policy can then perform its operation with the given data and pass
the control along to the next policy in the pipeline.
P O L IC Y GIT H UB L IN K
Next steps
Now that you're familiar with HTTP client functionality in the Azure SDK for Java, see Configure proxies in the
Azure SDK for Java to learn how to further customize the HTTP client you're using.
Asynchronous programming in the Azure SDK for
Java
2/16/2022 • 10 minutes to read • Edit Online
This article describes the asynchronous programming model in the Azure SDK for Java.
The Azure SDK initially contained only non-blocking, asynchronous APIs for interacting with Azure services.
These APIs let you use the Azure SDK to build scalable applications that use system resources efficiently.
However, the Azure SDK for Java also contains synchronous clients to cater to a wider audience, and also make
our client libraries approachable for users not familiar with asynchronous programming. (See Approachable in
the Azure SDK design guidelines.) As such, all Java client libraries in the Azure SDK for Java offer both
asynchronous and synchronous clients. However, we recommend using the asynchronous clients for production
systems to maximize the use of system resources.
Reactive streams
If you look at the Async Service Clients section in the Java Azure SDK Design Guidelines, you'll notice that,
instead of using CompletableFuture provided by Java 8, our async APIs use reactive types. Why did we choose
reactive types over types that are natively available in JDK?
Java 8 introduced features like Streams, Lambdas, and CompletableFuture. These features provide many
capabilities, but have some limitations.
CompletableFuture provides callback-based, non-blocking capabilities, and the CompletionStage interface
allowed for easy composition of a series of asynchronous operations. Lambdas make these push-based APIs
more readable. Streams provide functional-style operations to handle a collection of data elements. However,
streams are synchronous and can't be reused. CompletableFuture allows you to make a single request, provides
support for a callback, and expects a single response. However, many cloud services require the ability to stream
data - Event Hubs for instance.
Reactive streams can help to overcome these limitations by streaming elements from a source to a subscriber.
When a subscriber requests data from a source, the source sends any number of results back. It doesn't need to
send them all at once. The transfer happens over a period of time, whenever the source has data to send.
In this model, the subscriber registers event handlers to process data when it arrives. These push-based
interactions notify the subscriber through distinct signals:
An onSubscribe() call indicates that the data transfer is about to begin.
An onError() call indicates there was an error, which also marks the end of data transfer.
An onComplete() call indicates successful completion of data transfer.
Unlike Java Streams, reactive streams treat errors as first-class events. Reactive streams have a dedicated
channel for the source to communicate any errors to the subscriber. Also, reactive streams allow the subscriber
to negotiate the data transfer rate to transform these streams into a push-pull model.
The Reactive Streams specification provides a standard for how the transfer of data should occur. At a high level,
the specification defines the following four interfaces and specifies rules on how these interfaces should be
implemented.
Publisher is the source of a data stream.
Subscriber is the consumer of a data stream.
Subscription manages the state of data transfer between a publisher and a subscriber.
Processor is both a publisher and a subscriber.
There are some well-known Java libraries that provide implementations of this specification, such as RxJava,
Akka Streams, Vert.x, and Project Reactor.
The Azure SDK for Java adopted Project Reactor to offer its async APIs. The main factor driving this decision was
to provide smooth integration with Spring Webflux, which also uses Project Reactor. Another contributing factor
to choose Project Reactor over RxJava was that Project Reactor uses Java 8 but RxJava, at the time, was still at
Java 7. Project Reactor also offers a rich set of operators that are composable and allow you to write declarative
code for building data processing pipelines. Another nice thing about Project Reactor is that it has adapters for
converting Project Reactor types to other popular implementation types.
For the sake of completeness, it's worth mentioning that Java 9 introduced the Flow class that includes the four
reactive streams interfaces. However, this class doesn't include any implementation.
System.out.println("Done");
Notice that after calling getConfigurationSetting() on the client, the example code subscribes to the result and
provides three separate lambdas. The first lambda consumes data received from the service, which is triggered
upon successful response. The second lambda is triggered if there is an error while retrieving the configuration.
The third lambda is invoked when the data stream is complete, meaning no more data elements are expected
from this stream.
NOTE
As with all asynchronous programming, after the subscription is created, execution proceeds as usual. If there's nothing to
keep the program active and executing, it may terminate before the async operation completes. The main thread that
called subscribe() won't wait until you make the network call to Azure App Configuration and receive a response. In
production systems, you might continue to process something else, but in this example you can add a small delay by
calling Thread.sleep() or use a CountDownLatch to give the async operation a chance to complete.
As shown in the following example, APIs that return a Flux also follow a similar pattern. The difference is that
the first callback provided to the subscribe() method is called multiple times for each data element in the
response. The error or the completion callbacks are called exactly once and are considered as terminal signals.
No other callbacks are invoked if either of these signals are received from the publisher.
asyncClient.receive().subscribe(
event -> System.out.println("Sequence number of received event: " +
event.getData().getSequenceNumber()),
ex -> System.out.println("Error receiving events: " + ex.getMessage()),
() -> System.out.println("Successfully completed receiving all events"));
Backpressure
What happens when the source is producing the data at a faster rate than the subscriber can handle? The
subscriber can get overwhelmed with data, which can lead to out-of-memory errors. The subscriber needs a way
to communicate back to the publisher to slow down when it can't keep up. By default, when you call
subscribe() on a Flux as shown in the example above, the subscriber is requesting an unbounded stream of
data, indicating to the publisher to send the data as quickly as possible. This behavior isn't always desirable, and
the subscriber may have to control the rate of publishing through "backpressure". Backpressure allows the
subscriber to take control of the flow of data elements. A subscriber will request a limited number of data
elements that they can handle. After the subscriber has completed processing these elements, the subscriber can
request more. By using backpressure, you can transform a push-model for data transfer into a push-pull model.
The following example shows how you can control the rate at which events are received by the Event Hubs
consumer:
asyncClient.receive().subscribe(new Subscriber<PartitionEvent>() {
private Subscription subscription;
@Override
public void onSubscribe(Subscription subscription) {
this.subscription = subscription;
this.subscription.request(1); // request 1 data element to begin with
}
@Override
public void onNext(PartitionEvent partitionEvent) {
System.out.println("Sequence number of received event: " +
partitionEvent.getData().getSequenceNumber());
this.subscription.request(1); // request another event when the subscriber is ready
}
@Override
public void onError(Throwable throwable) {
System.out.println("Error receiving events: " + throwable.getMessage());
}
@Override
public void onComplete() {
System.out.println("Successfully completed receiving all events")
}
});
When the subscriber first "connects" to the publisher, the publisher hands the subscriber a Subscription
instance, which manages the state of the data transfer. This Subscription is the medium through which the
subscriber can apply backpressure by calling request() to specify how many more data elements it can handle.
If the subscriber requests more than one data element each time it calls onNext() , request(10) for example, the
publisher will send the next 10 elements immediately if they're available or when they become available. These
elements accumulate in a buffer on the subscriber's end, and since each onNext() call will request 10 more, the
backlog keeps growing until either the publisher has no more data elements to send, or the subscriber's buffer
overflows, resulting in out-of-memory errors.
Cancel a subscription
A subscription manages the state of data transfer between a publisher and a subscriber. The subscription is
active until the publisher has completed transferring all the data to the subscriber or the subscriber is no longer
interested in receiving data. There are a couple of ways you can cancel a subscription as shown below.
The following example cancels the subscription by disposing the subscriber:
EventHubConsumerAsyncClient asyncClient = new EventHubClientBuilder()
.connectionString("<your connection string>")
.consumerGroup("<your consumer group>")
.buildAsyncConsumerClient();
// much later on in your code, when you are ready to cancel the subscription,
// you can call the dispose method, as such:
disposable.dispose();
The follow example cancels the subscription by calling the cancel() method on Subscription :
asyncClient.receive().subscribe(new Subscriber<PartitionEvent>() {
private Subscription subscription;
@Override
public void onSubscribe(Subscription subscription) {
this.subscription = subscription;
this.subscription.request(1); // request 1 data element to begin with
}
@Override
public void onNext(PartitionEvent partitionEvent) {
System.out.println("Sequence number of received event: " +
partitionEvent.getData().getSequenceNumber());
this.subscription.cancel(); // Cancels the subscription. No further event is received.
}
@Override
public void onError(Throwable throwable) {
System.out.println("Error receiving events: " + throwable.getMessage());
}
@Override
public void onComplete() {
System.out.println("Successfully completed receiving all events")
}
});
Conclusion
Threads are expensive resources that you shouldn't waste on waiting for responses from remote service calls. As
the adoption of microservices architectures increase, the need to scale and use resources efficiently becomes
vital. Asynchronous APIs are favorable when there are network-bound operations. The Azure SDK for Java offers
a rich set of APIs for async operations to help maximize your system resources. We highly encourage you to try
out our async clients.
For more information on the operators that best suit your particular tasks, see Which operator do I need? in the
Reactor 3 Reference Guide.
Next steps
Now that you better understand the various asynchronous programming concepts, it's important to learn how
to iterate over the results. For more information on the best iteration strategies, and details of how pagination
works, see Pagination and iteration in the Azure SDK for Java.
Pagination and iteration in the Azure SDK for Java
2/16/2022 • 4 minutes to read • Edit Online
This article provides an overview of how to use the Azure SDK for Java pagination and iteration functionality to
work efficiently and productively with large data sets.
Many operations provided by the client libraries within the Azure Java SDK return more than one result. The
Azure Java SDK defines a set of acceptable return types in these cases to ensure that developer experience is
maximized through consistency. The return types used are PagedIterable for sync APIs and PagedFlux for
async APIs. The APIs differ slightly on account of their different use cases, but conceptually they have the same
requirements:
Make it possible to easily iterate over each element in the collection individually, ignoring any need for
manual pagination or tracking of continuation tokens. Both PagedIterable and PagedFlux make this task
easy by iterating over a paginated response deserialized into a given type T . PagedIterable implements
the Iterable interface, and offers an API to receive a Stream , while PagedFlux provides a Flux . In all
cases, the act of pagination is transparent, and iteration continues while there are still results iterate over.
Make it possible to iterate explicitly page-by-page. Doing so lets you understand more clearly when
requests are made, and lets you access per-page response information. Both PagedIterable and
PagedFlux have methods that will return appropriate types to iterate by page, rather than by individual
element.
This article is split between the Java Azure SDK synchronous and asynchronous APIs. You'll see the synchronous
iteration APIs when you work with synchronous clients, and asynchronous iteration APIs when you work with
asynchronous clients.
Use Stream
Because PagedIterable has a stream() method defined on it, you can call it to use the standard Java Stream
APIs, as shown in the following example:
client.listSecrets()
.stream()
.forEach(secret -> System.out.println("Secret is: " + secret));
Use Iterator
Because PagedIterable implements Iterable , it also has an iterator() method to allow for the Java iterator
programming style, as show in the following example:
There's also an iterableByPage overload that accepts a continuation token. You can call this overload when you
want to return to the same point of iteration at a later time.
Use Stream
The following example shows how the streamByPage() method performs the same operation as shown above.
This API also has a continuation token overload for returning to the same point of iteration at a later time.
client.listSecrets()
.streamByPage()
.forEach(page -> {
System.out.println("Response code: " + page.getStatusCode());
System.out.println("Continuation Token: " + page.getContinuationToken());
page.getElements().forEach(secret -> System.out.println("Secret value: " + secret))
});
asyncClient.listSecrets()
.subscribe(secret -> System.out.println("Secret value: " + secret),
ex -> System.out.println("Error listing secrets: " + ex.getMessage()),
() -> System.out.println("Successfully listed all secrets"));
Observe pages
The following example shows how the PagedFlux API lets you observe each page asynchronously, again by
using a byPage() API and by providing a consumer, error consumer, and a completion consumer.
asyncClient.listSecrets().byPage()
.subscribe(page -> {
System.out.println("Response code: " + page.getStatusCode());
System.out.println("Continuation Token: " + page.getContinuationToken());
page.getElements().forEach(secret -> System.out.println("Secret value: " + secret))
},
ex -> System.out.println("Error listing pages with secret: " + ex.getMessage()),
() -> System.out.println("Successfully listed all pages with secret"));
Next steps
Now that you're familiar with pagination and iteration in the Azure SDK for Java, consider reviewing Long-
running operations in the Azure SDK for Java. Long-running operations are operations that run for a longer
duration than most normal HTTP requests, typically because they require some effort on the server side.
Long-running operations in the Azure SDK for Java
2/16/2022 • 4 minutes to read • Edit Online
This article provides an overview of using long-running operations with the Azure SDK for Java.
Certain operations on Azure may take extended amounts of time to complete. These operations are outside the
standard HTTP style of quick request / response flow. For example, copying data from a source URL to a Storage
blob, or training a model to recognize forms, are operations that may take a few seconds to several minutes.
Such operations are referred to as Long-Running Operations, and are often abbreviated as 'LRO'. An LRO may
take seconds, minutes, hours, days, or longer to complete, depending on the operation requested and the
process that must be performed on the server side.
In the Java client libraries for Azure, a convention exists that all long-running operations begin with the begin
prefix. This prefix indicates that this operation is long-running, and that the means of interaction with this
operation is slightly different that the usual request / response flow. Along with the begin prefix, the return type
from the operation is also different than usual, to enable the full range of long-running operation functionality.
As with most things in the Azure SDK for Java, there are both synchronous and asynchronous APIs for long-
running operations:
In synchronous clients, long-running operations will return a SyncPoller instance.
In asynchronous clients, long-running operations will return a PollerFlux instance.
Both SyncPoller and PollerFlux are the client-side abstractions intended to simplify the interaction with long-
running server-side operations. The rest of this article outlines best practices when working with these types.
do {
response = poller.poll();
System.out.println("Status of long running upload operation: " + response.getStatus());
Duration pollInterval = response.getRetryAfter();
TimeUnit.MILLISECONDS.sleep(pollInterval.toMillis());
} while (!response.getStatus().isComplete());
This example uses the poll() method on the SyncPoller to retrieve information on progress of the long-
running operation. This code prints the status to the console, but a better implementation would make relevant
decisions based on this status.
The getRetryAfter() method returns information about how long to wait before the next poll. Most Azure long-
running operations return the poll delay as part of their HTTP response (that is, the commonly used
retry-after header). If the response doesn't contain the poll delay, then the getRetryAfter() method returns
the duration given at the time of invoking the long-running operation.
The example above uses a do..while loop to repeatedly poll until the long-running operation is complete. If
you aren't interested in these intermediate results, you can instead call waitForCompletion() . This call will block
the current thread until the long-running operation completes and returns the last poll response:
If the last poll response indicates that the long-running operation has completed successfully, you can retrieve
the final result using getFinalResult() :
if (LongRunningOperationStatus.SUCCESSFULLY_COMPLETED == response.getStatus()) {
UploadedBlobProperties result = poller.getFinalResult();
}
asyncClient.beginUploadFromUri(...)
.subscribe(response -> System.out.println("Status of long running upload operation: " +
response.getStatus()));
In the following example, you'll get intermittent status updates on the long-running operation. You can use these
updates to determine whether the long-running operation is still operating in the expected fashion. This
example prints the status to the console, but a better implementation would make relevant error handling
decisions based on this status.
If you aren't interested in the intermediate status updates and just want to get notified of the final result when it
arrives, you can use code similar to the following example:
asyncClient.beginUploadFromUri(...)
.last()
.flatMap(response -> {
if (LongRunningOperationStatus.SUCCESSFULLY_COMPLETED == response.getStatus()) {
return response.getFinalResult();
}
return Mono.error(new IllegalStateException("Polling completed unsuccessfully with status: "+
response.getStatus()));
})
.subscribe(
finalResult -> processFormPages(finalResult),
ex -> countDownLatch.countDown(),
() -> countDownLatch.countDown());
In this code, you retrieve the final result of the long-running operation by calling last() . This call tells the
PollerFlux that you want to wait for all the polling to complete, at which point the long-running operation has
reached a terminal state, and you can inspect its status to determine the outcome. If the poller indicates that the
long-running operation has completed successfully, you can retrieve the final result and pass it on to the
consumer in the subscribe call.
Next steps
Now that you're familiar with the long-running APIs in the Azure SDK for Java, see Configure proxies in the
Azure SDK for Java to learn how to customize the HTTP client further.
Configure proxies in the Azure SDK for Java
2/16/2022 • 3 minutes to read • Edit Online
This article provides an overview of how to configure the Azure SDK for Java to make proper use of proxies.
The * represents the well-known Java proxy properties. For more information, see Java Networking and
Proxies in the Oracle documentation.
If the builder finds any of the environment configurations, it creates a instance by calling
ProxyOptions
ProxyOptions.fromConfiguration(Configuration.getGlobalConfiguration()) . This article provides more details
below about the ProxyOptions type.
IMPORTANT
To use any proxy configuration, Java requires you to set the system environment property java.net.useSystemProxies
to true .
You can also create an HTTP client instance that doesn't use any proxy configuration present in the system
environment variables. To override the default behavior, you explicitly set a differently-configured
Configuration in the HTTP client builder. When you set a Configuration in the builder, it will no longer call
Configuration.getGlobalConfiguration() . For example, if you call configuration(Configuration) using
Configuration.NONE , you can explicitly prevent the builder from inspecting the environment for configuration.
The following example uses the HTTP_PROXY environment variable with value localhost:8888 to use Fiddler as
the proxy. This code demonstrates creating a Netty and an OkHttp HTTP client. (For more information on HTTP
client configuration, see HTTP clients and pipelines.)
export HTTP_PROXY=localhost:8888
To prevent the environment proxy from being used, configure the HTTP client builder with Configuration.NONE ,
as shown in the following example:
The following example uses the http.proxy* configurations set in a Configuration object to use a proxy that
authenticates Fiddler as the proxy.
The following example creates an authenticated ProxyOptions that proxies requests to a Fiddler instance
requiring proxy authentication:
// Fiddler uses username "1" and password "1" with basic authentication as its proxy authentication
requirement.
ProxyOptions proxyOptions = new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost",
8888))
.setCredentials("1", "1");
You can configure HTTP client builders with ProxyOptions directly to indicate an explicit proxy to use. This
configuration is the most granular way to provide a proxy, and generally isn't as flexible as passing a
Configuration that you can mutate to update proxying requirements.
Next steps
Now that you're familiar with proxy configuration in the Azure SDK for Java, see Configure tracing in the Azure
SDK for Java to better understand flows within your application, and to help diagnose issues.
Configure tracing in the Azure SDK for Java
2/16/2022 • 2 minutes to read • Edit Online
This article provides an overview of how to configure the Azure SDK for Java to integrate tracing functionality.
You can enable tracing in Azure client libraries by using and configuring the OpenTelemetry SDK or using an
OpenTelemetry-compatible agent. OpenTelemetry is a popular open-source observability framework for
generating, capturing, and collecting telemetry data for cloud-native software.
There are two key concepts related to tracing: span and trace . A span represents a single operation in a trace. A
span can represent an HTTP request, a remote procedure call (RPC), a database query, or even the path that your
code takes. A trace is a tree of spans showing the path of work through a system. You can distinguish a trace on
its own by a unique 16-byte sequence called a TraceID. For more information on these concepts and how they
relate to OpenTelemetry, see the OpenTelemetry documentation.
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-core-tracing-opentelemetry</artifactId>
<version>{latest version}</version>
</dependency>
If you use an OpenTelemetry agent, that's all you have to do to start getting spans from Azure SDKs. For more
details on how to configure exporters, add manual instrumentation, or enrich telemetry, see OpenTelemetry
Instrumentation for Java.
Manually instrument the application with OpenTelemetry SDK
If you use OpenTelemetry SDK directly, make sure to configure SDK and exporter for the backend of your choice.
For more information, see OpenTelemetry documentation.
If you run the application now, you should get Azure SDK spans on your backend. However with asynchronous
calls, the correlation between Azure SDK and application spans may be broken.
By default, Azure SDK uses io.opentelemetry.context.Context.current() , implicitly propagated by
OpenTelemetry, as a parent to new spans. In asynchronous calls, implicit context propagation breaks.
OpenTelemetry agents solve this problem by helping context propagate, but the OpenTelemetry SDK doesn't
have such capabilities.
Pass trace context explicitly
Azure SDK allows passing trace context explicitly through com.azure.core.util.Context under the
trace-context key. When you provide explicit trace context, Azure SDK uses it instead of the implicit one, which
enables correlation between application and Azure SDK spans.
In the following example, when an incoming web request is traced manually, the Application Configuration
Client Library is called asynchronously in the scope of this request.
// Put the incoming-request span (wrapped into the OpenTelemetry Context) into the Azure SDK Context
// and pass it over to the Application Configuration call.
appConfigClient.setConfigurationSettingWithResponse(settings, true, new com.azure.core.util.Context("trace-
context", traceContext));
// You could also pass the context using the reactor `contextWrite` method under the same `trace-context`
key.
appConfigAsyncClient.setConfigurationSettingWithResponse(settings)
.contextWrite(reactor.util.context.Context.of("trace-context", traceContext))
//...
Next steps
Now that you're familiar with the core cross-cutting functionality in the Azure SDK for Java, see Azure
authentication with Java and Azure Identity to learn how you can create secure applications.
Azure authentication with Java and Azure Identity
2/16/2022 • 4 minutes to read • Edit Online
This article provides an overview of the Java Azure Identity library, which provides Azure Active Directory token
authentication support across the Azure SDK for Java. This library provides a set of TokenCredential
implementations that you can use to construct Azure SDK clients that support AAD token authentication.
The Azure Identity library currently supports:
Azure authentication in Java development environments, which enables:
IDEA IntelliJ authentication, with the login information retrieved from the Azure Toolkit for IntelliJ.
Visual Studio Code authentication, with the login information saved in Azure plugin for Visual Studio
Code.
Azure CLI authentication, with the login information saved in the Azure CLI
Authenticating applications hosted in Azure, which enables:
Default Azure Credential Authentication
Managed Identity Authentication
Authentication with service principals, which enables:
Client Secret Authentication
Client Certificate Authentication
Authentication with user credentials, which enables:
Interactive browser authentication
Device code authentication
Username/password authentication
Follow the links above to learn more about the specifics of each of these authentication approaches. In the rest
of this article, we'll introduce the commonly used DefaultAzureCredential and related topics.
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.2.1</version>
</dependency>
Key concepts
There are two key concepts in understanding the Azure Identity library: the concept of a credential, and the most
common implementation of that credential, the DefaultAzureCredential .
A credential is a class that contains or can obtain the data needed for a service client to authenticate requests.
Service clients across the Azure SDK accept credentials when they're constructed, and service clients use those
credentials to authenticate requests to the service.
The Azure Identity library focuses on OAuth authentication with Azure Active Directory, and it offers various
credential classes that can acquire an AAD token to authenticate service requests. All of the credential classes in
this library are implementations of the TokenCredential abstract class in azure-core, and you can use any of
them to construct service clients that can authenticate with a TokenCredential .
The DefaultAzureCredential is appropriate for most scenarios where the application is intended to ultimately
run in the Azure Cloud. DefaultAzureCredential combines credentials that are commonly used to authenticate
when deployed, with credentials that are used to authenticate in a development environment. For more
information, including examples using DefaultAzureCredential , see the Default Azure credential section of
Authenticating Azure-hosted Java applications.
Examples
As noted in Use the Azure SDK for Java, the management libraries differ slightly. One of the ways they differ is
that there are libraries for consuming Azure services, called client libraries, and libraries for managing Azure
services, called management libraries. In the following sections, there's a quick overview of authenticating in
both client and management libraries.
Authenticate Azure client libraries
The following example below demonstrates authenticating the SecretClient from the azure-security-keyvault-
secrets client library using the DefaultAzureCredential .
You can set the subscription ID in the AZURE_SUBSCRIPTION_ID environment variable. This ID is picked up by
AzureProfile as the default subscription ID during the creation of a Manager instance, as shown in the
following example:
The DefaultAzureCredential used in this example authenticates an AzureResourceManager instance using the
DefaultAzureCredential . You can also use other Token Credential implementations offered in the Azure Identity
library in place of DefaultAzureCredential .
Troubleshooting
Credentials raise exceptions either when they fail to authenticate or can't execute authentication. When
credentials fail to authenticate, the ClientAuthenticationException is raised and it has a message attribute that
describes why authentication failed. When ChainedTokenCredential raises this exception, the chained execution
of underlying list of credentials is stopped.
When credentials can't execute authentication because one of the underlying resources required by the
credential is unavailable on the machine, the CredentialUnavailableException is raised and it has a message
attribute that describes why the credential is unavailable for authentication execution. When
ChainedTokenCredential raises this exception, the message collects error messages from each credential in the
chain.
Next steps
This article introduced the Azure Identity functionality available in the Azure SDK for Java. It described the
DefaultAzureCredential as common and appropriate in many cases. The following articles describe other ways
to authenticate using the Azure Identity library, and provide more information about the
DefaultAzureCredential :
This article provides an overview of the Azure Identity library support for Azure Active Directory token
authentication. This support enables authentication for applications running locally on developer machines
through a set of TokenCredential implementations.
Topics covered in this article include:
Device code credential
Interactive browser credential
Azure CLI credential
IntelliJ credential
Visual Studio Code credential
az login
If the account or service principal has access to multiple tenants, make sure the desired tenant or subscription is
in the state "Enabled" in the output from the following command:
az account list
Before you use AzureCliCredential in code, run the following command to verify that the account has been
successfully configured.
az account get-access-token
You may need to repeat this process after a certain time period, depending on the refresh token validity in your
organization. Generally, the refresh token validity period is a few weeks to a few months. AzureCliCredential
will prompt you to sign in again.
Authenticate a user account with Azure CLI
The following example demonstrates authenticating the SecretClient from the azure-security-keyvault-secrets
client library using the AzureCliCredential on a workstation with Azure CLI installed and signed in.
IntelliJ credential
The IntelliJ credential authenticates in a development environment with the account in Azure Toolkit for IntelliJ. It
uses the logged in user information on the IntelliJ IDE and uses it to authenticate the application against Azure
Active Directory.
Next steps
This article covered authentication during development using credentials available on your computer. This form
of authentication is one of multiple ways you can authenticate in the Azure SDK for Java. The following articles
describe other ways:
Authenticating applications hosted in Azure
Authentication with service principals
Authentication with user credentials
After you've mastered authentication, see Configure logging in the Azure SDK for Java for information on the
logging functionality provided by the SDK.
Authenticate Azure-hosted Java applications
2/16/2022 • 4 minutes to read • Edit Online
This article looks at how the Azure Identity library supports Azure Active Directory token authentication for
applications hosted on Azure. This support is made possible through a set of TokenCredential implementations,
which are discussed below.
This article covers the following topics:
Default Azure credential
Managed Identity credential
Environment - The DefaultAzureCredential will read account information specified via environment variables
and use it to authenticate.
Managed Identity - If the application deploys to an Azure host with Managed Identity enabled, the
DefaultAzureCredential will authenticate with that account.
IntelliJ - If you've authenticated via Azure Toolkit for IntelliJ, the DefaultAzureCredential will authenticate with
that account.
Visual Studio Code - If you've authenticated via the Visual Studio Code Azure Account plugin, the
DefaultAzureCredential will authenticate with that account.
Azure CLI - If you've authenticated an account via the Azure CLI az login command, the
DefaultAzureCredential will authenticate with that account.
Configure DefaultAzureCredential
DefaultAzureCredential supports a set of configurations through setters on the DefaultAzureCredentialBuilder
or environment variables.
Setting the environment variables AZURE_CLIENT_ID , AZURE_CLIENT_SECRET , and AZURE_TENANT_ID as defined in
Environment variables configures the DefaultAzureCredential to authenticate as the service principal
specified by the values.
Setting .managedIdentityClientId(String) on the builder or the environment variable AZURE_CLIENT_ID
configures the DefaultAzureCredential to authenticate as a user-defined managed identity, while leaving
them empty configures it to authenticate as a system-assigned managed identity.
Setting .tenantId(String) on the builder or the environment variable AZURE_TENANT_ID configures the
DefaultAzureCredential to authenticate to a specific tenant for shared token cache, Visual Studio Code, and
IntelliJ IDEA.
Setting the environment variable AZURE_USERNAME configures the DefaultAzureCredential to pick the
corresponding cached token from the shared token cache.
Setting .intelliJKeePassDatabasePath(String) on the builder configures the DefaultAzureCredential to read
a specific KeePass file when authenticating with IntelliJ credentials.
Authenticate with DefaultAzureCredential
The following example demonstrates authenticating the SecretClient from the azure-security-keyvault-secrets
client library using the DefaultAzureCredential .
/**
* The default credential will use the user-assigned managed identity with the specified client ID.
*/
DefaultAzureCredential defaultCredential = new DefaultAzureCredentialBuilder()
.managedIdentityClientId("<managed identity client ID>")
.build();
/**
* The default credential will use the KeePass database path to find the user account in IntelliJ on
Windows.
*/
// KeePass configuration is required only for Windows. No configuration needed for Linux / Mac.
DefaultAzureCredential defaultCredential = new DefaultAzureCredentialBuilder()
.intelliJKeePassDatabasePath("C:\\Users\\user\\AppData\\Roaming\\JetBrains\\IdeaIC2020.1\\c.kdbx")
.build();
/**
* Authenticate with a managed identity.
*/
ManagedIdentityCredential managedIdentityCredential = new ManagedIdentityCredentialBuilder()
.clientId("<user-assigned managed identity client ID>") // required only for user-assigned
.build();
Environment variables
You can configure DefaultAzureCredential and EnvironmentCredential with environment variables. Each type of
authentication requires values for specific variables:
Service principal with secret
VA RIA B L E N A M E VA L UE
Configuration is attempted in the above order. For example, if values for a client secret and certificate are both
present, the client secret is used.
Next steps
This article covered authentication for applications hosted in Azure. This form of authentication is one of
multiple ways you can authenticate in the Azure SDK for Java. The following articles describe other ways:
Azure authentication in development environments
Authentication with service principals
Authentication with user credentials
After you've mastered authentication, see Configure logging in the Azure SDK for Java for information on the
logging functionality provided by the SDK.
Azure authentication with service principal
2/16/2022 • 2 minutes to read • Edit Online
This article looks at how the Azure Identity library supports Azure Active Directory token authentication via
service principal. Topics covered in this article include:
Create a service principal with the Azure CLI
Client secret credential
Client certificate credential
For more information, see Application and service principal objects in Azure Active Directory.
{
"appId": "generated-app-ID",
"displayName": "dummy-app-name",
"name": "http://dummy-app-name",
"password": "random-password",
"tenant": "tenant-ID"
}
Use the following command to create a service principal along with a certificate. Note down the path/location of
this certificate.
az ad sp create-for-rbac -n <your application name> --role Contributor --cert <certificate name> --create-
cert
Check the returned credentials and to note down the following information:
AZURE\_CLIENT\_ID for the appId.
AZURE\_CLIENT\_SECRET for the password.
AZURE\_TENANT\_ID for the tenant.
/**
* Authenticate with a client certificate.
*/
ClientCertificateCredential clientCertificateCredential = new ClientCertificateCredentialBuilder()
.clientId("<your client ID>")
.pemCertificate("<path to PEM certificate>")
// Choose between either a PEM certificate or a PFX certificate.
//.pfxCertificate("<path to PFX certificate>", "PFX CERTIFICATE PASSWORD")
.tenantId("<your tenant ID>")
.build();
Next steps
This article covered authentication via service principal. This form of authentication is one of multiple ways you
can authenticate in the Azure SDK for Java. The following articles describe other ways:
Azure authentication in development environments
Authenticating applications hosted in Azure
Authentication with User Credentials
After you've mastered authentication, see Configure logging in the Azure SDK for Java for information on the
logging functionality provided by the SDK.
Azure authentication with user credentials
2/16/2022 • 3 minutes to read • Edit Online
This article looks at how the Azure Identity library supports Azure Active Directory token authentication with
user-provided credentials. This support is made possible through a set of TokenCredential implementations
discussed below.
This article covers the following topics:
Device code credential
Interactive browser credential
Username password credential
These steps will let the application authenticate, but it still won't have permission to log you into Active
Directory, or access resources on your behalf. To address this issue, navigate to API Permissions , and enable
Microsoft Graph and the resources you want to access, such as Azure Service Management, Key Vault, and so
on.
You also need to be the admin of your tenant to grant consent to your application when you log in for the first
time.
If you can't configure the device code flow option on your Active Directory, then it may require your app to be
multi- tenant. To make your app multi-tenant, navigate to the Authentication panel, then select Accounts in
any organizational director y . Then, select yes for Treat application as Public Client .
Authenticate a user account with device code flow
The following example demonstrates authenticating the SecretClient from the Azure Key Vault Secret client
library for Java using the DeviceCodeCredential on an IoT device.
/**
* Authenticate with device code credential.
*/
DeviceCodeCredential deviceCodeCredential = new DeviceCodeCredentialBuilder()
.challengeConsumer(challenge -> {
// Lets the user know about the challenge.
System.out.println(challenge.getMessage());
}).build();
/**
* Authenticate interactively in the browser.
*/
InteractiveBrowserCredential interactiveBrowserCredential = new InteractiveBrowserCredentialBuilder()
.clientId("<your app client ID>")
.redirectUrl("YOUR_APP_REGISTERED_REDIRECT_URL")
.build();
For more information, see Microsoft identity platform and OAuth 2.0 Resource Owner Password Credentials.
Next steps
This article covered authentication with user credentials. This form of authentication is one of multiple ways you
can authenticate in the Azure SDK for Java. The following articles describe other ways:
Azure authentication in development environments
Authenticating applications hosted in Azure
Authentication with service principals
After you've mastered authentication, see Configure logging in the Azure SDK for Java for information on the
logging functionality provided by the SDK.
Configure logging in the Azure SDK for Java
2/16/2022 • 2 minutes to read • Edit Online
This article provides an overview of how to enable logging in applications that make use of the Azure SDK for
Java. The Azure client libraries for Java have two logging options:
A built-in logging framework for temporary debugging purposes.
Support for logging using the SLF4J interface.
We recommend that you use SLF4J because it's well known in the Java ecosystem and it's well documented. For
more information, see the SLF4J user manual.
This article links to other articles that cover many of the popular Java logging frameworks. These other articles
provide configuration examples, and describe how the Azure client libraries can use the logging frameworks.
Whatever logging configuration you use, the same log output is available in either case because all logging
output in the Azure client libraries for Java is routed through an azure-core ClientLogger abstraction.
The rest of this article details the configuration of all available logging options.
After the environment variable is set, restart the application to enable the environment variable to take effect.
This logger will log to the console, and doesn't provide the advanced customization capabilities of an SLF4J
implementation, such as rollover and logging to file. To turn the logging off again, just remove the environment
variable and restart the application.
SLF4J logging
By default, you should configure logging using an SLF4J-supported logging framework. First, include a relevant
SLF4J logging implementation as a dependency from your project. For more information, see Declaring project
dependencies for logging in the SLF4J user manual. Next, configure your logger to work as necessary in your
environment, such as setting log levels, configuring which classes do and do not log, and so on. Some examples
are provided through the links below, but for more detail, see the documentation for your chosen logging
framework.
Next steps
Now that you've seen how logging works in the Azure SDK for Java, consider reviewing the links below for
guidance on how to configure some of the more popular Java logging frameworks to work with SLF4J and the
Java client libraries:
java.util.logging
Logback
Log4J
Log with the Azure SDK for Java and
java.util.logging
2/16/2022 • 2 minutes to read • Edit Online
This article provides an overview of how to add logging using java.util.logging to applications that use the Azure
SDK for Java. The java.util.logging framework is part of the JDK. As mentioned in Configure logging in the Azure
SDK for Java, all Azure client libraries log through SLF4J, so you can use logging frameworks such as
java.util.logging.
To enable java.util.logging, you must do two things:
1. Include the SLF4J adapter for java.util.logging as a dependency,
2. Create a file called logging.properties under the /src/main/resources project directory.
For more information related to configuring your logger, see Configuring Logging Output in the Oracle
documentation.
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.30</version> <!-- replace this version with the latest available version on Maven central -
->
</dependency>
Console logging
You can create a configuration to log to the console as shown in the following example. This example is
configured to log all logging events that are INFO level or higher, wherever they come from.
handlers = java.util.logging.ConsoleHandler
.level = INFO
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=[%1$tF %1$tT] [%4$s] %5$s %n
Log to a file
The previous example logs to the console, which isn't normally the preferred location for logs. To configure
logging to a file instead, use the following configuration:
handlers = java.util.logging.FileHandler
.level = INFO
java.util.logging.FileHandler.pattern = %h/myapplication.log
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.level = INFO
This code will create a file called myapplication.log in your home directory ( %h ). This logger doesn't support
automatic file rotation after a certain period. If you require this functionality, you'll need to write a scheduler to
manage log file rotation.
Next steps
This article covered the configuration of java.util.logging and how to make the Azure SDK for Java use it for
logging. Because the Azure SDK for Java works with all SLF4J logging frameworks, consider reviewing the SLF4J
user manual for further details.
After you've mastered logging, consider looking into the integrations that Azure offers into frameworks such as
Spring and MicroProfile.
Log with the Azure SDK for Java and Logback
2/16/2022 • 3 minutes to read • Edit Online
This article provides an overview of how to add logging using Logback to applications that use the Azure SDK
for Java. As mentioned in Configure logging in the Azure SDK for Java, all Azure client libraries log through
SLF4J, so you can use logging frameworks such as Logback.
To enable Logback logging, you must do two things:
1. Include the Logback library as a dependency,
2. Create a file called logback.xml in the /src/main/resources project directory.
For more information related to configuring Logback, see Logback configuration in the Logback documentation.
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover hourly and gzip logs -->
<fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd-HH}.log.gz</fileNamePattern>
</rollingPolicy>
</appender>
Spring applications
The Spring framework works by reading the Spring application.properties file for various configurations,
including the logging configuration. It's possible to configure the Spring application to read Logback
configurations from any file, however. To do so, configure the logging.config property to point to the
logback.xml configuration file by adding the following line into your Spring
/src/main/resources/application.properties file:
logging.config=classpath:logback.xml
Next steps
This article covered the configuration of Logback and how to make the Azure SDK for Java use it for logging.
Because the Azure SDK for Java works with all SLF4J logging frameworks, consider reviewing the SLF4J user
manual for further details. If you use Logback, there's also a vast amount of configuration guidance on its
website. For more information, see Logback configuration in the Logback documentation.
After you've mastered logging, consider looking into the integrations that Azure offers into frameworks such as
Spring and MicroProfile.
Log with the Azure SDK for Java and Log4j
2/16/2022 • 2 minutes to read • Edit Online
This article provides an overview of how to add logging using Log4j to applications that use the Azure SDK for
Java. As mentioned in Configure logging in the Azure SDK for Java, all Azure client libraries log through SLF4J,
so you can use logging frameworks such as log4j.
This article provides guidance to use the Log4J 2.x releases, but Log4J 1.x is equally supported by the Azure SDK
for Java. To enable log4j logging, you must do two things:
1. Include the log4j library as a dependency,
2. Create a configuration file (either log4j2.properties or log4j2.xml) under the /src/main/resources project
directory.
For more information related to configuring log4j, see Welcome to Log4j 2.
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.16.0</version>
</dependency>
NOTE
Due to known vulnerability CVE-2021-44228, be sure to use Log4j version 2.16 or later
Configuring Log4j
There are two common ways to configure Log4j: through an external properties file, or through an external XML
file. These approaches are outlined below.
Using a property file
You can place a flat properties file named log4j2.properties in the /src/main/resource directory of the project.
This file should take the following form:
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %msg%n
logger.app.name = com.azure.core
logger.app.level = ERROR
rootLogger.level = info
rootLogger.appenderRefs = stdout
rootLogger.appenderRef.stdout.ref = STDOUT
Using an XML file
You can place an XML file named log4j2.xml in the /src/main/resource directory of the project. This file should
take the following form:
Next steps
This article covered the configuration of Log4j and how to make the Azure SDK for Java use it for logging.
Because the Azure SDK for Java works with all SLF4J logging frameworks, consider reviewing the SLF4J user
manual for further details. If you use Log4j, there's also vast amount of configuration guidance on its website.
For more information, see Welcome to Log4j 2!
After you've mastered logging, consider looking into the integrations that Azure offers into frameworks such as
Spring and MicroProfile.
Spring Boot Starters for Azure
2/16/2022 • 4 minutes to read • Edit Online
This article describes the various Spring Boot Starters for the Spring Initializr that provide Java developers with
integration features for working with Microsoft Azure.
The following Spring Boot Starters are currently available for Azure:
Azure Suppor t
Provides auto-configuration support for Azure Services; e.g. Service Bus, Storage, Active Directory, etc.
Azure Active Director y
Provides integration support for Spring Security with Azure Active Directory for authentication.
Azure Key Vault
Provides Spring value annotation support for integration with Azure Key Vault Secrets.
Azure Storage
Provides Spring Boot support for Azure Storage services.
NOTE
The new version of the Spring Boot Starter for Azure Storage doesn't currently support adding an Azure storage
dependency from within Spring Initializr. However, you can add the dependency by modifying the pom.xml file
after the project is generated.
Azure Support
This Spring Boot Starter provides auto-configuration support for Azure Services; for example: Service Bus,
Storage, Active Directory, Cosmos DB, Key Vault, etc.
For examples of how to use the various Azure features that are provided by this starter, see the following:
The azure-spring-boot-samples repo on GitHub.
When you add this starter to a Spring Boot project, the following changes are made to the pom.xml file:
The following property is added to <properties> element:
<properties>
<!-- Other properties will be listed here -->
<java.version>1.8</java.version>
<azure.version>3.13.0</azure.version>
</properties>
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-bom</artifactId>
<version>${azure.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<!-- Other properties will be listed here -->
<java.version>1.8</java.version>
<azure.version>3.13.0</azure.version>
</properties>
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-starter-active-directory</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-bom</artifactId>
<version>${azure.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-starter-keyvault-secrets</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-bom</artifactId>
<version>${azure.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Azure Storage
This Spring Boot Starter provides Spring Boot integration support for Azure Storage services.
For examples of how to use the Azure Storage features that are provided by this starter, see the following:
How to use the Spring Boot Starter for Azure Storage
Spring Cloud Azure Storage Queue Operation Code Sample shared library for Java
When you add this starter to a Spring Boot project, the following changes are made to the pom.xml file:
The following property is added to <properties> element:
<properties>
<!-- Other properties will be listed here -->
<java.version>1.8</java.version>
<azure.version>3.13.0</azure.version>
</properties>
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-starter-storage</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-bom</artifactId>
<version>${azure.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Application Insights
Azure Monitor Application Insights can help you understand how your app is performing and how it's being
used. Application Insights uses the Java agent to enable the application monitor. There are no code changes
needed, and you can enable the Java agent with just a couple of configuration changes. For instructions and
more information, see Java codeless application monitoring Azure Monitor Application Insights.
Next steps
To learn more about Spring and Azure, continue to the Spring on Azure documentation center.
Spring on Azure
Additional Resources
For more information about using Spring Boot applications on Azure, see Spring on Azure.
For more information about using Azure with Java, see the Azure for Java Developers and the Working with
Azure DevOps and Java.
For help with getting started with your own Spring Boot applications, see the Spring Initializr at
https://start.spring.io/.
Troubleshoot networking issues
2/16/2022 • 5 minutes to read • Edit Online
This article describes a few tools that can diagnose networking issues of various complexities. These issues
include scenarios that range from troubleshooting an unexpected response value from a service, to root-causing
a connection-closed exception.
For client-side troubleshooting, the Azure client libraries for Java offer a consistent and robust logging story, as
described in Configure logging in the Azure SDK for Java. However, the client libraries make network calls over
various protocols, which may lead to troubleshooting scenarios that extend outside of the troubleshooting
scope provided. When these problems occur, the solution is to use the external tooling described in this article to
diagnose networking issues.
Fiddler
Fiddler is an HTTP debugging proxy that allows for requests and responses passed through it to be logged as-is.
The raw requests and responses that you capture can help you troubleshoot scenarios where the service gets an
unexpected request, or the client receives an unexpected response. To use Fiddler, you need to configure the
client library with an HTTP proxy. If you use HTTPS, you need extra configuration you need to inspect the
decrypted request and response bodies.
Add an HTTP proxy
To add an HTTP proxy, follow the guidance in Configure proxies in the Azure SDK for Java. Be sure to use the
default Fiddler address of localhost on port 8888.
Enable HTTPS decryption
By default, Fiddler can capture only HTTP traffic. If your application uses HTTPS, you must take extra steps to
trust Fiddler's certificate to allow it to capture HTTPS traffic. For more information, see HTTPS Menu in the
Fiddler documentation.
The following procedures describe how to use the Java Runtime Environment (JRE) to trust the certificate.
Without trusting the certificate, an HTTPS request through Fiddler may fail with security warnings.
Linux/macOS
1. Export Fiddler's certificate.
2. Find the JRE's keytool (usually jre/bin ).
3. Find the JRE's cacert (usually jre/lib/security ).
4. Open a Bash window and run the following command to import the certificate:
sudo keytool -import -file <location of Fiddler certificate> -keystore <location of cacert> -alias
Fiddler
5. Enter a password.
6. Trust the certificate.
Windows
1. Export Fiddler's certificate. The certificate is typically exported to the desktop.
2. Find the JRE's keytool (usually jre\bin ).
3. Find the JRE's cacert (usually jre\lib\security ).
4. Open a PowerShell window in administrator mode and run the following command to import the
certificate:
5. Enter a password. If you have not set a password before, the default is 'changeit'. For more information,
see Working with Certificates and SSL in the Oracle documentation.
6. Trust the certificate.
Wireshark
Wireshark is a network protocol analyzer that can capture network traffic without needing changes to
application code. Wireshark is highly configurable and can capture broad to specific, low-level network traffic.
This capability is useful for troubleshooting scenarios such as a remote host closing a connection or having
connections closed during an operation. The Wireshark GUI displays captures using a color scheme that
identifies unique capture cases, such as a TCP retransmission, RST, and so on. You can also filter captures either
at capture time or during analysis.
Configure a capture filter
Capture filters reduce the number of network calls that are captured for analysis. Without capture filters,
Wireshark will capture all traffic that goes through a network interface. This behavior can produce massive
amounts of data where most of it may be noise to the investigation. Using a capture filter helps preemptively
scope the network traffic being captured to help target an investigation. For more information, see Capturing
Live Network Data in the Wireshark documentation.
The following example adds a capture filter to capture network traffic sent to or received from a specific host.
In Wireshark, navigate to Capture > Capture Filters... and add a new filter with the value
host <host IP or hostname> . This filter will capture traffic only to and from that host. If the application
communicates to multiple hosts, you can add multiple capture filters, or you can add the host IP/hostname with
the 'OR' operator to provide looser capture filtering.
Capture to disk
You might need to run an application for a long time to reproduce an unexpected networking exception, and to
see the traffic that leads up to it. Additionally, it may not be possible to maintain all captures in memory.
Fortunately, Wireshark can log captures to disk so that they are available for post-processing. This approach
avoids the risk of running out of memory while you reproduce an issue. For more information, see File Input,
Output, And Printing in the Wireshark documentation.
The following example sets up Wireshark to persist captures to disk with multiple files, where the files split on
either 100k capture or 50 MB in size.
In Wireshark, navigate to Capture > Options and find the Output tab, then enter a file name to use. This
configuration will cause Wireshark to persist captures to a single file. To enable capture to multiple files, select
Create a new file automatically and then select after 100000 packets and after 50 megabytes . This
configuration will have Wireshark create a new file when one of the predicates is matched. Each new file will use
the same base name as the file name entered, and will append a unique identifier. If you want to limit the
number of files that Wireshark can create, select Use a ring buffer with X files . This option will limit
Wireshark to logging with only the specified number of files. When that number of files is reached, Wireshark
will begin overwriting the files, starting with the oldest.
Filter captures
Sometimes you can't tightly scope the traffic that Wireshark captures - for example, if your application
communicates with multiple hosts using various protocols. In this scenario, generally with using persistent
capture outlined above, it's easier to run analysis after network capturing. Wireshark supports filter-like syntax
for analyzing captures. For more information, see Working With Captured Packets in the Wireshark
documentation.
The following example loads a persisted capture file, and filters on ip.src_host==<IP> .
In Wireshark, navigate to File > Open and load a persisted capture from the file location used above. After the
file has loaded below the menu bar, a filter input will appear. In the filter input, enter ip.src_host==<IP> . This
filter will limit the capture view so that it shows only captures where the source was from the host with the IP
<IP> .
Next steps
This topic covered using various tools to diagnose networking issues when working with the Azure SDK for Java.
Now that you're familiar with the high-level usage scenarios, you can begin exploring the SDK itself. For more
information on the APIs available, see the Azure SDK for Java libraries.
Troubleshoot dependency version conflicts
2/16/2022 • 7 minutes to read • Edit Online
This article describes dependency version conflicts and how to troubleshoot them.
Azure client libraries for Java depend on several popular third-party libraries: Jackson, Netty, Reactor, and SLF4J.
Many Java applications and frameworks use these libraries directly or transitively, which leads to version
conflicts. Dependency managers such as Maven and Gradle resolve all dependencies so that there's only a single
version of each dependency on the classpath. However, it's not guaranteed that the resolved dependency version
is compatible with all consumers of that dependency in your application. For more information, see Introduction
to the Dependency Mechanism in the Maven documentation and Understanding dependency resolution in the
Gradle documentation.
The API incompatibility of direct dependencies results in compilation errors. Diamond dependency
incompatibility usually results in runtime failures such as NoClassDefFoundError, NoSuchMethodError, or other
LinkageError. Not all libraries strictly follow semantic versioning, and breaking changes sometimes happen
within the same major version.
Look for warning/error logs from JacksonVersion . For more information, see Configure logging in the Azure
SDK for Java. For example:
[main] ERROR com.azure.core.implementation.jackson.JacksonVersion - Version '2.9.0' of package 'jackson-core'
is not supported (too old), please upgrade.
NOTE
Check that all of the Jackson packages have the same version.
For the list of packages used by Azure SDK and the supported Jackson versions, see the Support for multiple
Jackson versions section.
NOTE
Shading has significant drawbacks: it increases package size and number of classes on the classpath, it makes code
navigation and debugging hard, does not relocate JNI code, breaks reflection, and may violate code licenses among other
things. It should be used only after other options are exhausted.
Shading enables you to include dependencies within a JAR at build time, renaming packages, and updating
application code to use the code in the shaded location. Diamond dependency conflict is no longer an issue
because there are two different copies of a dependency. You may shade a library that has a conflicting transitive
dependency or a direct application dependency, as described in the following list:
Transitive dependency conflict : for example, third-party library A requires Jackson 2.9, which is not
supported by Azure SDKs, and it's not possible to update A . Create a new module, which includes A and
shades (relocates) Jackson 2.9 and, optionally, other dependencies of A .
Application dependency conflict : your application uses Jackson 2.9 directly and while you're working on
updating your code, you can shade and relocate Jackson 2.9 into a new module with relocated Jackson
classes instead.
NOTE
Creating fat JAR with relocated Jackson classes doesn't resolve a version conflict in these examples - it only forces a single
shaded version of Jackson.
Jackson 2.10.0 and newer minor versions are compatible. For more
information, see the Support for multiple Jackson versions
section.
SLF4J 1.7.*
netty-tcnative-boringssl-static 2.0.*
DEP EN DEN C Y SUP P O RT ED VERSIO N S
netty-common 4.1.*
NOTE
Using old versions of Jackson may expose applications to known vulnerabilities and issues. For more information, see the
list of known vulnerabilities for Jackson libraries.
When pinning a specific version of Jackson, make sure to do it for all modules used by Azure SDK, which are
shown in the following list:
jackson-annotations
jackson-core
jackson-databind
jackson-dataformat-xml
jackson-datatype-jsr310
Next steps
Now that you're familiar with dependency version conflicts and how to troubleshoot them, see Dependency
Management for Java for information on the best way to prevent them.
Azure management libraries for Java - Virtual
machine samples
2/16/2022 • 2 minutes to read • Edit Online
The following table links to Java source you can use to create and configure Azure virtual machines.
SA M P L E DESC RIP T IO N
Create a virtual machine from a custom image Create a custom virtual machine image and use it to create
new virtual machines.
Create a virtual machine using specialized VHD from a Create snapshot from the virtual machine's OS and data
snapshot disks, create managed disks from the snapshots, and then
create a virtual machine by attaching the managed disks.
Create virtual machines in parallel in the same network Create virtual machines in the same region on the same
virtual network with two subnets in parallel.
Azure management libraries for Java - Web app
samples
2/16/2022 • 2 minutes to read • Edit Online
The following table links to Java source you can use to create and configure web apps.
SA M P L E DESC RIP T IO N
Create an app
Create a web app and deploy from FTP or GitHub Deploy web apps from local Git, FTP, and continuous
integration from GitHub.
Create a web app and manage deployment slots Create a web app and deploy to staging slots, and then
swap deployments between slots.
Configure an app
Create a web app and configure a custom domain Create a web app with a custom domain and self-signed SSL
certificate.
Scale an app
Scale a web app with high availability across multiple regions Scale a web app in three different geographical regions and
make them available through a single endpoint using Azure
Traffic Manager.
Connect a web app to a storage account Create an Azure storage account and add the storage
account connection string to the app settings.
Connect a web app to a SQL database Create a web app and SQL database, and then add the SQL
database connection string to the app settings.
Azure management libraries for Java - SQL
Database samples
2/16/2022 • 2 minutes to read • Edit Online
The following table links to Java source you can use to manage SQL Database.
SA M P L E DESC RIP T IO N
Connect and query data from Azure SQL Database using Configure a sample database, then run select, insert, update,
JDBC and delete commands.
Create and manage SQL databases Create SQL databases, set performance levels, and configure
firewalls.
Manage SQL databases across multiple regions Create a master SQL database and read-only databases
from the master in multiple regions. Connect VMs to their
nearest SQL database instance with a virtual network and
firewall rules.
Java source samples for Azure Active Directory
2/16/2022 • 2 minutes to read • Edit Online
The following table links to Java source you can use to access and work with Azure Active Directory (AD) in your
apps.
SA M P L E DESC RIP T IO N
Integrating Azure AD into a Java web application Set up OAuth2 authentication in a Java web app.
Integrating Azure AD into a Java command line using Obtain a JWT access token through OAuth 2.0, then use the
username and password access token to authenticate with an Azure AD protected
web API.
Manage users, groups, and roles with the Graph API Manage users, groups, roles, and service principals with the
Graph API using the management API.
Manage service principals Create a service principal for an application, assign it a role,
and use the service principal to access resources in the
subscription
Java samples for Azure Container Service
2/16/2022 • 2 minutes to read • Edit Online
The following table links to Java source you can use to create and configure applications running in Azure
Container Service.
SA M P L E DESC RIP T IO N
Manage Azure Container Registries Create a new Azure Container registry and add an new
image.
Manage Azure Container Service Create an Azure Container Service with Kubernetes
orchestration.
Deploy an image from Azure Container Registry into a new Deploy a Docker image running Tomcat to a new web app
Linux Web App running in Azure App Service for Linux.
Azure SDK for Java libraries
2/16/2022 • 44 minutes to read • Edit Online
The Azure SDK for Java is composed of many libraries - one for each Azure service. Additionally, there are
libraries designed to integrate with open-source projects, such as Spring, to provide Azure-specific support. All
Azure SDK for Java libraries are designed to work together and provide a cohesive developer experience, as
described in Use the Azure SDK for Java. The SDK achieves this cohesion through a common set of concepts,
including HTTP pipelines, identity and authentication, and logging.
The following tables show all libraries that exist in the Azure SDK for Java. These tables provide links to all
relevant repositories and documentation. To keep up to date with the Azure SDKs, consider following the
@AzureSDK Twitter account and the Azure SDK blog.
Libraries using azure-core
All libraries
All libraries
NAME PA C K A GE DO C S SO URC E