-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
1.1, 1.2.2, 5.0
-
Fix Understood
-
generic, x86, sparc
-
generic, solaris_2.5, windows_xp
java.lang.reflect.Field (get* and set*) and Method (invoke) base their access check on the declaring class. This is contrary to the JLS, which defines accessibility in terms of the reference type. Consider the following:
package foo;
class X {
public int i;
}
package foo;
public class Y extends X {
public static Object get() { return new Z(); }
}
package foo;
class Z extends Y {}
package bar;
import foo.Y;
public class T {
public static void main(String[] args) {
Y y = new Y();
int i = y.i;
try {
y.getClass().getField("i").getInt(y);
} catch (Exception e) {
e.printStackTrace();
}
Object z = Y.get();
i = ((Y)z).i;
try {
z.getClass().getField("i").getInt(z);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Both of the getInt calls throw IllegalAccessException, contrary to what the compiler allows.
At runtime you need to check if there exists some class, between the declaring class and the actual class (inclusive), that is public. This could be a bit messy for interface methods, since there isn't a single linear chain to search.
package foo;
class X {
public int i;
}
package foo;
public class Y extends X {
public static Object get() { return new Z(); }
}
package foo;
class Z extends Y {}
package bar;
import foo.Y;
public class T {
public static void main(String[] args) {
Y y = new Y();
int i = y.i;
try {
y.getClass().getField("i").getInt(y);
} catch (Exception e) {
e.printStackTrace();
}
Object z = Y.get();
i = ((Y)z).i;
try {
z.getClass().getField("i").getInt(z);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Both of the getInt calls throw IllegalAccessException, contrary to what the compiler allows.
At runtime you need to check if there exists some class, between the declaring class and the actual class (inclusive), that is public. This could be a bit messy for interface methods, since there isn't a single linear chain to search.
- duplicates
-
JDK-8193172 Refection vs Compiler gives different access levels to package-private classes
- Closed
-
JDK-4032740 (Reflection)Accessibilities of members should be ACCESS-LEVEL sensitive.
- Closed
-
JDK-8181410 Regular accessibility, not reflective access
- Closed
- relates to
-
JDK-4071957 (reflect) Method.invoke access control does not understand inner class scoping
- Closed
-
JDK-8167262 java.lang.IllegalAccessException When Reflecting on Iterator.hasNext()
- Closed