JDK-8014230 : compilation incorrectly succeeds with inner class constructor with 254 parameter
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2013-05-07
  • Updated: 2013-07-25
  • Resolved: 2013-06-27
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 8
8 b98Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
various on JDK 6 and 7

ADDITIONAL OS VERSION INFORMATION :
Windows ver7, but I think this is a general problem

EXTRA RELEVANT SYSTEM CONFIGURATION :
there is no specific configuration information

A DESCRIPTION OF THE PROBLEM :
Instance methods and constructors have an implicit first parameter for this, so the max number of formal parameters is 254, not 255. Inner class constructors have a second implicit formal parameter namely reference to the enclosing instance. I should therefore not be able to declare an inner class constructor with 254 formal parameters. Javac compiles this anyway somehow... At runtime of course there is an error if such a constructor is used.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
class Houter {
    public class Hinner {
        public Hinner(
                                    byte b01, byte b02, byte b03, byte b04, byte b05, byte b06, byte b07, byte b08, byte b09,
                          byte b10, byte b11, byte b12, byte b13, byte b14, byte b15, byte b16, byte b17, byte b18, byte b19,
                          byte b20, byte b21, byte b22, byte b23, byte b24, byte b25, byte b26, byte b27, byte b28, byte b29,
                          byte b30, byte b31, byte b32, byte b33, byte b34, byte b35, byte b36, byte b37, byte b38, byte b39,
                          byte b40, byte b41, byte b42, byte b43, byte b44, byte b45, byte b46, byte b47, byte b48, byte b49,
                          byte b50, byte b51, byte b52, byte b53, byte b54, byte b55, byte b56, byte b57, byte b58, byte b59,
                          byte b60, byte b61, byte b62, byte b63, byte b64, byte b65, byte b66, byte b67, byte b68, byte b69,
                          byte b70, byte b71, byte b72, byte b73, byte b74, byte b75, byte b76, byte b77, byte b78, byte b79,
                          byte b80, byte b81, byte b82, byte b83, byte b84, byte b85, byte b86, byte b87, byte b88, byte b89,
                          byte b90, byte b91, byte b92, byte b93, byte b94, byte b95, byte b96, byte b97, byte b98, byte b99,
                          byte b100, byte b101, byte b102, byte b103, byte b104, byte b105, byte b106, byte b107, byte b108, byte b109,
                          byte b110, byte b111, byte b112, byte b113, byte b114, byte b115, byte b116, byte b117, byte b118, byte b119,
                          byte b120, byte b121, byte b122, byte b123, byte b124, byte b125, byte b126, byte b127, byte b128, byte b129,
                          byte b130, byte b131, byte b132, byte b133, byte b134, byte b135, byte b136, byte b137, byte b138, byte b139,
                          byte b140, byte b141, byte b142, byte b143, byte b144, byte b145, byte b146, byte b147, byte b148, byte b149,
                          byte b150, byte b151, byte b152, byte b153, byte b154, byte b155, byte b156, byte b157, byte b158, byte b159,
                          byte b160, byte b161, byte b162, byte b163, byte b164, byte b165, byte b166, byte b167, byte b168, byte b169,
                          byte b170, byte b171, byte b172, byte b173, byte b174, byte b175, byte b176, byte b177, byte b178, byte b179,
                          byte b180, byte b181, byte b182, byte b183, byte b184, byte b185, byte b186, byte b187, byte b188, byte b189,
                          byte b190, byte b191, byte b192, byte b193, byte b194, byte b195, byte b196, byte b197, byte b198, byte b199,
                          byte b200, byte b201, byte b202, byte b203, byte b204, byte b205, byte b206, byte b207, byte b208, byte b209,
                          byte b210, byte b211, byte b212, byte b213, byte b214, byte b215, byte b216, byte b217, byte b218, byte b219,
                          byte b220, byte b221, byte b222, byte b223, byte b224, byte b225, byte b226, byte b227, byte b228, byte b229,
                          byte b230, byte b231, byte b232, byte b233, byte b234, byte b235, byte b236, byte b237, byte b238, byte b239,
                          byte b240, byte b241, byte b242, byte b243, byte b244, byte b245, byte b246, byte b247, byte b248, byte b249,
                          byte b250, byte b251, byte b252, byte b253, byte b254
                                                 
                     ) {

System.out.println(b01);
System.out.println(b02);
System.out.println(b03);
System.out.println(b04);
System.out.println(b05);
System.out.println(b06);
System.out.println(b07);
System.out.println(b08);
System.out.println(b09);
System.out.println(b10);
System.out.println(b11);
System.out.println(b12);
System.out.println(b13);
System.out.println(b14);
System.out.println(b15);
System.out.println(b16);
System.out.println(b17);
System.out.println(b18);
System.out.println(b19);
System.out.println(b20);
System.out.println(b21);
System.out.println(b22);
System.out.println(b23);
System.out.println(b24);
System.out.println(b25);
System.out.println(b26);
System.out.println(b27);
System.out.println(b28);
System.out.println(b29);
System.out.println(b30);
System.out.println(b31);
System.out.println(b32);
System.out.println(b33);
System.out.println(b34);
System.out.println(b35);
System.out.println(b36);
System.out.println(b37);
System.out.println(b38);
System.out.println(b39);
System.out.println(b40);
System.out.println(b41);
System.out.println(b42);
System.out.println(b43);
System.out.println(b44);
System.out.println(b45);
System.out.println(b46);
System.out.println(b47);
System.out.println(b48);
System.out.println(b49);
System.out.println(b50);
System.out.println(b51);
System.out.println(b52);
System.out.println(b53);
System.out.println(b54);
System.out.println(b55);
System.out.println(b56);
System.out.println(b57);
System.out.println(b58);
System.out.println(b59);
System.out.println(b60);
System.out.println(b61);
System.out.println(b62);
System.out.println(b63);
System.out.println(b64);
System.out.println(b65);
System.out.println(b66);
System.out.println(b67);
System.out.println(b68);
System.out.println(b69);
System.out.println(b70);
System.out.println(b71);
System.out.println(b72);
System.out.println(b73);
System.out.println(b74);
System.out.println(b75);
System.out.println(b76);
System.out.println(b77);
System.out.println(b78);
System.out.println(b79);
System.out.println(b80);
System.out.println(b81);
System.out.println(b82);
System.out.println(b83);
System.out.println(b84);
System.out.println(b85);
System.out.println(b86);
System.out.println(b87);
System.out.println(b88);
System.out.println(b89);
System.out.println(b90);
System.out.println(b91);
System.out.println(b92);
System.out.println(b93);
System.out.println(b94);
System.out.println(b95);
System.out.println(b96);
System.out.println(b97);
System.out.println(b98);
System.out.println(b99);
System.out.println(b100);
System.out.println(b101);
System.out.println(b102);
System.out.println(b103);
System.out.println(b104);
System.out.println(b105);
System.out.println(b106);
System.out.println(b107);
System.out.println(b108);
System.out.println(b109);
System.out.println(b110);
System.out.println(b111);
System.out.println(b112);
System.out.println(b113);
System.out.println(b114);
System.out.println(b115);
System.out.println(b116);
System.out.println(b117);
System.out.println(b118);
System.out.println(b119);
System.out.println(b120);
System.out.println(b121);
System.out.println(b122);
System.out.println(b123);
System.out.println(b124);
System.out.println(b125);
System.out.println(b126);
System.out.println(b127);
System.out.println(b128);
System.out.println(b129);
System.out.println(b130);
System.out.println(b131);
System.out.println(b132);
System.out.println(b133);
System.out.println(b134);
System.out.println(b135);
System.out.println(b136);
System.out.println(b137);
System.out.println(b138);
System.out.println(b139);
System.out.println(b140);
System.out.println(b141);
System.out.println(b142);
System.out.println(b143);
System.out.println(b144);
System.out.println(b145);
System.out.println(b146);
System.out.println(b147);
System.out.println(b148);
System.out.println(b149);
System.out.println(b150);
System.out.println(b151);
System.out.println(b152);
System.out.println(b153);
System.out.println(b154);
System.out.println(b155);
System.out.println(b156);
System.out.println(b157);
System.out.println(b158);
System.out.println(b159);
System.out.println(b160);
System.out.println(b161);
System.out.println(b162);
System.out.println(b163);
System.out.println(b164);
System.out.println(b165);
System.out.println(b166);
System.out.println(b167);
System.out.println(b168);
System.out.println(b169);
System.out.println(b170);
System.out.println(b171);
System.out.println(b172);
System.out.println(b173);
System.out.println(b174);
System.out.println(b175);
System.out.println(b176);
System.out.println(b177);
System.out.println(b178);
System.out.println(b179);
System.out.println(b180);
System.out.println(b181);
System.out.println(b182);
System.out.println(b183);
System.out.println(b184);
System.out.println(b185);
System.out.println(b186);
System.out.println(b187);
System.out.println(b188);
System.out.println(b189);
System.out.println(b190);
System.out.println(b191);
System.out.println(b192);
System.out.println(b193);
System.out.println(b194);
System.out.println(b195);
System.out.println(b196);
System.out.println(b197);
System.out.println(b198);
System.out.println(b199);
System.out.println(b200);
System.out.println(b201);
System.out.println(b202);
System.out.println(b203);
System.out.println(b204);
System.out.println(b205);
System.out.println(b206);
System.out.println(b207);
System.out.println(b208);
System.out.println(b209);
System.out.println(b210);
System.out.println(b211);
System.out.println(b212);
System.out.println(b213);
System.out.println(b214);
System.out.println(b215);
System.out.println(b216);
System.out.println(b217);
System.out.println(b218);
System.out.println(b219);
System.out.println(b220);
System.out.println(b221);
System.out.println(b222);
System.out.println(b223);
System.out.println(b224);
System.out.println(b225);
System.out.println(b226);
System.out.println(b227);
System.out.println(b228);
System.out.println(b229);
System.out.println(b230);
System.out.println(b231);
System.out.println(b232);
System.out.println(b233);
System.out.println(b234);
System.out.println(b235);
System.out.println(b236);
System.out.println(b237);
System.out.println(b238);
System.out.println(b239);
System.out.println(b240);
System.out.println(b241);
System.out.println(b242);
System.out.println(b243);
System.out.println(b244);
System.out.println(b245);
System.out.println(b246);
System.out.println(b247);
System.out.println(b248);
System.out.println(b249);
System.out.println(b250);
System.out.println(b251);
System.out.println(b252);
System.out.println(b253);
System.out.println(b254);
        }


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
javac should not allow compilation to succeed!
ACTUAL -
javac allows compilation to succeed.

At runtime:
java.lang.VerifyError

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.VerifyError: (class: Bontoso/Exe, method: main signature: ([Ljava/lang/String;)V) Signature (LBontoso/Houter;BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB)V has too many arguments
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2442)
at java.lang.Class.getMethod0(Class.java:2685)
at java.lang.Class.getMethod(Class.java:1620)
at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:484)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:476)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
see above
---------- END SOURCE ----------
Comments
The submitter is correct. javac should accept one fewer formal parameter declaration in the constructor of a certain kind of inner class than it accepts in the constructor of a top-level class. (When I say "a certain kind of inner class", I mean i) a non-private inner member class, and ii) an anonymous class whose superclass is inner.) In the ClassFile structure, a method descriptor for an instance method (such as an <init> method which represents a Java constructor) can express at most 255 parameters. One parameter is always expressed without being explicitly denoted, namely the receiver object. (For a constructor, this is the newly created instance.) Accordingly, a method descriptor for an instance method can denote the types of at most 254 parameters. When a Java compiler emits an <init> method for a certain kind of inner class, the method descriptor must denote the type of a parameter representing the enclosing instance. (In the Java language, this parameter is "implicitly declared".) Thus, the method descriptor can denote 253 more parameters. The Hinner class has 254 parameters, but only 253 can be denoted, so a Java compiler must reject the class (JLS 13.1). Assuming that a compiler lets the Hinner class slip through, the question arises of what runtime error is required. The method_info structure for the <init> method of the Houter$Hinner class will point to an illegal method descriptor. (javap shows "locals=256, args_size=256" - 256 locals is OK, 256 args is not.) Therefore, the class should not even load. HotSpot in JDK8 correctly throws a ClassFormatError when Houter$Hinner is defined. The submitter indicates that a VerifyError occurs (I assume when Houter$Hinner is defined) which indicates class format checking is excessively lazy.
17-06-2013

A fix is prepared for this particular issue.
14-06-2013

This bug actually identifies a class of errors. The most general statement of the bug might be "javac attempts to generate methods with too many parameters". Note that addition of synthesized/mandated parameters may push the number of parameters over the limit. Detection of this condition needs to happen *after* addition of synthetic/mandated parameters, preferably just before lowering. Also, capture of instance variables means that the "safe" number of parameters may vary. Also, it may be possible to capture too many instance variables.
13-06-2013