JDK-6356636 : Compiler fails to read signatures of inner classes with non-generic outer instance leading to crash
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,linux,windows_xp
  • CPU: generic,x86
  • Submitted: 2005-11-29
  • Updated: 2011-02-16
  • Resolved: 2006-05-13
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 6
6 b85Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_05-b05)
Java HotSpot(TM) Client VM (build 1.5.0_05-b05, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Linux bass 2.4.31 #9 Sun Jun 26 22:44:43 MSD 2005 i686 i686 i386 GNU/Linux
Linux desperado 2.6.13-suspend2-r4 #3 SMP Fri Sep 16 12:13:52 MSD 2005 i686 AMD Athlon(TM) XP 2400+ AuthenticAMD GNU/Linux
SunOS aldan 5.9 Generic_117171-17 sun4u sparc SUNW,Ultra-5_10
Windows XP

A DESCRIPTION OF THE PROBLEM :
A certain piece of code (attached below) involving inheritance and generics can't be compiled with javac: it reports an internal NullPointerException.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just try to compile the code attached.

Important: the code should be organized into 2 packages (just like in the example atached). If you merge everything to a single package, you won't get any error.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code should be compiled cleanly.
ACTUAL -
Compiler crashes with an internal error.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
An exception has occurred in the compiler (1.5.0_05). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport)  after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report.  Thank you.
java.lang.NullPointerException
        at com.sun.tools.javac.code.Types$IsSameTypeFcn.visitClassType(Types.java:652)
        at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:482)
        at com.sun.tools.javac.code.Types$IsSameTypeFcn.isSameType(Types.java:601)
        at com.sun.tools.javac.code.Types$IsSameTypeFcn.visitClassType(Types.java:674)
        at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:482)
        at com.sun.tools.javac.code.Types$IsSameTypeFcn.isSameType(Types.java:601)
        at com.sun.tools.javac.code.Types.isSameType(Types.java:591)
        at com.sun.tools.javac.code.Types.covariantReturnType(Types.java:2645)
        at com.sun.tools.javac.code.Types.resultSubtype(Types.java:2607)
        at com.sun.tools.javac.code.Types.returnTypeSubstitutable(Types.java:2615)
        at com.sun.tools.javac.code.Symbol$MethodSymbol.overrides(Symbol.java:814)
        at com.sun.tools.javac.code.Symbol$MethodSymbol.implementation(Symbol.java:866)
        at com.sun.tools.javac.comp.Check.firstUndef(Check.java:1354)
        at com.sun.tools.javac.comp.Check.firstUndef(Check.java:1367)
        at com.sun.tools.javac.comp.Check.checkAllDefined(Check.java:1319)
        at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:2436)
        at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:2406)
        at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:2355)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:444)
        at com.sun.tools.javac.main.Main.compile(Main.java:592)
        at com.sun.tools.javac.main.Main.compile(Main.java:544)
        at com.sun.tools.javac.Main.compile(Main.java:67)
        at com.sun.tools.javac.Main.main(Main.java:52)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
---- BEGIN a/AbstractFoo.java ----
package a;

public class AbstractFoo {
	public class InnerFoo<T> {}
}
---- END a/AbstractFoo.java ----
---- BEGIN a/Bar.java ----
package a;

import a.AbstractFoo.InnerFoo;

public interface Bar {
	InnerFoo<String> getInnerFoo();
}
---- END a/Bar.java ----
---- BEGIN b/Foo.java ----
package b;

import a.*;

public final class Foo extends AbstractFoo implements Bar {
	public InnerFoo<String> getInnerFoo() {
		return null;
	}
}
---- END b/Foo.java ----
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
There're three possible workarounds:

either abandon generalization of an inner class: a.AbstractFoo.InnerFoo instead of a.AbstractFoo.InnerFoo<T>,

or declare inner class static (though it may be never referenced from the static context),

or move the descendant class (b.Foo) to the package where its superclass and superinterface reside (a).
.

Comments
EVALUATION Dare I say this: we seem to have a simple solution which could make it to beta 2.
26-04-2006

EVALUATION That solution might break the invariant that the class reader only reads one class at a time. Also, the compiler can't reliably use '.' to determine if a signature refers to a inner class or a static nested class. According to the JVMS, '.' has no special meaning. Fixing this requires rewriting how javac reads generic signatures and how it is determined if an outer instance exists. This is a significant change which might not be ready for beta 2.
24-02-2006

EVALUATION I found a solution which doesn't require any changes to the class file.
06-01-2006

EVALUATION This problem requires a change in how javac writes generic signatures. Currently javac writes: La/AbstractFoo$InnerFoo<Ljava.lang.String;>; Whereas it can only read this: La/AbstractFoo.InnerFoo<Ljava.lang.String;>; The former is allowed by the JVMS. I tried fixing the problem by changing the class reader but this causes problems with synthesized names, for example, an anonymous class with a generic signature, such as: La/AbstractFoo.InnerFoo$0<Ljava.lang.String;>;
30-12-2005

WORK AROUND Compile all the files at the same time
16-12-2005

SUGGESTED FIX Webrev of changes: http://sa.sfbay/projects/langtools/bugid_summary.pl?bugid=6356636
02-12-2005

EVALUATION This is probably the same problem as 6343995. To reproduce: javac a/AbstractFoo.java a/Bar.java javac b/Foo.java
02-12-2005