JDK-8058313 : Mismatch of method descriptor and MethodParameters.parameters_count should cause MalformedParameterException
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-09-12
  • Updated: 2016-05-27
  • Resolved: 2014-11-11
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
9 b42Fixed
Related Reports
Blocks :  
Relates :  
Description
In case of mismatch of method descriptor and parameters_count MalformedParameterExeption is expected when reflection j.l.r.Executable.getParameters() is used.
API spec says:

      "The following is a list of conditions under which this exception
can be thrown:

  * The number of parameters (parameter_count) is wrong for the method" 

But in case of one parameter in the descriptor and zero parameters in the parameters_count of attribute, exception isn't thrown.

The following test will fail due to this bug: vm/classfmt/atr/atrmtp002/atrmtp00201m1/atrmtp00201m1 

How to reproduce:
1) Convert following .jcod to class file (both jcod and class files are attached)
-------------------------------
class javasoft/sqe/tests/vm/classfmt/atr/atrmtp002/atrmtp00201m1/atrmtp00201m11n {
  0xCAFEBABE;
  0; // minor version
  52; // version
  [] { // Constant Pool
    ; // first element is empty
    Method #4 #13; // #1
    Method #14 #15; // #2
    class #8; // #3
    class #16; // #4
    Utf8 "<init>"; // #5
    Utf8 "()V"; // #6
    Utf8 "Code"; // #7
    Utf8 "javasoft/sqe/tests/vm/classfmt/atr/atrmtp002/atrmtp00201m1/atrmtp00201m11n"; // #8
    Utf8 "(I)V"; // #9
    Utf8 "m"; // #10
    Utf8 "run"; // #11
    Utf8 "([Ljava/lang/String;Ljava/io/PrintStream;)I"; // #12
    NameAndType #5 #6; // #13
    class #17; // #14
    NameAndType #11 #12; // #15
    Utf8 "java/lang/Object"; // #16
    Utf8 "javasoft/sqe/tests/vm/classfmt/atr/atrmtp002/atrmtp00201m1/atrmtp00201m11nChecker"; // #17
    Utf8 "MethodParameters"; // #18
    Utf8 "p"; // #19
  } // Constant Pool

  0x0021; // access
  #3;// this_cpx
  #4;// super_cpx

  [] { // Interfaces
  } // Interfaces

  [] { // fields
  } // fields

  [] { // methods
    { // Member
      0x0001; // access
      #5; // name_cpx
      #6; // sig_cpx
      [] { // Attributes
        Attr(#7) { // Code
          1; // max_stack
          1; // max_locals
          Bytes[]{
            0x2AB70001B1;
          };
          [] { // Traps
          } // end Traps
          [] { // Attributes
          } // Attributes
        } // end Code
      } // Attributes
    } // Member
    ;
    { // Member
      0x0001; // access
      #10; // name_cpx
      #9; // sig_cpx
      [] { // Attributes
        Attr(#7) { // Code
          0; // max_stack
          2; // max_locals
          Bytes[]{
            0xB1;
          };
          [] { // Traps
          } // end Traps
          [] { // Attributes
          } // Attributes
        } // end Code
        ;
        Attr(#18) { // MethodParameters
/* right:
          0x0100130000;
end right */
// wrong:
          0x00;
// end wrong
        } // end MethodParameters
      } // Attributes
    } // Member
    ;
    { // Member
      0x0009; // access
      #11; // name_cpx
      #12; // sig_cpx
      [] { // Attributes
        Attr(#7) { // Code
          2; // max_stack
          2; // max_locals
          Bytes[]{
            0x2A2BB80002AC;
          };
          [] { // Traps
          } // end Traps
          [] { // Attributes
          } // Attributes
        } // end Code
      } // Attributes
    } // Member
  } // methods

  [] { // Attributes
  } // Attributes

} // end class javasoft/sqe/tests/vm/classfmt/atr/atrmtp002/atrmtp00201m1/atrmtp00201m11n

---------------------------------------------------

2) Get Method parameters of "m" method of this class

Method m = Class.forName("\@(packageName).\@(bitest)")
                    .getDeclaredMethod("m", int.class);
Parameter[] pars = m.getParameters();
Comments
Out for review.
31-10-2014

Root cause is hotspot returning null when parameter_count = 0
29-10-2014

In method descriptor of method m we have: Utf8 "(I)V"; // #9 (from Constant Pool) That means that method m is void and have one int parameter. So the parameter_count in MethodParameters attribute should be equal to 1. The correct attributte is 0x0100130000; The first byte in this attribute is the parameter_count. Here it is 1. And the wrong one, that I used, is 0x00; In this case we have parameter_count == 0.
22-10-2014

There is an existing test that supposedly covers this case. Please explain in more detail exactly what the method descriptor contains, what parameters_count should be, and what it is instead.
21-10-2014

Downgraded to P4. Low severity, low likelihood, simple workaround, cannot justify P2 or P3.
19-09-2014