JDK-8322655 : Allow NameAndType constants with special method names
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 21
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2023-12-22
  • Updated: 2024-06-18
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 24
24Unresolved
Related Reports
Relates :  
Relates :  
Relates :  
Description
JVMS (4.4.6) says that the 'name' portion of a NameAndType may represent "either a valid unqualified name denoting a field or method, or the special method name <init>", while the 'descriptor' portion may be "a valid field descriptor or method descriptor".

Per 4.2.2, names that include '<' are valid unqualified field names. This includes the names '<init>' and '<clinit>', which should be fully usable as names of fields.

During format checking of a NameAndType constant (setting aside whether it is referenced by any other constant), HotSpot seems to consider the name and descriptor in tandem, and enforce different rules for the name based on the descriptor. Some examples:

<init>:()I --> CFE
<clinit>:()I --> CFE
<clinit>:()V --> no error
<finit>:()I --> CFE

This is inconsistent with the spec, and should be cleaned up. Given a standalone NameAndType, any valid unqualified name should be accepted for 'name', and any valid field or method descriptor should be accepted for 'descriptor'.

*References* to NameAndType constants enforce some additional constraints:

- From a Fieldref, the descriptor must be a field descriptor

- From a Methodref, the name must be a valid method name and must not be '<clinit>'. The descriptor must be a method descriptor, and if the name is '<init>', the descriptor must return 'V'.

- Same for InterfaceMethodref.

- From a Dynamic, the descriptor must be a field descriptor

- From an InvokeDynamic, the descriptor must be a method descriptor. (Should the name be restricted? I think so, but the spec doesn't say so for now, so that's a separate issue.)

Comments
> Per 4.2.2, names that include '<' are valid unqualified field names. This includes the names '<init>' and '<clinit>', which should be fully usable as names of fields. [~dlsmith] were you actually suggesting there is a problem with field name handling, or just mentioning this as something to check? Field name processing seems to be fine going back to at least JDK 8.
18-06-2024

I can't see, from code inspection in classFileParser.cpp, any obvious places where we restrict things unnecessarily. Field names certainly should not reject < or >. For method names there are special rules for anything named <init> or <clinit> as Dan H. referenced, which do include the signature checks.
18-06-2024

I think the issues with init/clinit that Dan S. reported were already addressed by Harold in JDK-8268720.
18-06-2024

There are also two rules in 4.6 Methods which may be being applied too broadly? See the text in the "descriptor" part of 4.6: > If this method is in a class rather than an interface, and the name of the method is <init>, then the descriptor must denote a void method. > > If the name of the method is <clinit>, then the descriptor must denote a void method, and, in a class file whose version number is 51.0 or above, a method that takes no arguments.
18-06-2024

See JDK-8323436 for a spec change to clarify legal names used by InvokeDynamic constants. If convenient, that change could be implemented in HotSpot via this issue.
10-01-2024