JDK-8054569 : problem with type inference of generic exceptions
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P3
  • Status: Resolved
  • Resolution: Duplicate
  • OS: os_x
  • CPU: x86
  • Submitted: 2014-08-07
  • Updated: 2016-08-31
  • Resolved: 2015-11-11
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 Other
9Resolved tbd_majorResolved
Related Reports
Blocks :  
Blocks :  
Duplicate :  
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_11"
Java(TM) SE Runtime Environment (build 1.8.0_11-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.11-b03, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Darwin Kernel Version 13.3.0
RELEASE_X86_64 x86_64

A DESCRIPTION OF THE PROBLEM :
The method 'f' throws a generic exception. The type of the exception should be inferable from the type of the second parameter, but the inference fails.

The diagnostic message 'unreported exception E' is unhelpful, since the type 'E' is not available to any callers of the method. If this is actually the intended inference behaviour, the diagnostic should refer to a type that can be caught or thrown by the calling method.

The problem only occurs with javac8 -source 8, and only if the inference on 'f' is being done inside another generic method invocation. I believe it's related to the changes made for JEP 101.

REGRESSION.  Last worked in version 7u67

ADDITIONAL REGRESSION INFORMATION: 
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
$ javac Test.java

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Compilation should succeed.
ACTUAL -
Compilation fails.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Test.java:10: error: unreported exception E; must be caught or declared to be thrown
    return g(f("Hi", MyException.class));
              ^
  where E,U are type-variables:
    E extends Exception declared in method <U,E>f(U,Class<E>)
    U extends Object declared in method <U,E>f(U,Class<E>)
1 error

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.List;

abstract class Test {
  abstract <U, E extends Exception> List<U> f(U u, Class<E> e) throws E;
  abstract <U> List<U> g(List<U> ux);

  class MyException extends Exception {}

  List<String> m() throws MyException {
    return g(f("Hi", MyException.class));
  }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Don't rely on inference, and provide explicit type parameters:

- return g(f("Hi", MyException.class));
+ return g(this.<String, MyException>f("Hi", MyException.class));


Comments
This bug was fixed by JDK-8066974. As this issue is reproducible in 8 repo, it can be considered backporting it to 8. The patch doesn't apply cleanly.
11-11-2015

not reproducible with current tip: 3001:7eef740c1482
03-08-2015

This bug seems to be provoked by a problem in flow analysis rather than in inference. The inference engine is solving E to MyException in both cases: f() and g(f())
09-09-2014