JDK-5003916 : (reflect) 24 classes from java package cause GenericSignatureFormatError
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 5.0
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2004-02-26
  • Updated: 2012-09-28
  • Resolved: 2004-04-16
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.
Other
5.0 b48Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description

Name: siR10004			Date: 02/26/2004



The following classes -

-------------------------------------------------------------
java.util.concurrent.FutureTask
java.util.concurrent.ConcurrentHashMap$EntryIterator
java.util.concurrent.ConcurrentHashMap$KeyIterator
java.util.concurrent.ConcurrentHashMap$ValueIterator
java.util.AbstractList$ListItr
java.util.EnumMap$EntryIterator
java.util.EnumMap$KeyIterator
java.util.EnumMap$ValueIterator
java.util.IdentityHashMap$EntryIterator
java.util.IdentityHashMap$KeyIterator
java.util.IdentityHashMap$ValueIterator
java.util.WeakHashMap$EntryIterator
java.util.WeakHashMap$KeyIterator
java.util.WeakHashMap$ValueIterator
java.util.TreeMap$EntryIterator
java.util.TreeMap$KeyIterator
java.util.TreeMap$SubMapEntryIterator
java.util.TreeMap$ValueIterator
java.util.HashMap$EntryIterator
java.util.HashMap$KeyIterator
java.util.HashMap$ValueIterator
java.util.LinkedHashMap$EntryIterator
java.util.LinkedHashMap$KeyIterator
java.util.LinkedHashMap$ValueIterator
-------------------------------------------------------------

cause 'java.lang.reflect.GenericSignatureFormatError' thrown
when calling some of reflection methods to get generic types.

The following program can be used to reproduce the bug
-------------------------------------------------------------
import java.lang.reflect.*;

public class Probe {
    public static void main (String[] args) throws Throwable
    {
        String name = args[0];
        System.out.println("\nCLASS " + name);
        Class c = Class.forName(name, false, null);
        int errs = probe(c);
        System.out.println(errs == 0 ? "  ok" : "  errors:" + errs);
    }
    
    static int probe (Class c) 
    {
    	int errs = 0;
    
        try {
            c.getTypeParameters();
            c.getGenericSuperclass();
            c.getGenericInterfaces();
        }
        catch (Throwable t) {
            errs++;
            System.err.println(t);
            //t.printStackTrace();
        }
        
        Field[] fields = c.getDeclaredFields();
        if (fields != null)
            for (int i = 0; i < fields.length; i++) {
                try {
                    fields[i].getGenericType();
                }
                catch (Throwable t) {
                    errs++;
                    System.err.println("FIELD " + fields[i]);
                    System.err.println(t);
                    //t.printStackTrace();
                }
            }
        
        Method[] methods = c.getDeclaredMethods();
        if (methods != null)
            for (int i = 0; i < methods.length; i++) {
                try {
                    methods[i].getTypeParameters();
                    methods[i].getGenericReturnType();
                    methods[i].getGenericParameterTypes();
                    methods[i].getGenericExceptionTypes();
                }
                catch (Throwable t) {
                    errs++;
                    System.err.println("METHOD " + methods[i]);
                    System.err.println(t);
                    //t.printStackTrace();
                }
            }
            
        Constructor[] ctors = c.getDeclaredConstructors();
        if (ctors != null)
            for (int i = 0; i < ctors.length; i++) {
                try {
                    ctors[i].getTypeParameters();
                    ctors[i].getGenericParameterTypes();
                    ctors[i].getGenericExceptionTypes();
                }
                catch (Throwable t) {
                    errs++;
                    System.err.println("CONSTRUCTOR " + ctors[i]);
                    System.err.println(t);
                    //t.printStackTrace();
                }
            }
            
        return errs;
    }
}    
-------------------------------------------------------------

This bug causes failure of JCK signature test on b40.
Not reproducible on b39.

It seems that root of the problem is in invalid 'Signature' attributes.
For example, field
  java.util.concurrent.FutureTask.sync
has the following attribute
  Ljava/util/concurrent/FutureTask<TV;>.Sync;
(note that '.Sync' violates the signature attribute syntax).

======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger-beta2 FIXED IN: tiger-beta2 INTEGRATED IN: tiger-b48 tiger-beta2 VERIFIED IN: tiger-beta2
14-06-2004

SUGGESTED FIX src/share/classes/sun/reflect/generics/parser>sccs sccsdiff -r1.3 -r1.4 SignatureParser.java ------- SignatureParser.java ------- 243c243 < scts.add(parseSimpleClassTypeSignature()); --- > scts.add(parseSimpleClassTypeSignature(false)); 245c245,247 < if (current() != ';') { throw error("expected ;");} --- > if (current() != ';') > throw error("expected ';' got '" + current() + "'"); > 250c252 < private SimpleClassTypeSignature parseSimpleClassTypeSignature(){ --- > private SimpleClassTypeSignature parseSimpleClassTypeSignature(boolean dollar){ 256c258 < return SimpleClassTypeSignature.make(id, new TypeArgument[0]) ; --- > return SimpleClassTypeSignature.make(id, dollar, new TypeArgument[0]) ; 258c260 < return SimpleClassTypeSignature.make(id, parseTypeArguments()); --- > return SimpleClassTypeSignature.make(id, dollar, parseTypeArguments()); 264,266c266,268 < private void parseClassTypeSignatureSuffix(List<SimpleClassTypeSignature> < scts) { < while (current() == '/') { --- > private void parseClassTypeSignatureSuffix(List<SimpleClassTypeSignature> scts) { > while (current() == '/' || current() == '.') { > boolean dollar = (current() == '.'); 268c270 < scts.add(parseSimpleClassTypeSignature()); --- > scts.add(parseSimpleClassTypeSignature(dollar)); 307c309 < ub[0] = SimpleClassTypeSignature.make("java.lang.Object", ta); --- > ub[0] = SimpleClassTypeSignature.make("java.lang.Object", false, ta); 314c316 < ub[0] = SimpleClassTypeSignature.make("java.lang.Object", ta); --- > ub[0] = SimpleClassTypeSignature.make("java.lang.Object", false, ta); src/share/classes/sun/reflect/generics/tree>eClassTypeSignature.java < ------- SimpleClassTypeSignature.java ------- 12a13 > private boolean dollar; 16c17 < private SimpleClassTypeSignature(String n, TypeArgument[] tas) { --- > private SimpleClassTypeSignature(String n, boolean dollar, TypeArgument[] tas) { 17a19 > this.dollar = dollar; 21,22c23,26 < public static SimpleClassTypeSignature make(String n, TypeArgument[] tas){ < return new SimpleClassTypeSignature(n, tas); --- > public static SimpleClassTypeSignature make(String n, > boolean dollar, > TypeArgument[] tas){ > return new SimpleClassTypeSignature(n, dollar, tas); 24a29,35 > /* > * Should a '$' be used instead of '.' to separate this component > * of the name from the previous one when composing a string to > * pass to Class.forName; in other words, is this a transition to > * a nested class. > */ > public boolean getDollar(){return dollar;} ###@###.### 2004-04-12
12-04-2004

EVALUATION The current specification is hopeless in a number of ways. Javac implements something that is known to be concise and sufficient for the purposes of this attribute. Both the specification and reflection implementation will need to be modified to match javac, or alternatively a new specification should be generated that is concise and sufficient, and then both javac and the libraries need to be modified. In any case a CCC will be needed. See 4942991 for the latest javac changes in this area. ###@###.### 2004-02-26 Must be fixed. ###@###.### 2004-03-02
26-02-2004