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

(reflect) Class.getDeclaredMethod and Class.getMethod return wrong method

XMLWordPrintable

    • mantis
    • generic
    • generic
    • Verified



      Name: erR10175 Date: 07/08/2002



      New JCK testcases

      api/java_lang/Class/index.html#Reflect2[Class2203]
      api/java_lang/Class/index.html#Reflect2[Class2230]

      fail with the following error messages:

      Class2203: Failed. getDeclaredMethod returns wrong method public java.lang.Throwable
      javasoft.sqe.tests.api.java.lang.Class.Overloader.m1(java.lang.Object)
      Class2230: Failed. getMethod returns wrong method public java.lang.Throwable
      javasoft.sqe.tests.api.java.lang.Class.Overloader.m1(java.lang.Object)

      because java.lang.Class's methods (getDeclaredMethod and getMethod respectively) do
      not choose from the set of methods with the same parameter types a method with the
      most specific return type. In the tests the Overloader (see below) class is used to
      get its method "m1(java.lang.Object)". The class has three methods with the signature.
      They differ in return types, which are Object, Throwable and Exception. Both
      getDeclaredMethod and getMethod choose the method that returns Throwable.

      The specification of the methods reads:
      "If more than one method with the same parameter types is declared in a class, and one
      of these methods has a return type that is more specific than any of the others, that
      method is returned;"
      and "If C declares exactly one public method with the specified name and exactly the
      same formal parameter types, that is the method reflected. If more than one such method
      is found in C, and one of these methods has a return type that is more specific than any
      of the others, that method is reflected;"

      To reproduce the first failure put Overloader.class file (see attachment) to the current
      directory then compile and run Class2203.java (see below) as the following log shows:
      $ls && java -version && javac Class2203.java && java Class2203; echo $?
      Class2203.java Overloader.class
      java version "1.4.1-rc"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-rc-b15)
      Java HotSpot(TM) Client VM (build 1.4.1-rc-b15, mixed mode)
      getDeclaredMethod returns wrong method public java.lang.Throwable Overloader.m1(java.lang.Object)
      1

      ----------------------- Overloader.jasm (the source of Overloader.class)
      /*
       * this class has three methods named "m1"
       * with the same parameter types, their return types are
       * Object, Throwable and Exception.
       */
      class Overloader
      {

      public Method m1:"(Ljava/lang/Throwable;)Ljava/lang/Throwable;"
              stack 1 locals 2
      {
                      aconst_null;
                      areturn;
      }

      public Method m1:"(Ljava/lang/Object;)Ljava/lang/Throwable;"
              stack 1 locals 2
      {
                      aconst_null;
                      areturn;
      }

      public Method m1:"(Ljava/lang/Object;)Ljava/lang/Object;"
              stack 1 locals 2
      {
                      aconst_null;
                      areturn;
      }

      public Method m1:"(Ljava/lang/Object;)Ljava/lang/Exception;"
              stack 1 locals 2
      {
                      aconst_null;
                      areturn;
      }

      } // end Class Overloader
      ---------------------------------------

      ----------------------- Class2203.java
      import java.lang.reflect.Method;

      class Class2203 {
          public static void exit(int retCode, String msg) {
              System.out.println(msg);
              System.exit(retCode);
          }

          public static void main(String[] args) {
              try {
                  Class arg[] = {Object.class};
                  Method m1 = Overloader.class.getDeclaredMethod("m1", arg);
          
                  if ( !m1.toString().equals("public java.lang.Exception Overloader.m1(java.lang.Object)" )) {
                      exit(1, "getDeclaredMethod returns wrong method " + m1);
                  }
                  exit(0, "OKAY");
              } catch (SecurityException se){
                  exit(1, "" + se);
              } catch (NoSuchMethodException e) {
                  exit(1, "Unexpected NoSuchMethodException");
              }
          }
      }
      --------------------------------------

      ======================================================================

            iris Iris Clark
            reysunw Rey Rey (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: