Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 375248 - AIOOBE inside twr with finally block
Summary: AIOOBE inside twr with finally block
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.8   Edit
Hardware: PC Linux
: P3 major (vote)
Target Milestone: 3.6.2+J7   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard: To be verified for 3.7.2+
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-24 08:12 EDT by Karl Weber CLA
Modified: 2012-04-30 13:32 EDT (History)
4 users (show)

See Also:
daniel_megert: pmc_approved+
satyam.kandula: review+


Attachments
Patch under test (6.67 KB, text/plain)
2012-03-25 03:21 EDT, Srikanth Sankaran CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Karl Weber CLA 2012-03-24 08:12:25 EDT
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.
Comment 1 Karl Weber CLA 2012-03-24 08:20:45 EDT
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...
Comment 2 Olivier Thomann CLA 2012-03-24 11:26:17 EDT
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.
Comment 3 Srikanth Sankaran CLA 2012-03-24 22:00:19 EDT
(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
Comment 4 Srikanth Sankaran CLA 2012-03-25 03:01:16 EDT
(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.
Comment 5 Srikanth Sankaran CLA 2012-03-25 03:21:26 EDT
Created attachment 213143 [details]
Patch under test

Also has a few more junits.
Comment 6 Srikanth Sankaran CLA 2012-03-25 06:26:32 EDT
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.
Comment 7 Srikanth Sankaran CLA 2012-03-25 06:27:01 EDT
Satyam, please review, TIA.
Comment 8 Satyam Kandula CLA 2012-03-26 01:54:31 EDT
The changes look good to me.
Comment 9 Srikanth Sankaran CLA 2012-03-29 00:27:48 EDT
Dani, do you want this Java 7 fix for 3.6.2+Java7 and 3.7.2+ streams ?
The fix is very safe IMO.
Comment 10 Dani Megert CLA 2012-03-29 10:05:06 EDT
I verified the code and that the fix works.
+1 to backport.
Comment 11 Dani Megert CLA 2012-03-29 10:05:23 EDT
Reopening for backport.
Comment 12 Satyam Kandula CLA 2012-03-30 09:29:57 EDT
Released on 3.7 maintenance using commit 6c7abe90183484d585c334aa10f32c5f8581b4a1
Comment 13 Satyam Kandula CLA 2012-03-30 11:55:08 EDT
Released on 3.6.2+J7 using commit c5c1cc11b405a60f0f2b3d63b95571e3500fa5dc
Comment 14 Ayushman Jain CLA 2012-04-30 13:14:45 EDT
Verified for 3.8M7 using build I20120429-1800.