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.