From 36c8024acb6c8ba969c93887a977125510ab7385 Mon Sep 17 00:00:00 2001 From: Vinay Gera <5430778+g2vinay@users.noreply.github.com> Date: Sun, 8 Feb 2026 23:52:21 -0800 Subject: [PATCH] Fix GraalVM native image compatibility for AzureIdentityEnvVars Replace reflection-dependent AzureIdentityEnvVars enum usage with direct string literal to avoid NullPointerException in GraalVM native images. The ExpandableStringEnum base class uses reflection for static field initialization, which doesn't work in native images without explicit configuration. Using the string literal 'AZURE_TOKEN_CREDENTIALS' directly eliminates the reflection dependency while maintaining identical runtime behavior. Fixes NullPointerException in IdentityClientOptions.loadFromConfiguration when running in GraalVM native builds (e.g., Quarkus applications). --- sdk/identity/azure-identity/CHANGELOG.md | 1 + .../azure/identity/implementation/IdentityClientOptions.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sdk/identity/azure-identity/CHANGELOG.md b/sdk/identity/azure-identity/CHANGELOG.md index 875eb13a8ff6..e789c805ecd5 100644 --- a/sdk/identity/azure-identity/CHANGELOG.md +++ b/sdk/identity/azure-identity/CHANGELOG.md @@ -8,6 +8,7 @@ - Renamed `enableAzureTokenProxy()` method in `WorkloadIdentityCredentialBuilder` to `enableAzureProxy()`. These changes only affect code written against beta version 1.19.0-beta.1. ### Bugs Fixed +- Fixed `NullPointerException` in `IdentityClientOptions` when running in GraalVM native images (e.g., Quarkus applications). Replaced reflection-dependent `AzureIdentityEnvVars` enum usage with direct string literal to ensure compatibility with native compilation. ### Other Changes - Removed unused jetty, redisson, and lettuce-core dependencies. diff --git a/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/IdentityClientOptions.java b/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/IdentityClientOptions.java index d934c23c1d67..c7d9e3e244f8 100644 --- a/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/IdentityClientOptions.java +++ b/sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/IdentityClientOptions.java @@ -15,7 +15,6 @@ import com.azure.core.util.logging.ClientLogger; import com.azure.identity.AuthenticationRecord; import com.azure.identity.AzureAuthorityHosts; -import com.azure.identity.AzureIdentityEnvVars; import com.azure.identity.BrowserCustomizationOptions; import com.azure.identity.ChainedTokenCredential; import com.azure.identity.TokenCachePersistenceOptions; @@ -40,6 +39,7 @@ public final class IdentityClientOptions implements Cloneable { private static final int MAX_RETRY_DEFAULT_LIMIT = 6; public static final String AZURE_IDENTITY_DISABLE_MULTI_TENANT_AUTH = "AZURE_IDENTITY_DISABLE_MULTITENANTAUTH"; public static final String AZURE_POD_IDENTITY_AUTHORITY_HOST = "AZURE_POD_IDENTITY_AUTHORITY_HOST"; + private static final String AZURE_TOKEN_CREDENTIALS = "AZURE_TOKEN_CREDENTIALS"; private String authorityHost; private BrowserCustomizationOptions browserCustomizationOptions; @@ -693,7 +693,7 @@ private void loadFromConfiguration(Configuration configuration) { = configuration.get(Configuration.PROPERTY_AZURE_AUTHORITY_HOST, AzureAuthorityHosts.AZURE_PUBLIC_CLOUD); imdsAuthorityHost = configuration.get(AZURE_POD_IDENTITY_AUTHORITY_HOST, IdentityConstants.DEFAULT_IMDS_ENDPOINT); - dacEnvConfiguredCredential = configuration.get(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS.toString()); + dacEnvConfiguredCredential = configuration.get(AZURE_TOKEN_CREDENTIALS); ValidationUtil.validateAuthHost(authorityHost, LOGGER); multiTenantAuthDisabled = configuration.get(AZURE_IDENTITY_DISABLE_MULTI_TENANT_AUTH, false); }