JDK-6966679 : (reflect) Incorrect argument order in sun.reflect.Reflection#verifyMemberAccess()
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 6u10,9
  • Priority: P2
  • Status: Resolved
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2010-07-05
  • Updated: 2016-10-24
  • Resolved: 2016-10-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Resolved
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
Accessing protected static fields and methods is not possible for subclasses using reflection. This is due to a bug in the method verifyMemberAccess() of class sun.reflect.Reflection:


In lines 110 ff. it is checked, that the caller's class (named currentClass) is a subclass of the member's class (named memberClass):
   if (Modifier.isProtected(modifiers)) {
      // See if currentClass is a subclass of memberClass
      if (isSubclassOf(currentClass, memberClass)) {
         successSoFar = true;
      }
   }

In the static case the variable targetClass is set to memberClass, line 135:
   Class targetClass = (target == null ? memberClass : target.getClass());

Later on the following code is reached (lines 141 ff.)
   if (!isSubclassOf(targetClass, currentClass)) {
      return false;
   }

The arguments order in this call to method isSubclassOf() is obviously wrong!


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
javac a/A.java a/b/B.java
java a.b.B


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Successfully set protected static member in a static way
Successfully set protected static member in a non-static way

ACTUAL -
java.lang.IllegalAccessException: Class a.b.B can not access a member of class a.A with modifiers "protected static"
        at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
        at java.lang.reflect.Field.doSecurityCheck(Unknown Source)
        at java.lang.reflect.Field.getFieldAccessor(Unknown Source)
        at java.lang.reflect.Field.set(Unknown Source)
        at a.b.B.reflectiveAccess(B.java:21)
        at a.b.B.main(B.java:12)
Successfully set protected static member in a non-static way


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
-----
package a;

public class A
{
  protected static Object member;
}
-----
package a.b;

public class B extends a.A
{
  public static void main(String[] args) throws Exception
  {
    new B().reflectiveAccess();
  }
  
  public void reflectiveAccess() throws Exception
  {
    java.lang.reflect.Field member = a.A.class.getDeclaredField("member");
    try {
      member.set(null, new Object());
      System.out.println("Successfully set protected static member in a static way");
    }
    catch (Exception e) {
      e.printStackTrace(System.err);
    }
    
    try {
      member.set(this, new Object());
      System.out.println("Successfully set protected static member in a non-static way");
    }
    catch (Exception e) {
      e.printStackTrace(System.err);
    }
  }
}
-----

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
1) Use a customized implementation of sun.reflect.FieldAccessor, sun.reflect.MethodAccessor and sun.reflect.ConstructorAccessor.
2) Reflectively access protected static members by passing in a target object.

Comments
This has been fixed by JDK-6378384. Close as a duplicate.
24-10-2016

This is indeed a long standing bug where the subtype check is incorrect and so fails when attempting to access a static protected member in a supertype. I believe this has been fixed by Peter Levart's recent changes in jdk9/dev.
24-10-2016