Community
Participate
Working Groups
Build Identifier: Version: 4.2.0 Build id: I20120209-1230 You cannot compile the following class: package de.gps.db.impl; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Path; import java.nio.file.StandardCopyOption; public class Test { public void executeImports() throws MalformedURLException { for (int i = 0; i < 3; i++) { URL url = new URL("dummy"); //$NON-NLS-1$ if (url != null) { Path target = new File("dummy").toPath(); try (InputStream is = url.openStream()) { java.nio.file.Files.copy(is, target, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { break; } finally { try { java.nio.file.Files.delete(target); } catch (IOException e1) { } } } } } } The cause of the error is the break statement in the catch clause. If you remove this statement, everything works fine. If the break-statement is present, the exception given below is thrown. The jre is jdk1.7.2_02 from sun. java.lang.ArrayIndexOutOfBoundsException: 2 at org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel.placeEnd(ExceptionLabel.java:41) at org.eclipse.jdt.internal.compiler.ast.TryStatement.generateSubRoutineInvocation(TryStatement.java:841) at org.eclipse.jdt.internal.compiler.ast.BranchStatement.generateCode(BranchStatement.java:48) at org.eclipse.jdt.internal.compiler.ast.Block.generateCode(Block.java:57) at org.eclipse.jdt.internal.compiler.ast.TryStatement.generateCode(TryStatement.java:663) at org.eclipse.jdt.internal.compiler.ast.Block.generateCode(Block.java:57) at org.eclipse.jdt.internal.compiler.ast.IfStatement.generateCode(IfStatement.java:189) at org.eclipse.jdt.internal.compiler.ast.Block.generateCode(Block.java:57) at org.eclipse.jdt.internal.compiler.ast.ForStatement.generateCode(ForStatement.java:303) at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.generateCode(AbstractMethodDeclaration.java:316) at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.generateCode(AbstractMethodDeclaration.java:261) at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCode(TypeDeclaration.java:547) at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.generateCode(TypeDeclaration.java:616) at org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.generateCode(CompilationUnitDeclaration.java:360) at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(CompilationUnitResolver.java:1205) at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(CompilationUnitResolver.java:684) at org.eclipse.jdt.core.dom.ASTParser.internalCreateAST(ASTParser.java:1181) at org.eclipse.jdt.core.dom.ASTParser.createAST(ASTParser.java:807) at org.eclipse.jdt.internal.ui.javaeditor.ASTProvider$1.run(ASTProvider.java:544) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.jdt.internal.ui.javaeditor.ASTProvider.createAST(ASTProvider.java:537) at org.eclipse.jdt.internal.ui.javaeditor.ASTProvider.getAST(ASTProvider.java:480) at org.eclipse.jdt.ui.SharedASTProvider.getAST(SharedASTProvider.java:128) at org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager$PartListenerGroup.calculateASTandInform(SelectionListenerWithASTManager.java:170) at org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager$PartListenerGroup$3.run(SelectionListenerWithASTManager.java:155) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54) Reproducible: Always Steps to Reproduce: Use the class given and comment / uncomment the break-statement. You should see the error.
Obviously, the jdk is jdk1.7.0_02, not jdk1.7.2_02. Furthermore, I would like to note, that javac compiles the Test class without error...
Reduced test case: import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; public class X { public void foo() throws MalformedURLException { URL url = new URL("dummy"); //$NON-NLS-1$ try (InputStream is = url.openStream()) { } catch (IOException e) { return; } finally { try { java.nio.file.Files.delete(null); } catch (IOException e1) { } } } } It seems to be related to the return statement inside the catch block. In the original test case, the pb is related to the break statement in the catch block. Both test cases should be added as regression tests.
(In reply to comment #2) > It seems to be related to the return statement inside the catch block. In the > original test case, the pb is related to the break statement in the catch > block. > Both test cases should be added as regression tests. Thanks Olivier. Disabled regression tests released via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=61acdac89cab049caf399067a6384e2df8085bdf
(In reply to comment #2) > It seems to be related to the return statement inside the catch block. In the > original test case, the pb is related to the break statement in the catch > block. > Both test cases should be added as regression tests. Indeed. return, break and continue don't need special handling from a resource closure stand point when they occur in a catch block or finally block. (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=338402#c16) When the catch/finally blocks are entered, resources have been properly closed already. Fix is to recognize that resource exception handlers are not needed past the try block - see analogous treatment for TryStatement.declaredExceptionLabels. Patch will follow shortly.
Created attachment 213143 [details] Patch under test Also has a few more junits.
Fix and tests released via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=90244a03b74762755d359afcfdbbdc7ca6e3137a. Note to reviewer: Basically if a return, break or continue would take the control out of the try block with resources, then the resource closures would have be handled as a part of code generation for the return, break or continue. However, if the return, break or continue is outside of the try i.e features in a catch block or finally block, the resources are already closed (https://bugs.eclipse.org/bugs/show_bug.cgi?id=338402#c16) and the code generation of return, break or continue should not attempt to close them. It was trying to and that was the problem and has since been fixed.
Satyam, please review, TIA.
The changes look good to me.
Dani, do you want this Java 7 fix for 3.6.2+Java7 and 3.7.2+ streams ? The fix is very safe IMO.
I verified the code and that the fix works. +1 to backport.
Reopening for backport.
Released on 3.7 maintenance using commit 6c7abe90183484d585c334aa10f32c5f8581b4a1
Released on 3.6.2+J7 using commit c5c1cc11b405a60f0f2b3d63b95571e3500fa5dc
Verified for 3.8M7 using build I20120429-1800.