@@ -70,65 +70,28 @@ public static boolean safeGetBooleanSystemProperty(String key) {
7070 return value .equalsIgnoreCase ("true" );
7171 }
7272
73- /**
74- * In order to call {@link SecurityManager#getClassContext()}, which is a
75- * protected method, we add this wrapper which allows the method to be visible
76- * inside this package.
77- */
78- private static final class ClassContextSecurityManager extends SecurityManager {
79- protected Class <?>[] getClassContext () {
80- return super .getClassContext ();
81- }
82- }
83-
84- private static ClassContextSecurityManager SECURITY_MANAGER ;
85- private static boolean SECURITY_MANAGER_CREATION_ALREADY_ATTEMPTED = false ;
86-
87- private static ClassContextSecurityManager getSecurityManager () {
88- if (SECURITY_MANAGER != null )
89- return SECURITY_MANAGER ;
90- else if (SECURITY_MANAGER_CREATION_ALREADY_ATTEMPTED )
91- return null ;
92- else {
93- SECURITY_MANAGER = safeCreateSecurityManager ();
94- SECURITY_MANAGER_CREATION_ALREADY_ATTEMPTED = true ;
95- return SECURITY_MANAGER ;
96- }
97- }
98-
99- private static ClassContextSecurityManager safeCreateSecurityManager () {
100- try {
101- return new ClassContextSecurityManager ();
102- } catch (SecurityException sm ) {
103- return null ;
104- }
105- }
106-
10773 /**
10874 * Returns the name of the class which called the invoking method.
75+ * Uses StackWalker API (Java 9+) instead of deprecated SecurityManager.
10976 *
11077 * @return the name of the class which called the invoking method.
11178 */
11279 public static Class <?> getCallingClass () {
113- ClassContextSecurityManager securityManager = getSecurityManager ();
114- if (securityManager == null )
80+ try {
81+ StackWalker walker = StackWalker .getInstance (StackWalker .Option .RETAIN_CLASS_REFERENCE );
82+ return walker .walk (stream -> {
83+ String thisClassName = Util .class .getName ();
84+ return stream
85+ .map (StackWalker .StackFrame ::getDeclaringClass )
86+ .dropWhile (clazz -> !thisClassName .equals (clazz .getName ()))
87+ .skip (2 ) // Skip Util class and the immediate caller
88+ .findFirst ()
89+ .orElse (null );
90+ });
91+ } catch (Exception e ) {
92+ // Fallback to null if StackWalker fails
11593 return null ;
116- Class <?>[] trace = securityManager .getClassContext ();
117- String thisClassName = Util .class .getName ();
118-
119- // Advance until Util is found
120- int i ;
121- for (i = 0 ; i < trace .length ; i ++) {
122- if (thisClassName .equals (trace [i ].getName ()))
123- break ;
12494 }
125-
126- // trace[i] = Util; trace[i+1] = caller; trace[i+2] = caller's caller
127- if (i >= trace .length || i + 2 >= trace .length ) {
128- throw new IllegalStateException ("Failed to find its caller in the stack; " + "this should not happen" );
129- }
130-
131- return trace [i + 2 ];
13295 }
13396
13497 static public void report (String msg , Throwable t ) {
0 commit comments