There is a nice function I use on IOUtils called "closeQuietly" , which closes the stream no matter what is in there.
for example:
InputStream input = null;
try
{
...
input = connection.getInputStream();
...
}
catch(Exception e)
{
}
finally
{
IOUtils.closeQuietly(input);
}
Somehow, it also hides the warning on Eclipse when I call it in the finally block , of "Resource leak: 'input' is not closed at this location" .
This means that in the above code, there is no such warning.
I don't understand how it hides the warning on the "outside world" of itself.
I've tried to check it out by copying the code of this library (example here), but the warning appears when I use it on the new class. It doesn't make sense...
here's a sample code i've created to show that the warning will occur on your own classes:
public class MyIOUtils {
public static void closeQuietly(final InputStream input) {
if (input == null)
return;
try {
input.close();
} catch (final IOException ioe) {
}
}
public static void closeQuietly(final OutputStream output) {
if (output == null)
return;
try {
output.close();
} catch (final IOException ioe) {
}
}
}
usage:
public class Test {
public void test() {
InputStream inputStream = null;
try {
inputStream = new FileInputStream("dummyFile.txt");
int t = 0;
--t;
if (t < 0)
return; // here you will get a warning
} catch (final FileNotFoundException e) {
} finally {
MyIOUtils.closeQuietly(inputStream);
}
}
}
Here's what I see, including the Eclipse version I have being installed:
How does it do it?
So why does it work for IOUtils? The eclipse team did something very plain - they hardcoded the methods! In previous versions of eclipse the warning was also there however starting from version 4.3 M4 it was gone since they fixed it:
Released for 4.3 M4 via commit 277792ba446c3713bcfdc898c37875d45fc06c18.
The fix covers the following well-known methods:
- com.google.common.io.Closeables.closeQuietly(Closeable)
- com.google.common.io.Closeables.close(Closeable,boolean)
- org.apache.commons.io.IOUtils.closeQuietly(Closeable)
For details see here - especially at the comments at the end...
UPDATE: So what does it mean for you? You have to use one of the obove methods or live with the warning. The check is basically not sophisticated and doesn't check the next level.
Update II: They basically hardcoded the file names. Maybe it is easer to understand with source code. Imagine this is the eclipse code checking for the warning:
public boolean showResourceWarning(){
//do somestuff to detect whether a potential ressource warning is shown
...
if(resourceLeakWarning){
if(this.checkForExceptions()){
return false;
}
}
return resourceLeakWarning;
}
private boolean checkForExceptions(){
if(name.equals("org.apache.commons.io.IOUtils.closeQuietly(Closeable)"){
return true;
}
if(name.equals("com.google.common.io.Closeables.close(Closeable,boolean)")){
return true;
}
if(name.equals("org.apache.commons.io.IOUtils.closeQuietly(Closeable)")){
return true;
}
// code executed for your method:
return false;
}
=> The result is, that you don't have a chance to remove the warning other to directly use close() (not in a sub method!) or to use one of the three methods listed above.
Update III: Have a look at the following class TypeConstants.java. Do you see the hardwired names in there? If you want to make it work with your code you need to add your class and method name there and then recompile eclipse. Then look at the class MessageSend.java starting from line 90.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With