JDK-8148464 : 15.12.2.5: Unclear interpretation of a method's "erasure"
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 7,8
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2016-01-04
  • Updated: 2018-08-03
  • Resolved: 2018-08-03
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 9
9Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b18)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b18, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
I found a bug in Oracle java compiler that causes "reference to ... is ambiguous" error. The same code does compile with Eclipse java compiler without any problem.
The scenario is as following:
* you have an generic interface GI with a method m using the generic (without bounds) as argument
* you have an typed (non-generic) interface TI with a method defining the same method signature but instead of the generic it uses a concret non-primitive type X.
* you have an interface CI that combines both interfaces and binds the generic to X (extends GI<X>, TI).
* also CI defines a default method that calls the method m with some argument compliant to X.

I added the minimum isolated code in the "Source code for an executable test case" field.

See also here where I discovered the problem in an open-source project:
https://github.com/m-m-m/util/issues/166

ADDITIONAL REGRESSION INFORMATION: 
Works fine in Eclipse compiler.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the code submitted in "Source code for an executable test case".

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Should compile as both methods are setValue(java.lang.Boolean) and should not be considered ambiguous but same.
ACTUAL -
[ERROR] .../src/main/java/CombinedInterface.java:[5,5] reference to setValue is ambiguous
[ERROR] both method setValue(java.lang.Boolean) in TypedInterface and method setValue(V) in GenericInterface match

ERROR MESSAGES/STACK TRACES THAT OCCUR :
[ERROR] .../src/main/java/CombinedInterface.java:[5,5] reference to setValue is ambiguous
[ERROR] both method setValue(java.lang.Boolean) in TypedInterface and method setValue(V) in GenericInterface match

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public interface GenericInterface<V> {
  void setValue(V value);
}
public interface TypedInterface {
  void setValue(Boolean value);
}
public interface CombinedInterface extends GenericInterface<Boolean>, TypedInterface {
  default void set(boolean value) {
    setValue(Boolean.valueOf(value));
  }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use Eclipse compiler instead.


Comments
The intent is to use declaration-site erasure. Eclipse is behaving incorrectly. JDK-7028828 will clarify the spec text.
30-09-2016

A similar test case, this one rejected by both javac and Eclipse: public interface GenericInterface<V> { void setValue(V value); void setValue(Boolean value); } static void set(GenericInterface<Boolean> gi, Boolean value) { gi.setValue(value); } Eclipse seems to be erasing the method's type as a member of the (possibly generic) class by which it is referenced, which is a strange intermediate step between the declared type and the fully-instantiated type.
23-06-2016

Honestly, this looks like a bug in Eclipse - the JLS says (15.12.2.5): "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." Note that it is a requirement that the erasure of the signatures of all applicable methods is the same; here we have that one signature erases to setValue(Object), while the other to setValue(Boolean) so this requirement is not satisfied. Looks like Eclipse is maybe doing erasure on the substituted signatures? Will assign to spec for further clarification.
28-01-2016

Test Result: ########## OS: Windows 7 64 bit ################## JAVAC, Netbeans: ############### 8u0 b132 : Fail 8u51 b16 : Fail 8u65 b17 : Fail 8u66 b18 : Fail 8u72 b05 : Fail 9u0 b94 : Fail Eclipse Mars: ########### 8u0 b132 : Pass 8u51 b16 : Pass 8u65 b17 : Pass 8u66 b18 : Pass 8u72 b05 : Pass 9u0 b94 : Pass
07-01-2016