JDK-8010436 : try-with-resources fails to compile with generic exception
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7u17,8
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • Submitted: 2013-03-20
  • Updated: 2013-03-21
  • Resolved: 2013-03-21
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version  " 1.7.0_09 " 
Java(TM) SE Runtime Environment (build 1.7.0_09-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.5-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux mintern-debian 3.2.0-4-amd64 #1 SMP Debian 3.2.32-1 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
When an AutoCloseable subclass throws a generic exception from close, it cannot be used correctly in a try-with-resources block. For example, if a CloseBug<E extends Exception> throws E from its close method, its usage as CloseBug<RuntimeException> in a try-with-resources requires the method signature to throw Exception. On the other hand, its usage in a try-finally lock requires no such declaration. See the Steps to Reproduce for sample code.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile AutoCloseableBug.java (provided in source code, below).

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The try-with-resources should behave similarly to the try-finally (see AutoCloseableNoBug.java, below).
ACTUAL -
Using try-with-resources in this case fails to compile.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
See source code, below. The following error should not occur.

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

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
 AutoCloseableBug.java:

public class AutoCloseableBug {
    public static void main(String[] args) {
        System.out.println( " hello " );
        try (TheBug<RuntimeException> bug = new TheBug<>()) {
            System.out.println( " [with bug] " );
        }
        System.out.println( " world " );
    }
    private static class TheBug<E extends Exception> implements AutoCloseable {
        @Override
        public void close() throws E {
            System.out.println( " [closing] " );
        }
    }
}

Compare to AutoCloseableNoBug.java, which compiles and runs as expected:

public class AutoCloseableNoBug {
    public static void main(String[] args) {
        System.out.println( " hello " );
        TheBug<RuntimeException> bug = new TheBug<>();
        try {
            System.out.println( " [with bug] " );
        } finally {
            bug.close();
        }
        System.out.println( " world " );
    }
    private static class TheBug<E extends Exception> implements AutoCloseable {
        @Override
        public void close() throws E {
            System.out.println( " [closing] " );
        }
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Avoid using try-with-resources with AutoCloseable classes that throw a generic exception from the close method.
Comments
Duplicate of JDK-7179353.
21-03-2013

Reproducible on latest JDK 7 release and on JDK 8.
21-03-2013