JDK-8177440 : Apparently valid Java code with generics compiles with Eclipse but not with javac
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8,9
  • Priority: P4
  • Status: Resolved
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2017-03-22
  • Updated: 2017-06-12
  • Resolved: 2017-05-12
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 Availabitlity Release.

To download the current JDK release, click here.
JDK 10
10Resolved
Description
FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+161)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+161, mixed mode)

(Tried with both)

ADDITIONAL OS VERSION INFORMATION :
Linux new-host 4.9.13-201.fc25.x86_64 #1 SMP Tue Mar 7 23:47:11 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
Try to compile the provided program. No matter what you do, the program cannot be compiled. javac complains about "ambiguous method", or if you try to cast the argument of the last call to Object, that no method can be found.

Eclipse compiles the source providing the expected result (the most specific method is called).


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just compile the source provided.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
> javac Test.java 
Test.java:19: error: reference to method is ambiguous
		c.method(Integer.valueOf(0));
		 ^
  both method method(Integer) in B and method method(K) in A match
  where K is a type-variable:
    K extends Object declared in interface A
1 error


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
interface A<K> {
        void method(K k);
}

interface B {
        void method(Integer k);
}

interface C extends A<Integer>, B {
}

class D implements C {
        public void method(Integer i) {}
}

public class Test {
        public static void main(String args[]) {
                C c = new D();
                c.method(Integer.valueOf(0));
        }
}

---------- END SOURCE ----------


Comments
IMO, this is not a bug, javac is behaving according to the spec. 15.12.2.5 Choosing the Most Specific Method, says: ... ��� Otherwise, if all the maximally specific methods are abstract or default, and the signatures of all of the maximally specific methods have the same erasure (��4.6), then the most specific method is chosen arbitrarily among the subset of the maximally specific methods that have the most specific return type. ... Otherwise, the method invocation is ambiguous, and a compile-time error occurs. ... here the applicable methods A's: void method(K k) and B's: void method(Integer k) are both abstract, but they don't have the same erasure, as the erasure of K is Object. So javac can't select the most specific of the two abstract methods and issues a compiler error.
2017-05-12

This is an issue during compiling with generics, we get the below error for ambigous method == 9/ea/161/binaries/linux-x64/bin/javac Test.java Test.java:19: error: reference to method is ambiguous c.method(Integer.valueOf(0)); ^ both method method(Integer) in B and method method(K) in A match where K is a type-variable: K extends Object declared in interface A 1 error == If you remove Type parameter K and make it concrete like Integer as the below program, It compiles properly. interface A { void method(Integer k); } interface B { void method(Integer k); } interface C extends A, B { } class D implements C { public void method(Integer i) {} } public class Test { public static void main(String args[]) { C c = new D(); c.method(Integer.valueOf(0)); } } This definetly indicate that there is an issue in resolving generic methods
2017-03-23