I know that there are a couple of similarly entitled questions out there, but most of them have simply forgotten to put a close()
directive on their stream. This here is different.
Lets say I have the following minimal example:
public void test() throws IOException
{
InputStream in;
if( file.exists() )
{
in = new FileInputStream( file );
}
else
{
in = new URL( "some url" ).openStream();
}
in.close();
}
This give me a Resource leak: 'in' is never closed
warning in Eclipse (Juno SR1).
But when I move the in.close()
into the conditional block, the warnings vanishes:
public void test() throws IOException
{
InputStream in;
if( file.exists() )
{
in = new GZIPInputStream( new FileInputStream( file ) );
in.close();
}
else
{
in = new URL( "some URL" ).openStream();
}
}
What is going on here?
A resource leak occurs when you don't close a reader, scanner, buffer, or another process that uses resources and needs to clean them up out of memory. You would call scanner. close() after you use the Scanner for whatever you're doing with it.
Resource leaks are bugs that arise when a program doesn't release the resources it has acquired. Resource leaks can lead to resource exhaustion. In the worst case, they can cause the system to slow down or even crash. Starting with Java 7, most classes holding resources implement the java.
In computer science, a resource leak is a particular type of resource consumption by a computer program where the program does not release resources it has acquired. This condition is normally the result of a bug in a program.
Because of the IO exception, you can run into a resource leak (poentially)
Try doing the following:
public void test() throws IOException
{
InputStream in= null;
try {
if( file.exists() )
{
// In this case, if the FileInputStream call does not
// throw a FileNotFoundException (descendant of IOException)
// it will create the input stream which you are wrapping
// in a GZIPInputStream (no IO exception on construction)
in = new GZIPInputStream( new FileInputStream( file ) );
}
else
{
// Here however, if you are able to create the URL
// object, "some url" is a valid URL, when you call
// openStream() you have the potential of creating
// the input stream. new URL(String spec) will throw
// a MalformedURLException which is also a descendant of
// IOException.
in = new URL( "some url" ).openStream();
}
// Do work on the 'in' here
} finally {
if( null != in ) {
try
{
in.close();
} catch(IOException ex) {
// log or fail if you like
}
}
}
}
Doing the above will make sure you've closed the stream or at least made a best effort to do so.
In your original code, you had the InputStream declared but never initialized. That is bad form to begin with. Initialize that to null as I illustrated above. My feeling, and I'm not running Juno at the moment, is that it sees that the InputStream 'in', may potentially make it through all the hoops and hurdles to get to the point at which you are going to use it. Unfortunate, as someone pointed out, your code is a bit dodgy for an example. Doing this as I've detailed as well as @duffymo you'll get rid of the warning.
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