Azure / azure-sdk-for-java

This repository is for active development of the Azure SDK for Java. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/java/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-java.
MIT License
2.35k stars 1.99k forks source link

[BUG] Recursive update exception in HttpLogOptions initialization with security manager enabled #42905

Closed martin-frydl closed 1 day ago

martin-frydl commented 1 day ago

Describe the bug java.lang.IllegalStateException: Recursive update exception is thrown when HttpLogOptions class is initialized with security manager enabled.

Exception or Stack Trace

Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.azure.core.implementation.ReflectionUtilsMethodHandle.performSafePrivateLookupIn(ReflectionUtilsMethodHandle.java:197)
    at com.azure.core.implementation.ReflectionUtilsMethodHandle.getLookupToUse(ReflectionUtilsMethodHandle.java:153)
    at com.azure.core.implementation.ReflectionUtilsMethodHandle.getConstructorInvoker(ReflectionUtilsMethodHandle.java:111)
    at com.azure.core.implementation.ReflectionUtils.getConstructorInvoker(ReflectionUtils.java:130)
    at com.azure.core.implementation.ReflectionUtils.getConstructorInvoker(ReflectionUtils.java:96)
    at com.azure.core.util.ExpandableStringEnum.getDefaultConstructor(ExpandableStringEnum.java:91)
    at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) <---------------------------
    at com.azure.core.util.ExpandableStringEnum.fromString(ExpandableStringEnum.java:70)
    at com.azure.core.http.HttpHeaderName.fromString(HttpHeaderName.java:73)
    at com.azure.core.http.HttpHeaderName.<clinit>(HttpHeaderName.java:101)
    at com.azure.core.http.policy.HttpLogOptions.<clinit>(HttpLogOptions.java:55)
    at AzureTest.main(AzureTest.java:3)
Caused by: java.lang.IllegalStateException: Recursive update
    at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1763) <----------------------
    at com.azure.core.util.ExpandableStringEnum.fromString(ExpandableStringEnum.java:70)
    at com.azure.core.http.HttpHeaderName.fromString(HttpHeaderName.java:73)
    at com.azure.core.implementation.ImplUtils.<clinit>(ImplUtils.java:55)
    ... 12 more

To Reproduce

public class AzureTest {
    public static void main(String args[]) {
        System.out.println(new com.azure.core.http.policy.HttpLogOptions());
   }
}

When running set -Djava.security.manager -Djava.security.policy=policy.policy where policy file contained following (just to make it run):

grant {
  permission java.lang.RuntimePermission "*";
  permission java.util.PropertyPermission "*", "read, write";
};

Expected behavior Working initialization. It works fine in version 1.53.0 but fails in 1.54.0.

Setup:

Additional context The problem is in ReflectionUtilsMethodHandle.performSafePrivateLookupIn() where ImplUtils.doPrivilegedException() is called. ImplUtils gets initializated by calling exactly the same method - HttpHeaderName.fromString() - leading to setting the same key in the same map.

github-actions[bot] commented 1 day ago

Thank you for your feedback. Tagging and routing to the team member best able to assist.

alzimmermsft commented 1 day ago

Thank you for reporting this @martin-frydl!

I'll file a PR to resolve this and include the information you've given to add tests that will prevent this in the future.