[ https://issues.apache.org/jira/browse/LUCENE-3334?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Uwe Schindler updated LUCENE-3334: ---------------------------------- Attachment: LUCENE-3334.patch Here my final patch. > IOUtils.closeSafely should log suppressed Exceptions in stack trace of > original Exception (a new feature of Java 7) > ------------------------------------------------------------------------------------------------------------------- > > Key: LUCENE-3334 > URL: https://issues.apache.org/jira/browse/LUCENE-3334 > Project: Lucene - Java > Issue Type: Improvement > Components: core/other > Reporter: Uwe Schindler > Assignee: Uwe Schindler > Priority: Minor > Attachments: LUCENE-3334.patch, LUCENE-3334.patch, LUCENE-3334.patch > > > I was always against Java 6 support, as it brings no really helpful new > features into Lucene. But there are several things that make life easier in > coming Java 7 (hopefully on July 28th, 2011). One of those is simplier > Exception handling and suppression on Closeable, called "Try-With-Resources" > (see http://docs.google.com/View?id=ddv8ts74_3fs7483dp, by the way all Lucene > classes support these semantics in Java 7 automatically, the cool try-code > below would work e.g. for IndexWriter, TokenStreams,...). > We already have this functionality in Lucene since adding the > IOUtils.closeSafely() utility (which can be removed when Java 7 is the > minimum requirement of Lucene - maybe in 10 years): > {code:java} > try (Closeable a = new ...; Closeable b = new ...) { > ... use Closeables ... > } catch (Exception e) { > dosomething; > throw e; > } > {code} > This code will close a and b in an autogenerated finally block and supress > any exception. This is identical to our IOUtils.closeSafely: > {code:java} > Exception priorException = null; > Closeable a,b; > try (Closeable a = new ...; Closeable b = new ...) { > a = new ...; > b = new ... > ... use Closeables ... > } catch (Exception e) { > priorException = e; > dosomething; > } finally { > IOUtils.closeSafely(priorException, a, b); > } > {code} > So this means we have the same functionality without Java 7, but there is one > thing that makes logging/debugging much nicer: > The above Java 7 code also adds maybe suppressed Exceptions in those > Closeables to the priorException, so when you print the stacktrace, it not > only shows the stacktrace of the original Exception, it also prints all > Exceptions that were suppressed to throw this Exception (all > Closeable.close() failures): > {noformat} > org.apache.lucene.util.TestIOUtils$TestException: BASE-EXCEPTION > at > org.apache.lucene.util.TestIOUtils.testSuppressedExceptions(TestIOUtils.java:61) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:601) > at > org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) > at > org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) > at > org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) > at > org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) > at org.junit.rules.TestWatchman$1.evaluate(TestWatchman.java:48) > at > org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) > at > org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) > at > org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) > at > org.apache.lucene.util.LuceneTestCase$LuceneTestCaseRunner.runChild(LuceneTestCase.java:1486) > at > org.apache.lucene.util.LuceneTestCase$LuceneTestCaseRunner.runChild(LuceneTestCase.java:1404) > at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) > at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) > at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) > at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) > at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) > at > org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) > at > org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) > at org.junit.runners.ParentRunner.run(ParentRunner.java:236) > at junit.framework.JUnit4TestAdapter.run(JUnit4TestAdapter.java:39) > at > org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:420) > at > org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:911) > at > org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:768) > Suppressed: java.io.IOException: TEST-IO-EXCEPTION-1 > at > org.apache.lucene.util.TestIOUtils$BrokenCloseable.close(TestIOUtils.java:36) > at org.apache.lucene.util.IOUtils.closeSafely(IOUtils.java:58) > at > org.apache.lucene.util.TestIOUtils.testSuppressedExceptions(TestIOUtils.java:62) > ... 26 more > Suppressed: java.io.IOException: TEST-IO-EXCEPTION-2 > at > org.apache.lucene.util.TestIOUtils$BrokenCloseable.close(TestIOUtils.java:36) > at org.apache.lucene.util.IOUtils.closeSafely(IOUtils.java:58) > at > org.apache.lucene.util.TestIOUtils.testSuppressedExceptions(TestIOUtils.java:62) > ... 26 more > {noformat} > For this in Java 7 a new method was added to Throwable, that allows logging > such suppressed Exceptions (it is called automatically by the synthetic > bytecode emitted by javac). This patch simply adds this functionality > conditionally to IOUtils, so it "registers" all suppressed Exceptions, if > running on Java 7. This is done by reflection: once it looks for this method > in Throwable.class and if found, it invokes it in closeSafely, so the > exceptions thrown on Closeable.close() don't get lost. > This makes debugging much easier and logs all problems that may occur. > This patch does *not* change functionality or behaviour, it just adds more > nformation to the stack trace in a Java-7-way (similar to the way how Java > 1.4 added causes). It works here locally on Java 6 and Java 7, but only Java > 7 gets the additional stack traces. For Java 6 nothing changes. Same for Java > 5 (if we backport to 3.x). > This would be our first Java 7 improvement (a minor one). Next would be > NIO2... - but thats not easy to do with reflection only, so we have to wait > 10 years :-) -- This message is automatically generated by JIRA. For more information on JIRA, see: http://www.atlassian.com/software/jira --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@lucene.apache.org For additional commands, e-mail: dev-h...@lucene.apache.org