Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4471811

Reflection (getMethod) access differs from 1.3 (and prior) to 1.4

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.0
    • 1.4.0
    • core-libs
    • beta2
    • generic
    • generic
    • Verified



      Name: bsC130419 Date: 06/19/2001


      java version "1.4.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b65)
      Java HotSpot(TM) Client VM (build 1.4.0-beta-b65, mixed mode)

      and

      java version "1.3.1"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-b24)
      Java HotSpot(TM) Client VM (build 1.3.1-b24, mixed mode)

      There is an inconsistency from previous versions of java (<= 1.3.1) when using
      reflection to call methods on classes that are protected and in a different
      package. Here is some code that demonstrates this.

      package p1;
      import java.lang.reflect.*;
      import p2.*;

      public class x extends y {
          public x() {
              z z = new z();
              z.callZ();

              try {
                  Class [] classes = {};
                  Object [] args = {};
                  Method m = z.getClass().getMethod("callZ", classes);
                  m.invoke(z, args);
              } catch(Exception e) {
                  e.printStackTrace();
              }
          }

          public static void main(String [] args) {
              x x = new x();
          }
      }

      and

      package p2;

      public class y {
          public y() {}
          protected class z {
              public z() {}
              public void callZ() {
                  System.out.println("Called Z");
              }
          }
      }

      The key is that x extends y so it should inherit and be able to use the
      protected class z. We can see this is true with z.callZ() directly. However,
      this behavior is no longer valid when reflection is used to invoke callZ()
      using Method's invoke(). It will work if the classes are in the same package,
      regardless though, since x is a child of y, it should have access to all of y's
      public and protected fields and methods. We can see this behavior correctly
      work in all previous versions of the JDK, however the 1.4 beta no longer allows
      this and throws a java.lang.IllegalAccessException, ie:

      1.4:
      $ java p1.x
      Called Z
      java.lang.IllegalAccessException: Class p1.x can not access a member of class p2
      .y$z with modifiers "public"
              at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:50)
              at java.lang.reflect.Method.invoke(Method.java:300)
              at p1.x.<init>(x.java:14)
              at p1.x.main(x.java:21)

      1.3.1 and prior:
      $ java p1.x
      Called Z
      Called Z

      Perhaps this is just a Windows bug as I have not verified it on other platforms
      yet, but I would strongly suspect it is not.

      If 1.4 implements the correct behavior per the JLS, then this may be
      troublesome to developers who have written code (albiet invalid code) that not
      only conforms to this bug, but requires it. If this is the case, Sun needs to
      document this in large bold red letters in the reflection section of the 1.4
      documentation.
      (Review ID: 126933)
      ======================================================================

            kbr Kenneth Russell (Inactive)
            bstrathesunw Bill Strathearn (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: