From alex.buckley at oracle.com Mon Aug 5 17:23:43 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 05 Aug 2013 17:23:43 -0700 Subject: Minor spec reorganization Message-ID: <5200420F.7030002@oracle.com> I have renumbered JLS 9.7 in the spec to JLS 9.7.5, in anticipation of changes for type annotations (JSR 308). In a similar vein, JLS 9.6.3.1 (@Target) no longer appears here, but will appear in the JSR 308 spec. The spec is at http://cr.openjdk.java.net/~abuckley/8misc.pdf as always. Alex From eric.mccorkle at oracle.com Mon Aug 19 14:57:00 2013 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Mon, 19 Aug 2013 17:57:00 -0400 Subject: Method Parameter Reflection spec Message-ID: <521294AC.2090807@oracle.com> The current version of the spec indicates that methods in java.lang.reflect.Parameter should throw ReflectiveOperationException for several cases (wrong number of parameters, bad parameter name, bad constant pool index). I'd like to suggest two (separate) minor revisions: 1) Executable.getParameters() should throw the ReflectiveOperationException in the case of an invalid name or the wrong number of parameters. The rationale is as follows: * Doing it this way makes it straightforward to implement j.l.r.Parameter as an immutable object. Having methods in Parameter throw the exception means Parameter objects will have to remember whether or not they have verified their name (or else verify the name every time they are called). * Having every single method in Parameter possibly check whether the number of parameters that were returned from the VM is correct seems rather awkward, as opposed to having a single check when Executable obtains the Parameter array back from the VM. 2) In the event of a bad constant pool index, an IllegalArgumentException. * The current behavior of hotspot whenever it expects a UTF-8 constant pool entry, but sees either an out-of-bounds index or something other than a UTF-8 is to throw an IllegalArgumentException. From alex.buckley at oracle.com Mon Aug 19 15:12:58 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 19 Aug 2013 15:12:58 -0700 Subject: Method Parameter Reflection spec In-Reply-To: <521294AC.2090807@oracle.com> References: <521294AC.2090807@oracle.com> Message-ID: <5212986A.6040704@oracle.com> The 8misc.pdf file doesn't say anything about bad constant pool indexes. If MethodParameters was an attribute that the JVM is required to recognize and correctly read, then the JVM would be required to throw ClassFormatError for bad constant pool indexes. But since MethodParameters is an attribute that the class libraries of the Java SE platform - as opposed to the JVM - are required to recognize and correctly read, it's the responsibility of the class libraries to throw something which is a) useful and b) consistent with bad constant pool indexes for similar situations such as AnnotatedElement#getAnnotations on a RuntimeVisibleAnnotations attribute. How the class libraries interact with a JVM implementation to determine good or bad constant pool entries (e.g. private functions of the JVM implementation throw IllegalArgumentException, which AnnotatedElement#getAnnotations then wraps as a FooBarException) is not a matter for the SE API specification. The only thing that matters for the SE API specification is what something like AnnotatedElement#getAnnotations is specified to throw today. Alex On 8/19/2013 2:57 PM, Eric McCorkle wrote: > The current version of the spec indicates that methods in > java.lang.reflect.Parameter should throw ReflectiveOperationException > for several cases (wrong number of parameters, bad parameter name, bad > constant pool index). > > I'd like to suggest two (separate) minor revisions: > > 1) Executable.getParameters() should throw the > ReflectiveOperationException in the case of an invalid name or the wrong > number of parameters. The rationale is as follows: > > * Doing it this way makes it straightforward to implement > j.l.r.Parameter as an immutable object. Having methods in Parameter > throw the exception means Parameter objects will have to remember > whether or not they have verified their name (or else verify the name > every time they are called). > > * Having every single method in Parameter possibly check whether the > number of parameters that were returned from the VM is correct seems > rather awkward, as opposed to having a single check when Executable > obtains the Parameter array back from the VM. > > 2) In the event of a bad constant pool index, an IllegalArgumentException. > > * The current behavior of hotspot whenever it expects a UTF-8 constant > pool entry, but sees either an out-of-bounds index or something other > than a UTF-8 is to throw an IllegalArgumentException. > From eric.mccorkle at oracle.com Tue Aug 20 12:10:23 2013 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Tue, 20 Aug 2013 15:10:23 -0400 Subject: Method Parameter Reflection spec In-Reply-To: <5212986A.6040704@oracle.com> References: <521294AC.2090807@oracle.com> <5212986A.6040704@oracle.com> Message-ID: <5213BF1F.6050502@oracle.com> Okay, strike #2 from my requests. What about having Executable.getParameters() throw ReflectiveOperationException instead of methods in Parameter, for the reasons I discuss? On 08/19/13 18:12, Alex Buckley wrote: > The 8misc.pdf file doesn't say anything about bad constant pool indexes. > > If MethodParameters was an attribute that the JVM is required to > recognize and correctly read, then the JVM would be required to throw > ClassFormatError for bad constant pool indexes. But since > MethodParameters is an attribute that the class libraries of the Java SE > platform - as opposed to the JVM - are required to recognize and > correctly read, it's the responsibility of the class libraries to throw > something which is a) useful and b) consistent with bad constant pool > indexes for similar situations such as AnnotatedElement#getAnnotations > on a RuntimeVisibleAnnotations attribute. > > How the class libraries interact with a JVM implementation to determine > good or bad constant pool entries (e.g. private functions of the JVM > implementation throw IllegalArgumentException, which > AnnotatedElement#getAnnotations then wraps as a FooBarException) is not > a matter for the SE API specification. The only thing that matters for > the SE API specification is what something like > AnnotatedElement#getAnnotations is specified to throw today. > > Alex > > On 8/19/2013 2:57 PM, Eric McCorkle wrote: >> The current version of the spec indicates that methods in >> java.lang.reflect.Parameter should throw ReflectiveOperationException >> for several cases (wrong number of parameters, bad parameter name, bad >> constant pool index). >> >> I'd like to suggest two (separate) minor revisions: >> >> 1) Executable.getParameters() should throw the >> ReflectiveOperationException in the case of an invalid name or the wrong >> number of parameters. The rationale is as follows: >> >> * Doing it this way makes it straightforward to implement >> j.l.r.Parameter as an immutable object. Having methods in Parameter >> throw the exception means Parameter objects will have to remember >> whether or not they have verified their name (or else verify the name >> every time they are called). >> >> * Having every single method in Parameter possibly check whether the >> number of parameters that were returned from the VM is correct seems >> rather awkward, as opposed to having a single check when Executable >> obtains the Parameter array back from the VM. >> >> 2) In the event of a bad constant pool index, an >> IllegalArgumentException. >> >> * The current behavior of hotspot whenever it expects a UTF-8 constant >> pool entry, but sees either an out-of-bounds index or something other >> than a UTF-8 is to throw an IllegalArgumentException. >> From alex.buckley at oracle.com Tue Aug 20 12:38:27 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 20 Aug 2013 12:38:27 -0700 Subject: Method Parameter Reflection spec In-Reply-To: <5213BF1F.6050502@oracle.com> References: <521294AC.2090807@oracle.com> <5212986A.6040704@oracle.com> <5213BF1F.6050502@oracle.com> Message-ID: <5213C5B3.9010609@oracle.com> The precedent is AnnotatedElement#getAnnotations as found in Class, Field, Executable, etc. Do those methods validate the RuntimeVisibleAnnotations attribute before returning an array of Annotation objects? I think they do. Can you describe the validation they do which may cause an AnnotationTypeMismatchException or IncompleteAnnotationException? If their validation is "equivalent" to what Executable#getParameters would do, then it would be acceptable to change the spec and implementation of Executable#getParameters and Parameter#getName/Type/etc at this late stage. Please comment ASAP. Alex On 8/20/2013 12:10 PM, Eric McCorkle wrote: > Okay, strike #2 from my requests. What about having > Executable.getParameters() throw ReflectiveOperationException instead of > methods in Parameter, for the reasons I discuss? > > On 08/19/13 18:12, Alex Buckley wrote: >> The 8misc.pdf file doesn't say anything about bad constant pool indexes. >> >> If MethodParameters was an attribute that the JVM is required to >> recognize and correctly read, then the JVM would be required to throw >> ClassFormatError for bad constant pool indexes. But since >> MethodParameters is an attribute that the class libraries of the Java SE >> platform - as opposed to the JVM - are required to recognize and >> correctly read, it's the responsibility of the class libraries to throw >> something which is a) useful and b) consistent with bad constant pool >> indexes for similar situations such as AnnotatedElement#getAnnotations >> on a RuntimeVisibleAnnotations attribute. >> >> How the class libraries interact with a JVM implementation to determine >> good or bad constant pool entries (e.g. private functions of the JVM >> implementation throw IllegalArgumentException, which >> AnnotatedElement#getAnnotations then wraps as a FooBarException) is not >> a matter for the SE API specification. The only thing that matters for >> the SE API specification is what something like >> AnnotatedElement#getAnnotations is specified to throw today. >> >> Alex >> >> On 8/19/2013 2:57 PM, Eric McCorkle wrote: >>> The current version of the spec indicates that methods in >>> java.lang.reflect.Parameter should throw ReflectiveOperationException >>> for several cases (wrong number of parameters, bad parameter name, bad >>> constant pool index). >>> >>> I'd like to suggest two (separate) minor revisions: >>> >>> 1) Executable.getParameters() should throw the >>> ReflectiveOperationException in the case of an invalid name or the wrong >>> number of parameters. The rationale is as follows: >>> >>> * Doing it this way makes it straightforward to implement >>> j.l.r.Parameter as an immutable object. Having methods in Parameter >>> throw the exception means Parameter objects will have to remember >>> whether or not they have verified their name (or else verify the name >>> every time they are called). >>> >>> * Having every single method in Parameter possibly check whether the >>> number of parameters that were returned from the VM is correct seems >>> rather awkward, as opposed to having a single check when Executable >>> obtains the Parameter array back from the VM. >>> >>> 2) In the event of a bad constant pool index, an >>> IllegalArgumentException. >>> >>> * The current behavior of hotspot whenever it expects a UTF-8 constant >>> pool entry, but sees either an out-of-bounds index or something other >>> than a UTF-8 is to throw an IllegalArgumentException. >>> From eric.mccorkle at oracle.com Tue Aug 20 13:41:34 2013 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Tue, 20 Aug 2013 16:41:34 -0400 Subject: Method Parameter Reflection spec In-Reply-To: <5213C5B3.9010609@oracle.com> References: <521294AC.2090807@oracle.com> <5212986A.6040704@oracle.com> <5213BF1F.6050502@oracle.com> <5213C5B3.9010609@oracle.com> Message-ID: <5213D47E.9040607@oracle.com> getAnnotations for each of these calls out to AnnotationParser, which does indeed throw an AnnotationFormatError in a variety of cases (duplicated annotations, malformed or incomplete annotations, etc). In other cases (ie type mismatches), it delays throwing of exceptions. Exceptions coming from the VM (illegal access, bad constant pool indexes, parameter mismatches, class casts, and the like) are caught and rethrown as AnnotationFormatErrors. In light of this, I'm going to argue the precedent's there. General formatting issues (which I'll argue covers bad names and wrong numbers of parameters) cause errors to be thrown immediately, and the completely analogous case of a bad constant pool index does cause an error to be thrown immediately. I'll also put forward that parameters are a bit different, and favor the approach of having Executable.getParameters() be able to throw exceptions for bad formatting. Annotations are generally complex, with far more complex correctness conditions, and far higher cost to transform them from their storage format to reflective objects. It makes sense to defer some of this processing. MethodParameters, on the other hand, are very simple, and the main use case is to get the names of parameters. Therefore, the spec ought to imply, or at least allow for an implementation that makes a single trip to the VM per method, after which the names are immediately available. (Also, there are several practical advantages to allowing Parameter to be an immutable object that cannot be subclassed...) On 08/20/13 15:38, Alex Buckley wrote: > The precedent is AnnotatedElement#getAnnotations as found in Class, > Field, Executable, etc. Do those methods validate the > RuntimeVisibleAnnotations attribute before returning an array of > Annotation objects? I think they do. Can you describe the validation > they do which may cause an AnnotationTypeMismatchException or > IncompleteAnnotationException? > > If their validation is "equivalent" to what Executable#getParameters > would do, then it would be acceptable to change the spec and > implementation of Executable#getParameters and > Parameter#getName/Type/etc at this late stage. Please comment ASAP. > > Alex > > On 8/20/2013 12:10 PM, Eric McCorkle wrote: >> Okay, strike #2 from my requests. What about having >> Executable.getParameters() throw ReflectiveOperationException instead of >> methods in Parameter, for the reasons I discuss? >> >> On 08/19/13 18:12, Alex Buckley wrote: >>> The 8misc.pdf file doesn't say anything about bad constant pool indexes. >>> >>> If MethodParameters was an attribute that the JVM is required to >>> recognize and correctly read, then the JVM would be required to throw >>> ClassFormatError for bad constant pool indexes. But since >>> MethodParameters is an attribute that the class libraries of the Java SE >>> platform - as opposed to the JVM - are required to recognize and >>> correctly read, it's the responsibility of the class libraries to throw >>> something which is a) useful and b) consistent with bad constant pool >>> indexes for similar situations such as AnnotatedElement#getAnnotations >>> on a RuntimeVisibleAnnotations attribute. >>> >>> How the class libraries interact with a JVM implementation to determine >>> good or bad constant pool entries (e.g. private functions of the JVM >>> implementation throw IllegalArgumentException, which >>> AnnotatedElement#getAnnotations then wraps as a FooBarException) is not >>> a matter for the SE API specification. The only thing that matters for >>> the SE API specification is what something like >>> AnnotatedElement#getAnnotations is specified to throw today. >>> >>> Alex >>> >>> On 8/19/2013 2:57 PM, Eric McCorkle wrote: >>>> The current version of the spec indicates that methods in >>>> java.lang.reflect.Parameter should throw ReflectiveOperationException >>>> for several cases (wrong number of parameters, bad parameter name, bad >>>> constant pool index). >>>> >>>> I'd like to suggest two (separate) minor revisions: >>>> >>>> 1) Executable.getParameters() should throw the >>>> ReflectiveOperationException in the case of an invalid name or the >>>> wrong >>>> number of parameters. The rationale is as follows: >>>> >>>> * Doing it this way makes it straightforward to implement >>>> j.l.r.Parameter as an immutable object. Having methods in Parameter >>>> throw the exception means Parameter objects will have to remember >>>> whether or not they have verified their name (or else verify the name >>>> every time they are called). >>>> >>>> * Having every single method in Parameter possibly check whether the >>>> number of parameters that were returned from the VM is correct seems >>>> rather awkward, as opposed to having a single check when Executable >>>> obtains the Parameter array back from the VM. >>>> >>>> 2) In the event of a bad constant pool index, an >>>> IllegalArgumentException. >>>> >>>> * The current behavior of hotspot whenever it expects a UTF-8 >>>> constant >>>> pool entry, but sees either an out-of-bounds index or something other >>>> than a UTF-8 is to throw an IllegalArgumentException. >>>> From alex.buckley at oracle.com Tue Aug 20 15:10:12 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 20 Aug 2013 15:10:12 -0700 Subject: Method Parameter Reflection spec In-Reply-To: <5213D47E.9040607@oracle.com> References: <521294AC.2090807@oracle.com> <5212986A.6040704@oracle.com> <5213BF1F.6050502@oracle.com> <5213C5B3.9010609@oracle.com> <5213D47E.9040607@oracle.com> Message-ID: <5213E944.7050401@oracle.com> Sounds good. I'd wait a day in case Joe has a comment, then do it. Please send a summary to this list of which exceptions are thrown by Executable#getParameters and for what reasons. This will let me record some more color in section 2.3 of 8misc.pdf, above and beyond the change from: Methods of class java.lang.reflect.Parameter must throw ReflectiveOperationException if ... to: java.lang.reflect.Executable#getParameters must throw ReflectiveOperationException if ... Alex On 8/20/2013 1:41 PM, Eric McCorkle wrote: > getAnnotations for each of these calls out to AnnotationParser, which > does indeed throw an AnnotationFormatError in a variety of cases > (duplicated annotations, malformed or incomplete annotations, etc). In > other cases (ie type mismatches), it delays throwing of exceptions. > Exceptions coming from the VM (illegal access, bad constant pool > indexes, parameter mismatches, class casts, and the like) are caught and > rethrown as AnnotationFormatErrors. > > In light of this, I'm going to argue the precedent's there. General > formatting issues (which I'll argue covers bad names and wrong numbers > of parameters) cause errors to be thrown immediately, and the completely > analogous case of a bad constant pool index does cause an error to be > thrown immediately. > > I'll also put forward that parameters are a bit different, and favor the > approach of having Executable.getParameters() be able to throw > exceptions for bad formatting. Annotations are generally complex, with > far more complex correctness conditions, and far higher cost to > transform them from their storage format to reflective objects. It > makes sense to defer some of this processing. MethodParameters, on the > other hand, are very simple, and the main use case is to get the names > of parameters. Therefore, the spec ought to imply, or at least allow > for an implementation that makes a single trip to the VM per method, > after which the names are immediately available. (Also, there are > several practical advantages to allowing Parameter to be an immutable > object that cannot be subclassed...) > > On 08/20/13 15:38, Alex Buckley wrote: >> The precedent is AnnotatedElement#getAnnotations as found in Class, >> Field, Executable, etc. Do those methods validate the >> RuntimeVisibleAnnotations attribute before returning an array of >> Annotation objects? I think they do. Can you describe the validation >> they do which may cause an AnnotationTypeMismatchException or >> IncompleteAnnotationException? >> >> If their validation is "equivalent" to what Executable#getParameters >> would do, then it would be acceptable to change the spec and >> implementation of Executable#getParameters and >> Parameter#getName/Type/etc at this late stage. Please comment ASAP. >> >> Alex >> >> On 8/20/2013 12:10 PM, Eric McCorkle wrote: >>> Okay, strike #2 from my requests. What about having >>> Executable.getParameters() throw ReflectiveOperationException instead of >>> methods in Parameter, for the reasons I discuss? >>> >>> On 08/19/13 18:12, Alex Buckley wrote: >>>> The 8misc.pdf file doesn't say anything about bad constant pool indexes. >>>> >>>> If MethodParameters was an attribute that the JVM is required to >>>> recognize and correctly read, then the JVM would be required to throw >>>> ClassFormatError for bad constant pool indexes. But since >>>> MethodParameters is an attribute that the class libraries of the Java SE >>>> platform - as opposed to the JVM - are required to recognize and >>>> correctly read, it's the responsibility of the class libraries to throw >>>> something which is a) useful and b) consistent with bad constant pool >>>> indexes for similar situations such as AnnotatedElement#getAnnotations >>>> on a RuntimeVisibleAnnotations attribute. >>>> >>>> How the class libraries interact with a JVM implementation to determine >>>> good or bad constant pool entries (e.g. private functions of the JVM >>>> implementation throw IllegalArgumentException, which >>>> AnnotatedElement#getAnnotations then wraps as a FooBarException) is not >>>> a matter for the SE API specification. The only thing that matters for >>>> the SE API specification is what something like >>>> AnnotatedElement#getAnnotations is specified to throw today. >>>> >>>> Alex >>>> >>>> On 8/19/2013 2:57 PM, Eric McCorkle wrote: >>>>> The current version of the spec indicates that methods in >>>>> java.lang.reflect.Parameter should throw ReflectiveOperationException >>>>> for several cases (wrong number of parameters, bad parameter name, bad >>>>> constant pool index). >>>>> >>>>> I'd like to suggest two (separate) minor revisions: >>>>> >>>>> 1) Executable.getParameters() should throw the >>>>> ReflectiveOperationException in the case of an invalid name or the >>>>> wrong >>>>> number of parameters. The rationale is as follows: >>>>> >>>>> * Doing it this way makes it straightforward to implement >>>>> j.l.r.Parameter as an immutable object. Having methods in Parameter >>>>> throw the exception means Parameter objects will have to remember >>>>> whether or not they have verified their name (or else verify the name >>>>> every time they are called). >>>>> >>>>> * Having every single method in Parameter possibly check whether the >>>>> number of parameters that were returned from the VM is correct seems >>>>> rather awkward, as opposed to having a single check when Executable >>>>> obtains the Parameter array back from the VM. >>>>> >>>>> 2) In the event of a bad constant pool index, an >>>>> IllegalArgumentException. >>>>> >>>>> * The current behavior of hotspot whenever it expects a UTF-8 >>>>> constant >>>>> pool entry, but sees either an out-of-bounds index or something other >>>>> than a UTF-8 is to throw an IllegalArgumentException. >>>>> From eric.mccorkle at oracle.com Wed Aug 21 08:04:11 2013 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Wed, 21 Aug 2013 11:04:11 -0400 Subject: Method Parameter Reflection spec In-Reply-To: <5213E944.7050401@oracle.com> References: <521294AC.2090807@oracle.com> <5212986A.6040704@oracle.com> <5213BF1F.6050502@oracle.com> <5213C5B3.9010609@oracle.com> <5213D47E.9040607@oracle.com> <5213E944.7050401@oracle.com> Message-ID: <5214D6EB.2020007@oracle.com> I will give Joe a day to add his comments. Here's a list of all the ways MethodParameters attributes could go wrong: (i) Actual length does not match attribute_length (ii) The number of parameters (parameter_count) is wrong for the method (iii) A constant pool index is out of bounds. (iv) A constant pool index does not refer to a UTF-8 entry (v) A parameter's name is "", or contains an illegal character [0] (vi) The flags field contains an illegal flag (something other than FINAL, SYNTHETIC, or MANDATED) (i) causes a ClassFileFormatError when parsing the class file (as it should). Right now, (iii) and (iv) cause an IllegalArgumentException to be thrown. I am working on a patch to correct the behavior for (ii)-(vi), so I can have Executable.getParameters() throw whatever exception you choose (ie. this is one of those rare moments of freedom). [0]: I seem to recall there being some discussion about backspaces, but the current version doesn't seem to rule them out. Has this been changed? On 08/20/13 18:10, Alex Buckley wrote: > Sounds good. I'd wait a day in case Joe has a comment, then do it. > Please send a summary to this list of which exceptions are thrown by > Executable#getParameters and for what reasons. This will let me record > some more color in section 2.3 of 8misc.pdf, above and beyond the change > from: > > Methods of class java.lang.reflect.Parameter must throw > ReflectiveOperationException if ... > > to: > > java.lang.reflect.Executable#getParameters must throw > ReflectiveOperationException if ... > > Alex > > On 8/20/2013 1:41 PM, Eric McCorkle wrote: >> getAnnotations for each of these calls out to AnnotationParser, which >> does indeed throw an AnnotationFormatError in a variety of cases >> (duplicated annotations, malformed or incomplete annotations, etc). In >> other cases (ie type mismatches), it delays throwing of exceptions. >> Exceptions coming from the VM (illegal access, bad constant pool >> indexes, parameter mismatches, class casts, and the like) are caught and >> rethrown as AnnotationFormatErrors. >> >> In light of this, I'm going to argue the precedent's there. General >> formatting issues (which I'll argue covers bad names and wrong numbers >> of parameters) cause errors to be thrown immediately, and the completely >> analogous case of a bad constant pool index does cause an error to be >> thrown immediately. >> >> I'll also put forward that parameters are a bit different, and favor the >> approach of having Executable.getParameters() be able to throw >> exceptions for bad formatting. Annotations are generally complex, with >> far more complex correctness conditions, and far higher cost to >> transform them from their storage format to reflective objects. It >> makes sense to defer some of this processing. MethodParameters, on the >> other hand, are very simple, and the main use case is to get the names >> of parameters. Therefore, the spec ought to imply, or at least allow >> for an implementation that makes a single trip to the VM per method, >> after which the names are immediately available. (Also, there are >> several practical advantages to allowing Parameter to be an immutable >> object that cannot be subclassed...) >> >> On 08/20/13 15:38, Alex Buckley wrote: >>> The precedent is AnnotatedElement#getAnnotations as found in Class, >>> Field, Executable, etc. Do those methods validate the >>> RuntimeVisibleAnnotations attribute before returning an array of >>> Annotation objects? I think they do. Can you describe the validation >>> they do which may cause an AnnotationTypeMismatchException or >>> IncompleteAnnotationException? >>> >>> If their validation is "equivalent" to what Executable#getParameters >>> would do, then it would be acceptable to change the spec and >>> implementation of Executable#getParameters and >>> Parameter#getName/Type/etc at this late stage. Please comment ASAP. >>> >>> Alex >>> >>> On 8/20/2013 12:10 PM, Eric McCorkle wrote: >>>> Okay, strike #2 from my requests. What about having >>>> Executable.getParameters() throw ReflectiveOperationException >>>> instead of >>>> methods in Parameter, for the reasons I discuss? >>>> >>>> On 08/19/13 18:12, Alex Buckley wrote: >>>>> The 8misc.pdf file doesn't say anything about bad constant pool >>>>> indexes. >>>>> >>>>> If MethodParameters was an attribute that the JVM is required to >>>>> recognize and correctly read, then the JVM would be required to throw >>>>> ClassFormatError for bad constant pool indexes. But since >>>>> MethodParameters is an attribute that the class libraries of the >>>>> Java SE >>>>> platform - as opposed to the JVM - are required to recognize and >>>>> correctly read, it's the responsibility of the class libraries to >>>>> throw >>>>> something which is a) useful and b) consistent with bad constant pool >>>>> indexes for similar situations such as AnnotatedElement#getAnnotations >>>>> on a RuntimeVisibleAnnotations attribute. >>>>> >>>>> How the class libraries interact with a JVM implementation to >>>>> determine >>>>> good or bad constant pool entries (e.g. private functions of the JVM >>>>> implementation throw IllegalArgumentException, which >>>>> AnnotatedElement#getAnnotations then wraps as a FooBarException) is >>>>> not >>>>> a matter for the SE API specification. The only thing that matters for >>>>> the SE API specification is what something like >>>>> AnnotatedElement#getAnnotations is specified to throw today. >>>>> >>>>> Alex >>>>> >>>>> On 8/19/2013 2:57 PM, Eric McCorkle wrote: >>>>>> The current version of the spec indicates that methods in >>>>>> java.lang.reflect.Parameter should throw ReflectiveOperationException >>>>>> for several cases (wrong number of parameters, bad parameter name, >>>>>> bad >>>>>> constant pool index). >>>>>> >>>>>> I'd like to suggest two (separate) minor revisions: >>>>>> >>>>>> 1) Executable.getParameters() should throw the >>>>>> ReflectiveOperationException in the case of an invalid name or the >>>>>> wrong >>>>>> number of parameters. The rationale is as follows: >>>>>> >>>>>> * Doing it this way makes it straightforward to implement >>>>>> j.l.r.Parameter as an immutable object. Having methods in Parameter >>>>>> throw the exception means Parameter objects will have to remember >>>>>> whether or not they have verified their name (or else verify the name >>>>>> every time they are called). >>>>>> >>>>>> * Having every single method in Parameter possibly check >>>>>> whether the >>>>>> number of parameters that were returned from the VM is correct seems >>>>>> rather awkward, as opposed to having a single check when Executable >>>>>> obtains the Parameter array back from the VM. >>>>>> >>>>>> 2) In the event of a bad constant pool index, an >>>>>> IllegalArgumentException. >>>>>> >>>>>> * The current behavior of hotspot whenever it expects a UTF-8 >>>>>> constant >>>>>> pool entry, but sees either an out-of-bounds index or something other >>>>>> than a UTF-8 is to throw an IllegalArgumentException. >>>>>> From alex.buckley at oracle.com Thu Aug 22 12:11:52 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 22 Aug 2013 12:11:52 -0700 Subject: Method Parameter Reflection spec In-Reply-To: <5214D6EB.2020007@oracle.com> References: <521294AC.2090807@oracle.com> <5212986A.6040704@oracle.com> <5213BF1F.6050502@oracle.com> <5213C5B3.9010609@oracle.com> <5213D47E.9040607@oracle.com> <5213E944.7050401@oracle.com> <5214D6EB.2020007@oracle.com> Message-ID: <52166278.7090109@oracle.com> On 8/21/2013 8:04 AM, Eric McCorkle wrote: > I will give Joe a day to add his comments. You may have to ping Joe directly. > Here's a list of all the ways MethodParameters attributes could go wrong: > > (i) Actual length does not match attribute_length > (ii) The number of parameters (parameter_count) is wrong for the method > (iii) A constant pool index is out of bounds. > (iv) A constant pool index does not refer to a UTF-8 entry > (v) A parameter's name is "", or contains an illegal character [0] > (vi) The flags field contains an illegal flag (something other than > FINAL, SYNTHETIC, or MANDATED) > > (i) causes a ClassFileFormatError when parsing the class file (as it > should). Right now, (iii) and (iv) cause an IllegalArgumentException to > be thrown. Does an inaccurate attribute_length item in a RuntimeVisibleAnnotations attribute cause a CFE from HotSpot when the class file is loaded? How about in an InnerClasses attribute? I am not at all sure that the Java Virtual Machine should ever throw a CFE for these attributes. > I am working on a patch to correct the behavior for (ii)-(vi), so I can > have Executable.getParameters() throw whatever exception you choose (ie. > this is one of those rare moments of freedom). I no longer think ReflectiveOperationException is appropriate to throw from anything parameter-related. I think the best option is a parameter-oriented version of AnnotationFormatError, but under RuntimeException rather than Error. AttributeFormatException maybe. Sidebar: Why is AnnotationFormatError an Error? JLS 11 says an Error indicates an exception from which programs are not ordinarily expected to recover, but a reflective client can surely cope with a malformed annotation. I would agree AnnotationFormatError is kinda sorta a cousin of LinkageError, but in my view it should have been a RuntimeException. > [0]: I seem to recall there being some discussion about backspaces, but > the current version doesn't seem to rule them out. Has this been changed? I remember very little without a URL to a spec or mailing list thread :-) Alex From srikanth_sankaran at in.ibm.com Mon Aug 26 11:56:28 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Tue, 27 Aug 2013 00:26:28 +0530 Subject: enhanced-metadata-spec-discuss Digest, Vol 12, Issue 4 In-Reply-To: References: Message-ID: Hello ! I am trying to understand certain scenarios where javac 8b100 seems to deviate from the spec. (1) For the following case: // -- public class X { void foo() { class Local { } } } // -- why would javac emit a mandated formal parameter as in X$1Local(X); descriptor: (LX;)V flags: Code: stack=2, locals=2, args_size=2 0: aload_0 1: aload_1 2: putfield #1 // Field this$0:LX; 5: aload_0 6: invokespecial #2 // Method java/lang/Object." :()V 9: return LineNumberTable: line 3: 0 MethodParameters: Name Flags this$0 final mandated // -- I would think this is covered by "The local/ anonymous class is necessarily emitted by the same compiler as the class instance creation expression. That compiler can represent the immediately enclosing instance how ever it wishes. There is no need for the Java programming language to implicitly declare a parameter in the local/anonymous class's constructor." and so the parameter need not be mandated ? However, per 13.1 we have: A construct emitted by a Java compiler must be marked as mandated if it corresponds to a formal parameter declared implicitly in source code (?8.8.9, ?8.9.2, ?15.9.5.1) and per a reading of 15.9.5.1. seems to imply that this$0 above should be mandated, since class Local is not occurring in a static context. (2) 8.8.9 point 3) reads: In a class instance creation expression for an anonymous class, and where the anonymous class's superclass is inner, ?15.9.2 specifies the immediately enclosing instance with respect to the superclass. Similar to (1), the superclass may have been emitted by a compiler which is different than the compiler of the class instance creation expression. Therefore, there must be a standard way for the compiler of the creation expression to pass a reference (representing the immediately enclosing instance with respect to the superclass) to the superclass's constructor. Consequently, the Java programming language deems that an anonymous class's constructor implicitly declares an initial parameter for the immediately enclosing instance with respect to the superclass. 8b100's behavior is confusing on the following code: // -- public class X { void foo() { new Y().new Z() { }; } } class Y { class Z {} } // -- final X this$0; descriptor: LX; flags: ACC_FINAL, ACC_SYNTHETIC X$1(X, Y); descriptor: (LX;LY;)V flags: Code: stack=3, locals=3, args_size=3 0: aload_0 1: aload_1 2: putfield #1 // Field this$0:LX; 5: aload_0 6: aload_2 7: dup 8: invokevirtual #2 // Method java/lang/Object.getClas s:()Ljava/lang/Class; 11: pop 12: invokespecial #3 // Method Y$Z."":(LY;)V 15: return LineNumberTable: line 3: 0 MethodParameters: Name Flags this$0 final mandated x0 Why would the anonymous class's own enclosing instances be mandated while "x0" which I presume is the super classes enclosing instance be flag less ? Thanks in advance for any explanations. Srikanth. From alex.buckley at oracle.com Mon Aug 26 13:07:35 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 26 Aug 2013 13:07:35 -0700 Subject: enhanced-metadata-spec-discuss Digest, Vol 12, Issue 4 In-Reply-To: References: Message-ID: <521BB587.4070207@oracle.com> Hi Srikanth, Many thanks for trying out javac in the JDK 8 builds. Answers below. On 8/26/2013 11:56 AM, Srikanth S Adayapalam wrote: > (1) For the following case: > > // -- > public class X { > void foo() { > class Local { > } > } > } > // -- > > why would javac emit a mandated formal parameter as in > > X$1Local(X); > descriptor: (LX;)V > flags: > Code: > stack=2, locals=2, args_size=2 > 0: aload_0 > 1: aload_1 > 2: putfield #1 // Field this$0:LX; > 5: aload_0 > 6: invokespecial #2 // Method > java/lang/Object." > :()V > 9: return > LineNumberTable: > line 3: 0 > MethodParameters: > Name Flags > this$0 final mandated > > // -- > > I would think this is covered by "The local/ > anonymous class is necessarily emitted by the same compiler as the class > instance creation > expression. That compiler can represent the immediately enclosing instance > how ever > it wishes. There is no need for the Java programming language to > implicitly declare a > parameter in the local/anonymous class's constructor." > > and so the parameter need not be mandated ? I agree. This is a known bug in javac which was identified by unit tests on compiler-dev last week. (For those who can read GPL'd lists, it's http://mail.openjdk.java.net/pipermail/compiler-dev/2013-August/007190.html.) > However, per 13.1 we have: > > A construct emitted by a Java compiler must be marked as mandated if it > corresponds to a formal parameter declared implicitly in source code > (?8.8.9, > ?8.9.2, ?15.9.5.1) and per a reading of 15.9.5.1. seems to imply that > this$0 above should be mandated, since class Local is not > occurring in a static context. Not quite. 15.9.5.1 is about constructors of anonymous classes, and there is no anonymous class in class X above, so there is nothing in any current or future JLS text to say that class Local has an implicitly declared formal parameter. The interesting case is when an anonymous class has a direct superclass (the 'S' in 15.9.5.1) which is "special" in some way - private, or local in a static context. Per the compiler-dev thread above, I am due to update the enhanced metadata spec ASAP to fully enumerate these situations in order to completely specify when ctor formal parameters are implicitly declared. > (2) 8.8.9 point 3) reads: > > In a class instance creation expression for an anonymous class, and where > the anonymous > class's superclass is inner, ?15.9.2 specifies the immediately enclosing > instance with respect > to the superclass. Similar to (1), the superclass may have been emitted by > a compiler which > is different than the compiler of the class instance creation expression. > Therefore, there > must be a standard way for the compiler of the creation expression to pass > a reference > (representing the immediately enclosing instance with respect to the > superclass) to the > superclass's constructor. Consequently, the Java programming language > deems that an > anonymous class's constructor implicitly declares an initial parameter for > the immediately > enclosing instance with respect to the superclass. > > > 8b100's behavior is confusing on the following code: > > // -- > public class X { > void foo() { > new Y().new Z() { > }; > } > } > class Y { > class Z {} > } > // -- > > final X this$0; > descriptor: LX; > flags: ACC_FINAL, ACC_SYNTHETIC > > X$1(X, Y); > descriptor: (LX;LY;)V > flags: > Code: > stack=3, locals=3, args_size=3 > 0: aload_0 > 1: aload_1 > 2: putfield #1 // Field this$0:LX; > 5: aload_0 > 6: aload_2 > 7: dup > 8: invokevirtual #2 // Method > java/lang/Object.getClas > s:()Ljava/lang/Class; > 11: pop > 12: invokespecial #3 // Method > Y$Z."":(LY;)V > 15: return > LineNumberTable: > line 3: 0 > MethodParameters: > Name Flags > this$0 final mandated > x0 > > Why would the anonymous class's own enclosing instances be mandated > while "x0" which I presume is the super classes enclosing instance > be flag less ? There seem to be two javac (or maybe javap) bugs here: - The this$0 field and the this$0 formal parameter which supplies it are concerned with the immediately enclosing instance of the anonymous class's instance. Transmitting this instance to the anonymous class's instance is covered by point 2 in 8.8.9. Basically, it's not specified. As such, the this$0 field has been ACC_SYNTHETIC since forever, and that's a big hint that the this$0 formal parameter should be ACC_SYNTHETIC too. - The x0 formal parameter is implicitly declared by 15.9.5.1 as having type Y, because the direct superclass Z of the anonymous class is inner. So, x0 should be flagged and displayed as mandated. Alex