Duplicate :
|
|
Relates :
|
|
Relates :
|
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.
|