New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ZOOKEEPER-4246: Resource leaks in org.apache.zookeeper.server.persistence.SnapStream#getInputStream and #getOutputStream #1638
Conversation
…ence.SnapStream#getInputStream and #getOutputStream
@kelloggm Looks reasonable.
Could you please show us how the |
@maoling Sorry for the confusion. You asked:
in reference to my comment:
In this comment, I'm using "error-prone" as an adjective - i.e. I'm saying that I think GZIPOutputStream is easy to use incorrectly. I did not intend to refer to error-prone, Google's code analysis tool. From your comment, it sounds like you understood me to mean that tool - sorry for the confusion! As far as I'm aware, that tool cannot find this bug, but I haven't run it on this code. |
@kelloggm Sorry for my misunderstanding for code analysis tool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
@@ -104,10 +104,20 @@ public static CheckedInputStream getInputStream(File file) throws IOException { | |||
InputStream is; | |||
switch (getStreamMode(file.getName())) { | |||
case GZIP: | |||
is = new GZIPInputStream(fis); | |||
try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put the entire block in a try-catch:
try {
switch (getStreamMode(file.getName())) {
case GZIP:
is = new GZIPInputStream(fis);
break;
case SNAPPY:
is = new SnappyInputStream(fis);
break;
case CHECKED:
default:
is = new BufferedInputStream(fis);
}
return new CheckedInputStream(is, new Adler32());
} catch (IOException e) {
fis.close();
throw e;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made this change. Would you all also prefer one try
around the entire switch
in the other method, where only one of the case
s can throw? It would make the code look more symmetrical, but it's otherwise unnecessary.
@maoling no worries, sorry again for the confusion
I didn't encounter these in production, to be clear. I was already familiar with the JDK bug I linked in my bug report, and got suspicious when I saw GZIP was supported here so I looked at the code and noticed these. |
@anmolnar is there anything else you need from me on this PR? It's been a few weeks and I don't want it to be forgotten. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
I've made this change. Would you all also prefer one
try
around the entireswitch
in the other method, where only one of thecase
s can throw? It would make the code look more symmetrical, but it's otherwise unnecessary.
I, for one, have a slight preference for the "symmetrical" version, but let's not bikeshed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm
@kelloggm |
…ence.SnapStream#getInputStream and #getOutputStream Bug report is here: https://issues.apache.org/jira/browse/ZOOKEEPER-4246 This fix is simple: it just closes the possibly-leaked streams and re-throws the exception. We can't use a try-with-resources or a `finally` block here because in the happy case the resulting streams need to be returned open. I checked each of the other constructor calls in these methods, and none of the others can throw an exception as far as I can tell. Author: Martin Kellogg <kelloggm@cs.washington.edu> Reviewers: Andor Molnar <anmolnar@apache.org>, Enrico Olivelli <eolivelli@apache.org>, maoling <maoling@apache.org> Closes apache#1638 from kelloggm/ZOOKEEPER-4246 and squashes the following commits: fa1c0f0 [Martin Kellogg] surround whole switch with one try block instead of two inside the switch f023851 [Martin Kellogg] remove all the tabs for real 04c4b2f [Martin Kellogg] fix accidental tab e896efa [Martin Kellogg] ZOOKEEPER-4246: Resource leaks in org.apache.zookeeper.server.persistence.SnapStream#getInputStream and #getOutputStream
…ence.SnapStream#getInputStream and #getOutputStream (#144) Bug report is here: https://issues.apache.org/jira/browse/ZOOKEEPER-4246 This fix is simple: it just closes the possibly-leaked streams and re-throws the exception. We can't use a try-with-resources or a `finally` block here because in the happy case the resulting streams need to be returned open. I checked each of the other constructor calls in these methods, and none of the others can throw an exception as far as I can tell. Author: Martin Kellogg <kelloggm@cs.washington.edu> Reviewers: Andor Molnar <anmolnar@apache.org>, Enrico Olivelli <eolivelli@apache.org>, maoling <maoling@apache.org> Closes apache#1638 from kelloggm/ZOOKEEPER-4246 and squashes the following commits: fa1c0f0 [Martin Kellogg] surround whole switch with one try block instead of two inside the switch f023851 [Martin Kellogg] remove all the tabs for real 04c4b2f [Martin Kellogg] fix accidental tab e896efa [Martin Kellogg] ZOOKEEPER-4246: Resource leaks in org.apache.zookeeper.server.persistence.SnapStream#getInputStream and #getOutputStream Co-authored-by: Martin Kellogg <kelloggm@cs.washington.edu>
Bug report is here: https://issues.apache.org/jira/browse/ZOOKEEPER-4246
This fix is simple: it just closes the possibly-leaked streams and re-throws the exception. We can't use a try-with-resources or a
finally
block here because in the happy case the resulting streams need to be returned open. I checked each of the other constructor calls in these methods, and none of the others can throw an exception as far as I can tell.