JDK-7179353 : try-with-resources fails to compile with generic exception parameters
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: os_x
  • CPU: x86
  • Submitted: 2012-06-24
  • Updated: 2013-12-17
  • Resolved: 2013-05-31
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 JDK 8
7u40Fixed 8 b94Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.7.0_04"
Java(TM) SE Runtime Environment (build 1.7.0_04-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Darwin mac-mini.home 11.4.0 Darwin Kernel Version 11.4.0: Mon Apr  9 19:32:15 PDT 2012; root:xnu-1699.26.8~1/RELEASE_X86_64 x86_64


A DESCRIPTION OF THE PROBLEM :
The Java 1.7 compiler (Oracle SDK) fails to type-check valid code when the exception thrown from an AutoCloseable resource used in a try-with-resources is a generic type parameter. The attached test-case (see Steps to Reproduce) fails to compile with the error:

test.java:9: error: unreported exception E; must be caught or declared to be thrown
        try (Resource<E> r = new Resource<E>()) {
                         ^
  exception thrown from implicit call to close() on resource variable 'r'
  where E is a type-variable:
    E extends Exception declared in class Resource
1 error

As you can see from the code, E is in fact declared to be thrown by the enclosing method.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Save the supplied test case as test.java and compile with javac 1.7 (Oracle Java 7 SDK).

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A compiled test.class and test$Resource.class with no errors.
ACTUAL -
test.java:9: error: unreported exception E; must be caught or declared to be thrown
        try (Resource<E> r = new Resource<E>()) {
                         ^
  exception thrown from implicit call to close() on resource variable 'r'
  where E is a type-variable:
    E extends Exception declared in class Resource
1 error

ERROR MESSAGES/STACK TRACES THAT OCCUR :
test.java:9: error: unreported exception E; must be caught or declared to be thrown
        try (Resource<E> r = new Resource<E>()) {
                         ^
  exception thrown from implicit call to close() on resource variable 'r'
  where E is a type-variable:
    E extends Exception declared in class Resource
1 error

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class test {

    public static class Resource<E extends Exception> implements AutoCloseable {

        public void close() throws E { }
    }

    public <E extends Exception> void test() throws E {
        try (Resource<E> r = new Resource<E>()) {

        }
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Add an explicit catch block for Exception and re-throw the exception:

try (Resource<E> r = new Resource<E>()) {
    ...
} catch (Exception ex) {
    throw (E) ex;
}

Only works for a single generic exception parameter. No obvious workaround when there are multiple possible generic exceptions that could be thrown.

Comments
Respective test: tools/javac/T7179353/GenericsAndTWRCompileErrorTest.java
19-06-2013