2323 */ 
2424package  com .sun .jna ;
2525
26+ import  com .sun .jna .Callback .UncaughtExceptionHandler ;
27+ import  com .sun .jna .Structure .FFIType ;
2628import  java .awt .Component ;
2729import  java .awt .GraphicsEnvironment ;
2830import  java .awt .HeadlessException ;
3335import  java .io .IOException ;
3436import  java .io .InputStream ;
3537import  java .io .UnsupportedEncodingException ;
38+ import  java .lang .invoke .MethodHandle ;
39+ import  java .lang .invoke .MethodHandles ;
40+ import  java .lang .invoke .MethodHandles .Lookup ;
41+ import  java .lang .invoke .MethodType ;
3642import  java .lang .ref .Reference ;
3743import  java .lang .ref .WeakReference ;
3844import  java .lang .reflect .Array ;
5056import  java .nio .charset .Charset ;
5157import  java .nio .charset .IllegalCharsetNameException ;
5258import  java .nio .charset .UnsupportedCharsetException ;
53- import  java .security .AccessController ;
5459import  java .security .PrivilegedAction ;
5560import  java .util .ArrayList ;
5661import  java .util .Arrays ;
6065import  java .util .Map ;
6166import  java .util .StringTokenizer ;
6267import  java .util .WeakHashMap ;
63- 
64- import  com .sun .jna .Callback .UncaughtExceptionHandler ;
65- import  com .sun .jna .Structure .FFIType ;
6668import  java .util .logging .Level ;
6769import  java .util .logging .Logger ;
70+ import  java .util .stream .Stream ;
6871
6972/** Provides generation of invocation plumbing for a defined native 
7073 * library interface.  Also provides various utilities for native operations. 
@@ -181,6 +184,16 @@ public void uncaughtException(Callback c, Throwable e) {
181184    private  static  final  int  TYPE_BOOL  = 4 ;
182185    private  static  final  int  TYPE_LONG_DOUBLE  = 5 ;
183186
187+     private  static  final  MethodHandle  stackWalkerGetInstance ;
188+     private  static  final  Enum  stackWalkerRetainClassReference ;
189+     private  static  final  MethodHandle  stackWalkerWalk ;
190+     private  static  final  Object  stackWalkerFilter ;
191+ 
192+     private  static  final  MethodHandle  securityManagerExposerConstructor ;
193+     private  static  final  MethodHandle  securityManagerGetClassContext ;
194+ 
195+     private  static  final  MethodHandle  accessControllerDoPrivileged ;
196+ 
184197    static  final  int  MAX_ALIGNMENT ;
185198    static  final  int  MAX_PADDING ;
186199
@@ -255,6 +268,70 @@ static boolean isCompatibleVersion(String expectedVersion, String nativeVersion)
255268            || (Platform .isAndroid () && !Platform .isIntel ())
256269            ? 8  : LONG_SIZE ;
257270        MAX_PADDING  = (Platform .isMac () && Platform .isPPC ()) ? 8  : MAX_ALIGNMENT ;
271+ 
272+         Enum  stackWalkerRetainClassReferenceBuilder ;
273+         MethodHandle  stackWalkerGetInstanceBuilder ;
274+         MethodHandle  stackWalkerWalkBuilder ;
275+         Object  stackWalkerFilterBuilder ;
276+         try  {
277+             Lookup  lookup  = MethodHandles .lookup ();
278+             Class <?> stackWalkerClass  = Class .forName ("java.lang.StackWalker" );
279+             Class <? extends  Enum > stackWalkerOptionClass  = (Class <? extends  Enum >) Class .forName ("java.lang.StackWalker$Option" );
280+             stackWalkerRetainClassReferenceBuilder  = Enum .valueOf (stackWalkerOptionClass , "RETAIN_CLASS_REFERENCE" );
281+             stackWalkerGetInstanceBuilder  = lookup .findStatic (stackWalkerClass , "getInstance" , MethodType .methodType (stackWalkerClass , stackWalkerOptionClass ));
282+             stackWalkerWalkBuilder  = lookup .findVirtual (stackWalkerClass , "walk" , MethodType .methodType (Object .class , java .util .function .Function .class ));
283+             Class <?> stackframe  = Class .forName ("java.lang.StackWalker$StackFrame" );
284+             MethodHandle  stackFrameGetDeclaringClass  = lookup .findVirtual (stackframe , "getDeclaringClass" , MethodType .methodType (Class .class ));
285+             stackWalkerFilterBuilder  = new  java .util .function .Function <Stream <Object >, Class <?>>() {
286+                 @ Override 
287+                 public  Class <?> apply (Stream <Object > t ) {
288+                     Object  stackFrame  = t .skip (2 ).findFirst ().get ();
289+                     try  {
290+                         return  (Class <?>) stackFrameGetDeclaringClass .invoke (stackFrame );
291+                     } catch  (Throwable  ex ) {
292+                         return  null ;
293+                     }
294+                 }
295+             };
296+ 
297+         } catch  (Throwable  ex ) {
298+             LOG .log (Level .FINE , "Failed to initialize stack accessor method StackWalker" , ex );
299+             stackWalkerRetainClassReferenceBuilder  = null ;
300+             stackWalkerGetInstanceBuilder  = null ;
301+             stackWalkerWalkBuilder  = null ;
302+             stackWalkerFilterBuilder  = null ;
303+         }
304+         stackWalkerRetainClassReference  = stackWalkerRetainClassReferenceBuilder ;
305+         stackWalkerGetInstance  = stackWalkerGetInstanceBuilder ;
306+         stackWalkerWalk  = stackWalkerWalkBuilder ;
307+         stackWalkerFilter  = stackWalkerFilterBuilder ;
308+ 
309+         MethodHandle  securityManagerExposerConstructorBuilder ;
310+         MethodHandle  securityManagerGetClassContextBuilder ;
311+         try  {
312+             Lookup  lookup  = MethodHandles .lookup ();
313+             Class <?> securityManagerExposerClass  = Class .forName ("com.sun.jna.SecurityManagerExposer" );
314+             securityManagerExposerConstructorBuilder  = lookup .findConstructor (securityManagerExposerClass , MethodType .methodType (void .class ));
315+             securityManagerGetClassContextBuilder  = lookup .findVirtual (securityManagerExposerClass , "getClassContext" , MethodType .methodType (Class [].class ));
316+         } catch  (Throwable  ex ) {
317+             LOG .log (Level .FINE , "Failed to initialize stack accessor method SecurityManager" , ex );
318+             securityManagerExposerConstructorBuilder  = null ;
319+             securityManagerGetClassContextBuilder  = null ;
320+         }
321+         securityManagerExposerConstructor  = securityManagerExposerConstructorBuilder ;
322+         securityManagerGetClassContext  = securityManagerGetClassContextBuilder ;
323+ 
324+         MethodHandle  accessControllerDoPrivilegedBuilder  = null ;
325+         try  {
326+             Lookup  lookup  = MethodHandles .lookup ();
327+             Class <?> accessControllerClass  = Class .forName ("java.security.AccessController" );
328+             accessControllerDoPrivilegedBuilder  = lookup .findStatic (accessControllerClass , "doPrivileged" , MethodType .methodType (Object .class , PrivilegedAction .class ));
329+         } catch  (Throwable  ex ) {
330+             LOG .log (Level .FINE , "Failed to initialize AccessController#doPrivileged" , ex );
331+             accessControllerDoPrivilegedBuilder  = null ;
332+         }
333+         accessControllerDoPrivileged  = accessControllerDoPrivilegedBuilder ;
334+ 
258335        System .setProperty ("jna.loaded" , "true" );
259336    }
260337
@@ -1275,7 +1352,7 @@ public static String getWebStartLibraryPath(final String libName) {
12751352        try  {
12761353
12771354            final  ClassLoader  cl  = Native .class .getClassLoader ();
1278-             Method  m  = AccessController . doPrivileged (new  PrivilegedAction <Method >() {
1355+             Method  m  = ( Method )  accessControllerDoPrivileged . invoke (new  PrivilegedAction <Method >() {
12791356                @ Override 
12801357                public  Method  run () {
12811358                    try  {
@@ -1294,7 +1371,7 @@ public Method run() {
12941371            }
12951372            return  null ;
12961373        }
1297-         catch  (Exception  e ) {
1374+         catch  (Throwable  e ) {
12981375            return  null ;
12991376        }
13001377    }
@@ -1523,19 +1600,35 @@ static Class<?> findDirectMappedClass(Class<?> cls) {
15231600        was made. 
15241601    */ 
15251602    static  Class <?> getCallingClass () {
1526-         Class <?>[] context  = new  SecurityManager () {
1527-             @ Override 
1528-             public  Class <?>[] getClassContext () {
1529-                 return  super .getClassContext ();
1603+         if  (stackWalkerGetInstance  != null ) {
1604+             try  {
1605+                 Object  walker  = stackWalkerGetInstance .invoke (stackWalkerRetainClassReference );
1606+                 Class <?> caller  = (Class <?>) stackWalkerWalk .invoke (walker , stackWalkerFilter );
1607+                 return  caller ;
1608+             } catch  (Throwable  ex ) {
1609+                 LOG .log (Level .WARNING , "Failed to invoke StackWalker#getInstance or StackWalker#walk" , ex );
15301610            }
1531-         }.getClassContext ();
1532-         if  (context  == null ) {
1533-             throw  new  IllegalStateException ("The SecurityManager implementation on this platform is broken; you must explicitly provide the class to register" );
15341611        }
1535-         if  (context .length  < 4 ) {
1536-             throw  new  IllegalStateException ("This method must be called from the static initializer of a class" );
1612+ 
1613+         if  (securityManagerExposerConstructor  != null ) {
1614+             Class <?>[] context  = null ;
1615+             try  {
1616+                 Object  securityManagerExposer  = securityManagerExposerConstructor .invoke ();
1617+                 context  = (Class <?>[]) securityManagerGetClassContext .invoke (securityManagerExposer );
1618+             } catch  (Throwable  ex ) {
1619+                 LOG .log (Level .WARNING , "Failed to invoke SecurityManagerExposer#<init> or SecurityManagerExposer#getClassContext" , ex );
1620+             }
1621+ 
1622+             if  (context  == null ) {
1623+                 throw  new  IllegalStateException ("The SecurityManager implementation on this platform is broken; you must explicitly provide the class to register" );
1624+             }
1625+             if  (context .length  < 4 ) {
1626+                 throw  new  IllegalStateException ("This method must be called from the static initializer of a class" );
1627+             }
1628+             return  context [3 ];
15371629        }
1538-         return  context [3 ];
1630+ 
1631+         throw  new  IllegalStateException ("Neither the StackWalker, nor the SecurityManager based getCallingClass implementation are useable; you must explicitly provide the class to register" );
15391632    }
15401633
15411634    /** 
0 commit comments