-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
11, 17, 23, 24, 25
-
generic
-
generic
A DESCRIPTION OF THE PROBLEM :
I was using https://docs.oracle.com/javase/specs/jvms/se23/html/jvms-4.html#jvms-4.7.9.1 to determine how to write a correct signature for a class, and it states that a type parameter may be `Identifier ClassBound {InterfaceBound}`, with `ClassBound` being `: [ReferenceTypeSignature]`. This indicates to me that `T:` should be a valid type parameter, without any specified `ReferenceTypeSignature` or `InterfaceBound`. However, if a class with the signature `<T:>Ljava/lang/Object;` is loaded and `Class#getTypeParameters()` is called on it, it will throw an error.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the attached test case with ASM 9.7.1 and at least Java 9.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The class is loaded successfully and the test case prints out the type variables; OR the specification should indicate that this signature is invalid.
ACTUAL -
Exception in thread "main" java.lang.reflect.GenericSignatureFormatError: Signature Parse error: Expected Field Type Signature
Remaining input: >Ljava/lang/Object;
at java.base/sun.reflect.generics.parser.SignatureParser.error(SignatureParser.java:124)
at java.base/sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(SignatureParser.java:291)
at java.base/sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(SignatureParser.java:277)
at java.base/sun.reflect.generics.parser.SignatureParser.parseBounds(SignatureParser.java:523)
at java.base/sun.reflect.generics.parser.SignatureParser.parseFormalTypeParameter(SignatureParser.java:250)
at java.base/sun.reflect.generics.parser.SignatureParser.parseFormalTypeParameters(SignatureParser.java:234)
at java.base/sun.reflect.generics.parser.SignatureParser.parseZeroOrMoreFormalTypeParameters(SignatureParser.java:219)
at java.base/sun.reflect.generics.parser.SignatureParser.parseClassSignature(SignatureParser.java:212)
at java.base/sun.reflect.generics.parser.SignatureParser.parseClassSig(SignatureParser.java:156)
at java.base/sun.reflect.generics.repository.ClassRepository.parse(ClassRepository.java:57)
at java.base/sun.reflect.generics.repository.ClassRepository.parse(ClassRepository.java:41)
at java.base/sun.reflect.generics.repository.AbstractRepository.<init>(AbstractRepository.java:74)
at java.base/sun.reflect.generics.repository.GenericDeclRepository.<init>(GenericDeclRepository.java:51)
at java.base/sun.reflect.generics.repository.ClassRepository.<init>(ClassRepository.java:53)
at java.base/sun.reflect.generics.repository.ClassRepository.make(ClassRepository.java:70)
at java.base/java.lang.Class.getGenericInfo(Class.java:3439)
at java.base/java.lang.Class.getTypeParameters(Class.java:1047)
at DemonstrateWeirdSignature.main(DemonstrateWeirdSignature.java:29)
---------- BEGIN SOURCE ----------
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
public class DemonstrateWeirdSignature {
private static final String SIGNATURE = "<T:>Ljava/lang/Object;";
public static void main(String[] args) throws IllegalAccessException {
ClassWriter classWriter = new ClassWriter(0);
classWriter.visit(
Opcodes.V1_8,
Opcodes.ACC_PUBLIC,
"Example",
SIGNATURE,
"java/lang/Object",
null
);
classWriter.visitEnd();
Class<?> theClass = MethodHandles.lookup().defineClass(classWriter.toByteArray());
System.out.println(theClass);
System.out.println(Arrays.toString(theClass.getTypeParameters()));
}
}
---------- END SOURCE ----------
I was using https://docs.oracle.com/javase/specs/jvms/se23/html/jvms-4.html#jvms-4.7.9.1 to determine how to write a correct signature for a class, and it states that a type parameter may be `Identifier ClassBound {InterfaceBound}`, with `ClassBound` being `: [ReferenceTypeSignature]`. This indicates to me that `T:` should be a valid type parameter, without any specified `ReferenceTypeSignature` or `InterfaceBound`. However, if a class with the signature `<T:>Ljava/lang/Object;` is loaded and `Class#getTypeParameters()` is called on it, it will throw an error.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the attached test case with ASM 9.7.1 and at least Java 9.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The class is loaded successfully and the test case prints out the type variables; OR the specification should indicate that this signature is invalid.
ACTUAL -
Exception in thread "main" java.lang.reflect.GenericSignatureFormatError: Signature Parse error: Expected Field Type Signature
Remaining input: >Ljava/lang/Object;
at java.base/sun.reflect.generics.parser.SignatureParser.error(SignatureParser.java:124)
at java.base/sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(SignatureParser.java:291)
at java.base/sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(SignatureParser.java:277)
at java.base/sun.reflect.generics.parser.SignatureParser.parseBounds(SignatureParser.java:523)
at java.base/sun.reflect.generics.parser.SignatureParser.parseFormalTypeParameter(SignatureParser.java:250)
at java.base/sun.reflect.generics.parser.SignatureParser.parseFormalTypeParameters(SignatureParser.java:234)
at java.base/sun.reflect.generics.parser.SignatureParser.parseZeroOrMoreFormalTypeParameters(SignatureParser.java:219)
at java.base/sun.reflect.generics.parser.SignatureParser.parseClassSignature(SignatureParser.java:212)
at java.base/sun.reflect.generics.parser.SignatureParser.parseClassSig(SignatureParser.java:156)
at java.base/sun.reflect.generics.repository.ClassRepository.parse(ClassRepository.java:57)
at java.base/sun.reflect.generics.repository.ClassRepository.parse(ClassRepository.java:41)
at java.base/sun.reflect.generics.repository.AbstractRepository.<init>(AbstractRepository.java:74)
at java.base/sun.reflect.generics.repository.GenericDeclRepository.<init>(GenericDeclRepository.java:51)
at java.base/sun.reflect.generics.repository.ClassRepository.<init>(ClassRepository.java:53)
at java.base/sun.reflect.generics.repository.ClassRepository.make(ClassRepository.java:70)
at java.base/java.lang.Class.getGenericInfo(Class.java:3439)
at java.base/java.lang.Class.getTypeParameters(Class.java:1047)
at DemonstrateWeirdSignature.main(DemonstrateWeirdSignature.java:29)
---------- BEGIN SOURCE ----------
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
public class DemonstrateWeirdSignature {
private static final String SIGNATURE = "<T:>Ljava/lang/Object;";
public static void main(String[] args) throws IllegalAccessException {
ClassWriter classWriter = new ClassWriter(0);
classWriter.visit(
Opcodes.V1_8,
Opcodes.ACC_PUBLIC,
"Example",
SIGNATURE,
"java/lang/Object",
null
);
classWriter.visitEnd();
Class<?> theClass = MethodHandles.lookup().defineClass(classWriter.toByteArray());
System.out.println(theClass);
System.out.println(Arrays.toString(theClass.getTypeParameters()));
}
}
---------- END SOURCE ----------
- relates to
-
JDK-8333377 Migrate Generic Signature parsing to ClassFile API
-
- In Progress
-