Bug 45540

Summary: Eclipse compiler is in violation of Java Language Specification
Product: [Eclipse Project] JDT Reporter: Emir Alikadic <ealikadic>
Component: CoreAssignee: JDT-Core-Inbox <jdt-core-inbox>
Status: RESOLVED DUPLICATE QA Contact:
Severity: critical    
Priority: P3 CC: eclipse
Version: 3.0   
Target Milestone: 3.0 M5   
Hardware: PC   
OS: Windows 2000   
Whiteboard:

Description Emir Alikadic CLA 2003-10-24 15:48:49 EDT
Found in Eclipse 3.0 M4 (Windows 2000 SP3)

Making a call to a static method of a class does not initialize the class as JLS
requires (c.f. 2.17.4 Initialization).  Given:

public class TypesafeConstant
{
    private String m_id;
    private String m_desc;
    private static Map s_constants = new HashMap();

    protected TypesafeConstant(String id, String desc)
    {
        m_id = id;
        m_desc = desc;
        String key = getClass().getName() + "." + id;
        synchronized (s_constants)
        {
            s_constants.put(key, this);
        }
    }

    public static TypesafeConstant mapIdToObject(String id, Class constantClass)
    {
        if (id == null)
        {
            return null;
        }

        String className = constantClass.getName();
        String key = className + "." + id;
        synchronized (s_constants)
        {
            TypesafeConstant constant = (TypesafeConstant) s_constants.get(key);
            if (constant == null)
            {
                throw new UnknownConstantException("Could not find constant of
class ["
                        + className + "] id [" + id + "]");
            }
            return constant;
        }
    }
}

public class MyConstant extends TypesafeConstant
{
    public final static MyConstant MY_CONSTANT = new MyConstant("uniqueID",
"useless constant");
}

Now, if I do

MyConstant myConstant = (MyConstant) MyConstant.mapIdToObject("uniqueID",
MyConstant.class);

I get the UnknownConstantException, which shouldn't be the case (and isn't if I
use Sun's compiler (1.4.1_05, 1.4.2_01), or even Eclipse compiler in 2.1.1).
Comment 1 Luc Bourlier CLA 2003-10-24 16:46:30 EDT
I think it's a problem with the expansion of the special field 'class'.

If I replace 'MyConstant.class' by 'Class.forName("MyConstant")', it's working
fine with the Eclipse compiler.
If I replace it by 'Class.forName("[LMyConstant;").getComponentType()' (the
expansion done by the Eclipse compiler), it's not working with the Eclipse
compiler or with javac.
Comment 2 Philipe Mulet CLA 2003-10-24 17:22:38 EDT
This is exactly it. The language spec is changing to avoid class initialization 
on class literals. We have converted, Jikes has converted too. Javac hasn't yet.
Comment 3 Luc Bourlier CLA 2003-10-24 17:25:41 EDT
yes, I found the original bug

*** This bug has been marked as a duplicate of 37565 ***
Comment 4 Philipe Mulet CLA 2003-10-24 17:35:50 EDT
Actually, the spec hasn't changed. It is only a compiler implementation issue.
Javac confessed the bug:
http://developer.java.sun.com/developer/bugParade/bugs/4419673.html