JDK-6594284 : NPE thrown when calling a method on an intersection type
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,linux
  • CPU: generic,x86
  • Submitted: 2007-08-17
  • Updated: 2014-05-21
  • Resolved: 2011-05-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 7
7 b33Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
The followin exception was thrown while coppilation of the Test1.java(see below). winxp and solaris platforms, java 6 and 7.
------------------------------------OutPut----------------------------------------------
Information:An exception has occurred in the compiler (1.6.0). 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.
Information:java.lang.NullPointerException
Information:	at com.sun.tools.javac.comp.TransTypes.retype(TransTypes.java:135)
Information:	at com.sun.tools.javac.comp.TransTypes.visitApply(TransTypes.java:566)
Information:	at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1210)
Information:	at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:44)
Information:	at com.sun.tools.javac.comp.TransTypes.translate(TransTypes.java:398)
Information:	at com.sun.tools.javac.comp.TransTypes.visitExec(TransTypes.java:529)
Information:	at com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1074)
Information:	at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:56)
Information:	at com.sun.tools.javac.tree.TreeTranslator.visitBlock(TreeTranslator.java:146)
Information:	at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:739)
Information:	at com.sun.tools.javac.comp.TransTypes.visitMethodDef(TransTypes.java:432)
Information:	at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:639)
Information:	at com.sun.tools.javac.tree.TreeTranslator.visitClassDef(TreeTranslator.java:120)
Information:	at com.sun.tools.javac.comp.TransTypes.translateClass(TransTypes.java:742)
Information:	at com.sun.tools.javac.comp.TransTypes.visitClassDef(TransTypes.java:419)
Information:	at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:575)
Information:	at com.sun.tools.javac.comp.TransTypes.translateTopLevelClass(TransTypes.java:765)
Information:	at com.sun.tools.javac.main.JavaCompiler.desugar(JavaCompiler.java:1182)
Information:	at com.sun.tools.javac.main.JavaCompiler.desugar(JavaCompiler.java:1118)
Information:	at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:765)
Information:	at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:730)
Information:	at com.sun.tools.javac.main.Main.compile(Main.java:353)
Information:	at com.sun.tools.javac.main.Main.compile(Main.java:279)
Information:	at com.sun.tools.javac.main.Main.compile(Main.java:270)
Information:	at com.sun.tools.javac.Main.compile(Main.java:69)
Information:	at com.sun.tools.javac.Main.main(Main.java:54)
Information:	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Information:	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
Information:	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
Information:	at java.lang.reflect.Method.invoke(Method.java:597)
Information:	at com.intellij.rt.compiler.JavacRunner.main(JavacRunner.java:56)
Information:Compilation completed with 1 error and 0 warnings
Information:1 error
Information:0 warnings
Error:Compiler internal error. Process terminated with exit code 4

------------------------------Test1.java--------------------------------
class A{ public void a(){}}
class B extends A{ public void b(){}}
interface I{ void i();}
class E extends B implements I{ public void i(){};}

class C<W extends B & I, T extends W>{
     public T fieldT;    
}

public class Test1 {
    static void method(C<? extends I, ? extends E> arg){ //FAIL
//                 // (C<? extends I, ? extends B> arg){ // OK
        arg.fieldT.a();
    }
}

Comments
SUGGESTED FIX A webrev of the fix is available at http://sa.sfbay.sun.com/projects/langtools_data/7/6594284/
24-07-2008

EVALUATION This fix depends on 6651719
25-02-2008

EVALUATION JLS 5.1.10 (capture conversion) states that: "If Ti is a wildcard type argument of the form ? extends Bi, then Si is a fresh type variable whose upper bound is glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is a compile-time error if for any two classes (not interfaces) Vi and Vj,Vi is not a subclass of Vj or vice versa." This means that when capturing a type C<T1, T2 ... Tn>, each type argument in T1, T2 ... Tn that is a wildcards of the kind "? extends E" gets replaced with a fresh type variable whose upper bound is the result of the funcion glb applied to (i) the declared bound of its corresponding type variable and (ii) the type E (the bound of the wildcard). What is the capture of the type C<? extends I, ? extends E> given the hierarchy of classes described in the test case? It's the type C<#CAP1,#CAP2> where both X and Y are fresh type variables. While the upper bound of #CAP1 is clearly glb(I,(B & I)) === B & I, we have some trouble in computing the upper bound of #CAP2. The latter should be glb(E,#CAP1), since #CAP1 happens to be the (actual) upper bound of T. However, neither E <: #CAP1 nor #CAP1 <: E (see below) so this situation should result in a compile-time error as described in 5.1.10. -The direct supertype of #CAP1 is its upper bound, the intersection type B & I. -The direct supertypes of B & I are B and I, respectively. -The direct supertypes of E are B and I. So there's no way to prove that either E <: #CAP1 or #CAP1 <: E given the rules in 4.10.2. This bug can be fixed by correctly implementing the JLS 5.1.10 and raising a compile-time error whenever the upperbound of a fresh type variable cannot be computed. A good place in which to check for this condition is when checking for the well-formedness of a given type. JLS 4.5 states that "Let P = G<T1, ..., Tn> be a parameterized type. It must be the case that, after P is subjected to capture conversion (��5.1.10) resulting in the type G<X1, ..., Xn>, for each actual type argument Xi, 1 in , Xi <: Bi[A1 := X1, ..., An := Xn] (��4.10), or a compile time error occurs." Since to check conformance wrt type variable bounds the actual type should be capture-converted, it's sensible to give an error if such a captured type cannot be computed because of a non-existing glb.
18-02-2008

EVALUATION I can reproduce this bug in both JDK 6 and JDK 7.
25-09-2007