Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 367879 - Incorrect "Potential null pointer access" warning on statement after try-with-resources within try-finally
Summary: Incorrect "Potential null pointer access" warning on statement after try-with...
Status: VERIFIED DUPLICATE of bug 358827
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.7.1   Edit
Hardware: PC Windows XP
: P3 minor (vote)
Target Milestone: 3.7.2   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-01-04 12:50 EST by Sean Van Gorder CLA
Modified: 2012-03-12 04:22 EDT (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sean Van Gorder CLA 2012-01-04 12:50:47 EST
Build Identifier: Version: Indigo Service Release 1 Build id: 20110916-0149

Eclipse will incorrectly mark a variable with the warning "Potential null pointer access: The variable [name] may be null at this location" under very specific circumstances. This example is as far as I could narrow it down:

public void test() throws IOException {
	HttpURLConnection http = null;
	try {
		http = (HttpURLConnection) new URL("http://example.com/").openConnection();
		try (InputStream in = http.getInputStream()) { /* get input */ }
		http.getURL(); // WARNING: Potential null pointer access
	} finally {
		if (http != null) { /* http.disconnect(); */ }
	}
}

Uncommenting the "http.disconnect();" in the finally block has no effect. However, if that line is changed to simply "http.disconnect();" without the null check, the warning will correctly appear on that "http", and will no longer appear on the one in the try block.

Changing nearly anything else will cause the warning to disappear, including:
- Adding "catch (IOException e) { }" after the outer try block
- Adding "catch (IOException e) { }" after the try-with block
- Deleting the "if (http != null)" line, leaving the finally block empty
- Removing the outer try/finally construct, leaving only the 3 lines from the try block
- Deleting the try-with line
- Replacing the try-with line with the old finally-close method:
		InputStream in = null;
		try {
			in = http.getInputStream();
		} finally {
			if (in != null) in.close();
		}

The try-with replacement is the only real workaround to this issue.  Although, attempting to replace the old format with a try-with block is how I noticed the issue in the first place...

Reproducible: Always

Steps to Reproduce:
Copy the "test" method above into a new class.
Comment 1 Sean Van Gorder CLA 2012-01-04 13:12:37 EST
Another possible workaround: adding "catch (Exception e) { throw e; }" after the try-with block. I'm not 100% sure this has no side-effects apart from somehow avoiding this bug.
Comment 2 Stephan Herrmann CLA 2012-01-04 18:33:37 EST
This indeed looks weird. Many thanks for extracting the test case.

Luckily, it seems we already fixed this: 
I can reproduce only with builds < 3.8M3.
Most probably, this was fixed by the patch in bug 358827,
which has been released for 3.8M3 and also for 3.7.2.

Could you please check on your original sources with a more recent build,
e.g. a 3.7 maintenance build like:
http://download.eclipse.org/eclipse/downloads/drops/M20111214-1406 ?

Anyway we should add your test case to our suite, because it actually
triggers the same bug in a different way than the test in bug 358827.
Comment 3 Stephan Herrmann CLA 2012-01-04 18:39:24 EST
As an aside here's variant that demonstrates pretty well what's going on:

	public void test() throws IOException {
	    HttpURLConnection http = null;
	    try {
	        http = (HttpURLConnection) new URL("http://example.com/").openConnection();
	        try (InputStream in = http.getInputStream()) { /* get input */ }
	        http.getURL();
	    } finally {
	        if (http != null) { http.disconnect(); }
	        http.getURL(); // WARNING: Potential null pointer access - OK
	    }
	}

Now the warning is issued at the last line and not at the wrong location.
The if statement sheds doubt on the nullness of http and obviously in
the buggy case this information is wrongly folded back into the try-block.
This nicely matches the explanation in bug 358827 comment 0.
Comment 4 Stephan Herrmann CLA 2012-01-05 03:59:19 EST
I verified that the patch from bug 358827 indeed toggles also this bug
(the part in FlowContext actually).

I added the example as a new regression test and released it for 3.8M5 
via commit e62c45ebe5881b0e2838be4fcb8a4a48c85b9c0c
Comment 5 Ayushman Jain CLA 2012-01-05 07:40:35 EST
Thanks Stephan. 
Marking as a dup seems like a better resolution though, since nothing was fixed as such.

*** This bug has been marked as a duplicate of bug 358827 ***
Comment 6 Stephan Herrmann CLA 2012-01-05 07:56:05 EST
(In reply to comment #5)
> Thanks Stephan. 
> Marking as a dup seems like a better resolution though, since nothing was 
> fixed as such.

That's fine. I just wanted to use this as the reference bug for the added 
test case :)
Comment 7 Sean Van Gorder CLA 2012-01-05 09:48:49 EST
(In reply to comment #2)
> Could you please check on your original sources with a more recent build,
> e.g. a 3.7 maintenance build like:
> http://download.eclipse.org/eclipse/downloads/drops/M20111214-1406 ?
> 
> Anyway we should add your test case to our suite, because it actually
> triggers the same bug in a different way than the test in bug 358827.

Verified fixed in M20111214-1406. Glad to hear I could help with regression testing.
Comment 8 Satyam Kandula CLA 2012-01-19 00:49:33 EST
Verified for 3.7.2RC2 using build M20120118-0800
Comment 9 Jay Arthanareeswaran CLA 2012-03-12 02:05:10 EDT
This seem to have been missed out in our M5 verification. Marking it for M6.
Comment 10 Srikanth Sankaran CLA 2012-03-12 04:22:50 EDT
I could verify that this bugs shows up in 3.8 M1 and not in
Build id: I20120306-0800. Verified for 3.8 M6.