In this post, we explore the newest features, improvements, and bug fixes in Spring Cloud Azure and Java on Azure. We cover versions 5.16.0 to 5.19.0 of Spring Cloud Azure and provide troubleshooting tips for Java processes on Azure Kubernetes Service (AKS). This comprehensive overview shows you what’s new and how it can benefit your projects.
Fresh capabilities to explore
Discover the latest features and enhancements in Spring Cloud Azure, designed to address common user scenarios and improve your development experience.
Full support for Spring Boot 3.4
Spring Cloud Azure 5.19.0 now fully supports Spring Boot 3.4.0 and later versions. This means you can apply the latest Spring Boot features in your applications. For more information, see the release notes.
Enhanced configuration of authentication mechanism
Spring Cloud Azure offers flexible configuration properties, prefixed with spring.cloud.azure.credential.
, to manage several types of credentials, such as service principals and managed identities. With the latest enhancement, you can now use spring.cloud.azure.credential.token-credential-bean-name
to further customize your authentication beans, providing even greater control over your application’s security.
First, define a TokenCredential
bean in your application:
@Bean
TokenCredential myTokenCredential() {
// Your concrete TokenCredential instance
}
Next, add one property entry for it:
spring:
cloud:
azure:
credential:
token-credential-bean-name: myTokenCredential
Configuration for Azure SDK clients
Not only can the token-credential-bean-name
property be configured at the spring.cloud.azure
level, but it can also be configured for each service client. For example, you could configure it for the Azure Storage blob client:
spring:
cloud:
azure:
storage:
blob:
account-name: <your-azure-storage-account-name>
container-name: <your-blob-container-name>
credential:
token-credential-bean-name: myTokenCredential
Configuration for passwordless connections
Apart from configuring the token credential for Azure SDK clients, you could also configure it for other Azure services like Azure Database for MySQL – Flexible Server, Azure Database for PostgreSQL – Flexible Server, Azure Cache for Redis, and Service Bus. The following configuration is an example for the Redis passwordless connection:
spring:
data:
redis:
host: <your-azure-redis-name>.redis.cache.windows.net
port: 6380
ssl:
enabled: true
azure:
passwordless-enabled: true
credential:
token-credential-bean-name: myTokenCredential
And the following configuration is an example for a Service Bus JMS passwordless connection:
spring:
jms:
servicebus:
pricing-tier: <your-service-bus-pricing-tier>
namespace: <your-service-bus-namespace>
topic-client-id: <topic-client-id>
passwordless-enabled: true
credential:
token-credential-bean-name: myTokenCredential
Configuration for Key Vault property source
Since the Key Vault property source authenticates at an earlier initialization stage, the token-credential-bean-name
property doesn’t take effect on it. But you can still configure a customized TokenCredential
for it. For example, before the Spring Boot application runs, register a token credential object for authentication to Key Vault:
public static void main(String[] args) {
SpringApplication application = new SpringApplication(YourSpringApplication.class);
application.addBootstrapRegistryInitializer(registry ->
registry.register(TokenCredential.class, context -> {
// Your concrete TokenCredential instance
}));
application.run(args);
}
New Java Diagnostic Tool on AKS
The Java Diagnostic Tool (diag4j) is a lightweight, nonintrusive monitoring and diagnostic solution for Java applications running on AKS.
Key features of the tool include:
- Lightweight and noninvasive: By using Spring Boot Admin (SBA) and the Java Attach Agent, the tool is resource-efficient and doesn’t require extensive modifications to applications.
- Automatic Kubernetes Integration: The tool automatically discovers pods with exposed actuator endpoints, listing them on the SBA dashboard.
- Real-time metrics and diagnostics: The tool displays real-time application metrics, garbage collection (GC) status, and environment variables. You can also adjust log levels dynamically for deeper insights into specific issues.
- Advanced diagnostics: The tool offers enhanced diagnostic features. These features include:
- Inspection of stack traces
- Viewing of local variables
- Generation of heap and thread dumps
- Injection of logs dynamically for troubleshooting
- IDE compatibility: The tool integrates with JetBrains IntelliJ to enable debugging without needing to rebuild or redeploy the application, enabling streamlined troubleshooting.
For a detailed guide on getting started with diag4j, see Get started with Java Diagnostic Tool. Here’s a video about using diag4j.
You can provide feedback or create an issue in this GitHub repository.
Common scenarios
In the following sections, we iterate through several common scenarios.
Dead-lettering a message using Service Bus JMS
Service Bus JMS provides a way to consume Dead Letter Queue (DLQ) messages from a Service Bus queue in the same way as consuming a queue using the @JmsListener
annotation.
First, use the following configuration:
spring:
jms:
listener:
session:
acknowledge-mode: CLIENT
transacted: false
servicebus:
pricing-tier: <your-service-bus-pricing-tier>
namespace: <your-service-bus-namespace>
passwordless-enabled: true
Use the following sample code to consume messages from the Service Bus queue. If the message is invalid, move it to the DLQ of the queue:
@Component
public class QueueReceiveService {
private final Logger LOGGER = LoggerFactory.getLogger(QueueReceiveService.class);
private static final String QUEUE_NAME = "<your-queue-name>";
@JmsListener(destination = QUEUE_NAME, containerFactory = "jmsListenerContainerFactory")
public void receiveMessage(JmsObjectMessage message) throws JMSException {
User user = (User) message.getObject();
LOGGER.info("Received message from queue: {}.", user);
if (user.getName().toLowerCase().contains("invalid")) {
message.setIntProperty(JmsMessageSupport.JMS_AMQP_ACK_TYPE, REJECTED);
message.acknowledge();
LOGGER.info("Move message into dead letter queue: {}.", user);
}
}
}
Use the following sample code to consume DLQ messages from the Service Bus queue:
@Component
public class DeadLetterQueueReceiveService {
private final Logger LOGGER = LoggerFactory.getLogger(DeadLetterQueueReceiveService.class);
private static final String QUEUE_NAME = "<your-queue-name>";
private static final String DEAD_LETTER_QUEUE_NAME_SUFFIX = "/$deadletterqueue";
private static final String DEAD_LETTER_QUEUE_NAME = QUEUE_NAME + DEAD_LETTER_QUEUE_NAME_SUFFIX;
@JmsListener(destination = DEAD_LETTER_QUEUE_NAME, containerFactory = "jmsListenerContainerFactory")
public void receiveDeadLetterMessage(JmsObjectMessage message) throws JMSException {
User user = (User) message.getObject();
LOGGER.info("Received message from dead letter queue: {}.", user);
}
}
Refresh Key Vault property sources
Key Vault property sources support automatic refresh. For example, use the following configuration to refresh the secret keys. Then each property source can use a different refresh internal:
spring:
cloud:
azure:
keyvault:
secret:
property-source-enabled: true
property-sources:
- endpoint: ${KEY_VAULT_ENDPOINT_1}
name: KeyVault1
refresh-interval: 10s
secret-keys:
- one-minutes-available-username
- one-minutes-available-password
- endpoint: ${KEY_VAULT_ENDPOINT_2}
name: KeyVault2
refresh-interval: 30s
secret-keys: game-rules
Configure passwordless connections with multiple data sources
Spring Data supports registering multiple data sources. As of Spring Cloud Azure JDBC Starter 5.18.0
, it also supports multiple data sources with passwordless connections. For example, use the following configuration to define two database sources for different operation permissions. One source is for read operations and the other is for write operations:
spring:
datasource:
read:
url: <your-azure-database-jdbc-url>
username: <your-database-user-name-for-read>
azure:
passwordless-enabled: true
write:
url: <your-azure-database-jdbc-url>
username: <your-database-user-name-for-write>
azure:
passwordless-enabled: true
credential:
token-credential-bean-name: myTokenCredential
This configuration uses different authentication methods for each data source. The first data source uses the Azure Identity library’s DefaultAzureCredential
to authenticate with Microsoft Entra ID. The second data source uses the customized token credential bean.
Protect your applications with efficiency
Enhance your app’s security and performance with the latest updates in Key Vault JCA and Azure Identity Extensions. These updates include support for intermediate certificates and caching TokenCredential
instances.
Key Vault JCA supports loading of intermediate certificates
Since version 2.10.0, the Key Vault Java Cryptography Architecture (JCA) can read intermediate certificates in certificate chains. With the new version of azure-security-keyvault-jca
, such kinds of certificates can be used too:
- Enable HTTPS in Spring Boot application.
- Sign and verify jar files.
- Use Azure Key Vault to deliver TLS/SSL certificates to the Java Virtual Machine.
- Use Azure Key Vault to deliver TLS/SSL certificates to Apache Tomcat.
Azure Identity Extensions now supports caching of token credential instances
As of Azure Identity Extensions version 1.2.0, the library supports caching of TokenCredential
objects across multiple authentication invocations by default via the property azure.tokenCredentialCacheEnabled
. This capability reduces the number of Microsoft Entra access token requests. For example, when using the Azure Identity library’s WorkloadIdentityCredential
, more pressure is placed on the internal authorization server for access token acquisition if the token credential caching disabled. To disable token credential caching and to customize the access token acquisition timeout, use the following code:
Properties properties = new Properties();
properties.setProperty("user", "<your-database-username>");
properties.setProperty("authenticationPluginClassName",
"com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin");
properties.setProperty("azure.tokenCredentialCacheEnabled", "false");
String url = "<your-database-jdbc-url>";
Connection connection = DriverManager.getConnection(url, properties);
// use connection to execute SQL
Known issues
In the following section, note the known issues to be resolved as soon as possible after upgrading the newer version.
Use global managed identity credential
As of Spring Cloud Azure version 5.18.0, a defect in merging the global credential properties bean to each SDK properties bean is fixed. If you upgrade from version 5.18.0 to 5.19.0 and use global managed identity credential, you should encounter regression test failures. For more information, see the following GitHub issues:
Feedback
Your feedback and contributions are always welcome on StackOverflow or GitHub.
Resources
To learn more about Spring Cloud Azure, we invite you to visit the following links:
0 comments
Be the first to start the discussion.