IllegalAccessException on using reflection

后端 未结 5 783
情书的邮戳
情书的邮戳 2020-12-09 18:05

I was trying to learn reflection and I came across this IllegalAccessException. Please see the following code:

public class ReflectionTest
{
      public sta         


        
5条回答
  •  感动是毒
    2020-12-09 19:00

    You need to suppress Java language access checking in order to reflectively invoke a private method in another class, with setAccessible(true):

    Method mtd= itr.getClass().getMethod("hasNext");
      if(!mtd.isAccessible()) {
          mtd.setAccessible(true);
     }
    

    Furthermore, when a SecurityManager is enable, we need extra permissions to call setAccessible(true). Otherwise, we get:

    C:\ReflectionTest>java -Djava.security.manager CallFoo
    Exception in thread "main" java.security.AccessControlException: access denied (java.lang.reflect.ReflectPermission suppressAccessChecks)
        at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
        at java.security.AccessController.checkPermission(AccessController.java:427)
        at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
        at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:107)
        at CallFoo.main(CallFoo.java:8)
    

    We only want to grant this suppressAccessChecks permission to trusted code source, definitely not to all classes in the call stack. So we would modify CallFoo.java:

    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.security.AccessController;
    import java.security.PrivilegedActionException;
    import java.security.PrivilegedExceptionAction;
    
    public class CallFoo {
      public static void main(String args[]) throws Exception {
         doCallFoo();
      }
    
     public static void doCallFoo() throws IllegalAccessException, ClassNotFoundException, NoSuchMethodException, 
             InvocationTargetException, InstantiationException, PrivilegedActionException {
           Class fooClass = Class.forName("Foo");
         final Foo foo = (Foo) fooClass.newInstance();
         final Method helloMethod = fooClass.getDeclaredMethod("hello");
    
         AccessController.doPrivileged(new PrivilegedExceptionAction() {
             public Object run() throws Exception {
                 if(!helloMethod.isAccessible()) {
                     helloMethod.setAccessible(true);
                 }
                 helloMethod.invoke(foo);
               return null;
             }
         });
     }
     }
    

提交回复
热议问题