This is an automated email from the ASF dual-hosted git repository.

rzo1 pushed a commit to branch 7935
in repository https://gitbox.apache.org/repos/asf/storm.git

commit 5ad245a29704bc11ecd37e255abce839591266d4
Author: Richard Zowalla <[email protected]>
AuthorDate: Sun Feb 23 17:00:50 2025 +0100

    #7935 - Use reflection to handle Java SecurityManager deprecation
---
 .github/workflows/maven.yaml                       |  2 +-
 .../org/apache/storm/security/auth/ReqContext.java | 76 ++++++++++++++++++++--
 2 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/maven.yaml b/.github/workflows/maven.yaml
index 1bb4e1afe..643442841 100644
--- a/.github/workflows/maven.yaml
+++ b/.github/workflows/maven.yaml
@@ -28,7 +28,7 @@ jobs:
     strategy:
       matrix:
         os: [ ubuntu-latest ]
-        java: [ 17, 21 ]
+        java: [ 17, 21, 24 ]
         module: [ Client, Server, Core, External, Check-Updated-License-Files, 
Integration-Test ]
         experimental: [false]
       fail-fast: false
diff --git 
a/storm-client/src/jvm/org/apache/storm/security/auth/ReqContext.java 
b/storm-client/src/jvm/org/apache/storm/security/auth/ReqContext.java
index 11a1cdf2d..c591f9632 100644
--- a/storm-client/src/jvm/org/apache/storm/security/auth/ReqContext.java
+++ b/storm-client/src/jvm/org/apache/storm/security/auth/ReqContext.java
@@ -18,9 +18,10 @@
 
 package org.apache.storm.security.auth;
 
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
 import java.net.InetAddress;
-import java.security.AccessControlContext;
-import java.security.AccessController;
 import java.security.Principal;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -36,10 +37,13 @@ import 
org.apache.storm.shade.com.google.common.annotations.VisibleForTesting;
  * </ol>
  */
 public class ReqContext {
+
+    private static final MethodHandle CURRENT = lookupCurrent();
+
     private static final AtomicInteger uniqueId = new AtomicInteger(0);
     //each thread will have its own request context
     private static final ThreadLocal<ReqContext> ctxt =
-        ThreadLocal.withInitial(() -> new 
ReqContext(AccessController.getContext()));
+        ThreadLocal.withInitial(ReqContext::new);
     private Subject subject;
     private InetAddress remoteAddr;
     private final int reqId;
@@ -47,8 +51,8 @@ public class ReqContext {
 
     //private constructor
     @VisibleForTesting
-    public ReqContext(AccessControlContext aclCtxt) {
-        subject = Subject.getSubject(aclCtxt);
+    public ReqContext() {
+        subject = currentSubject();
         reqId = uniqueId.incrementAndGet();
     }
 
@@ -161,4 +165,66 @@ public class ReqContext {
     public int requestID() {
         return reqId;
     }
+
+    /**
+     * Maps to Subject.currect() is available, otherwise maps to 
Subject.getSubject()
+     * @return the current subject
+     */
+    public static Subject currentSubject() {
+        try {
+            return (Subject) CURRENT.invoke();
+        } catch (Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
+
+    private static MethodHandle lookupCurrent() {
+        final MethodHandles.Lookup lookup = MethodHandles.lookup();
+        try {
+            // Subject.getSubject(AccessControlContext) is deprecated for 
removal and replaced by
+            // Subject.current().
+            // Lookup first the new API, since for Java versions where both 
exists, the
+            // new API delegates to the old API (for example Java 18, 19 and 
20).
+            // Otherwise (Java 17), lookup the old API.
+            return lookup.findStatic(Subject.class, "current",
+                    MethodType.methodType(Subject.class));
+        } catch (NoSuchMethodException e) {
+            final MethodHandle getContext = lookupGetContext();
+            final MethodHandle getSubject = lookupGetSubject();
+            return MethodHandles.filterReturnValue(getContext, getSubject);
+        } catch (IllegalAccessException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    private static MethodHandle lookupGetSubject() {
+        final MethodHandles.Lookup lookup = MethodHandles.lookup();
+        try {
+            final Class<?> contextClazz =
+                    ClassLoader.getSystemClassLoader()
+                            .loadClass("java.security.AccessControlContext");
+            return lookup.findStatic(Subject.class, "getSubject",
+                    MethodType.methodType(Subject.class, contextClazz));
+        } catch (ClassNotFoundException | NoSuchMethodException | 
IllegalAccessException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    private static MethodHandle lookupGetContext() {
+        try {
+            // Use reflection to work with Java versions that have and don't 
have AccessController.
+            final Class<?> controllerClazz =
+                    
ClassLoader.getSystemClassLoader().loadClass("java.security.AccessController");
+            final Class<?> contextClazz =
+                    ClassLoader.getSystemClassLoader()
+                            .loadClass("java.security.AccessControlContext");
+
+            MethodHandles.Lookup lookup = MethodHandles.lookup();
+            return lookup.findStatic(controllerClazz, "getContext",
+                    MethodType.methodType(contextClazz));
+        } catch (ClassNotFoundException | NoSuchMethodException | 
IllegalAccessException e) {
+            throw new AssertionError(e);
+        }
+    }
+
 }

Reply via email to