Florent Guillaume wrote:
Good point.

As a python programmer, I was surprised by this, because python's GC deals with all this stuff and closes things automatically. The thing is, python has a much more deterministic garbage collector than Java, mostly based on reference counting, which means that as soon as a file handle goes out of scope it will be gc'ed and therefore closed.

In Java the GC will finalize a stream and close it, but that's in an indeterminate future and there may have been thousands others file descriptiors open by that time.
Yes you are right. But more, it is not guaranteed that the input stream will be closed by the garbage collector!
This depends on the stream implementation.
For FileInputStream it is true (i.e. GC will close the stream).
If you look inside class source you have a finalize() method that is doing this:

protected void finalize() throws IOException {
   if (fd != null) {
       if (fd != fd.in) {
       close();
       }
   }
}

But the finalize() method is not mandatory and some implementors may not implement it.


For reference, see the following thread and its comments:
http://www.javalobby.org/forums/thread.jspa?threadID=17310

This all comes done to deterministic finalization or not -- Java doesn't have it, so you must do it by hand to avoid leaking non-memory resources like file handles. That's an area where Java still sucks.

Also please note that what you actually should write is:

InputStream in = jndiResourceURL.openStream();
try {
   // do something with the stream
} finally {
   in.close();
}


Not necesarly, it depends ... The openStream() is throwing an IOException.
Usually you may want to intercept this exception.
Thus, the complete code will be like this (yes it is ugly):

InputStream in = null;
try {
   in = url.openStream();
   // do something with the insput stream
} catch (IOException e) {
   // do something with the exception
} finally {
   try {
   if (in != null) {
      in.close();
   } catch (IOException e) {
      // do somethid with the exception
   }
}

But it depends on where your code is located. For example you may put this code in a method that throws IOException In that case using your example is good, because you don't care about IOException:

InputStream in = jndiResourceURL.openStream();
try {
  // do something with the stream
} finally {
  in.close();
}


Florent



On 9 Dec 2006, at 15:00, Bogdan Stefanescu wrote:


I've seen several time in nuxeo sources that streams are not closed after being used. This is very bad. File or URL streams are system resources and you must close them manually.
Please pay attention to this sort of things.

An Example from JNDILookupHelper:

serverContainerLocation.load(jndiResourceURL.openStream());

This is *bad*.

You should write it like this:

InputStream in = null;
try {
   in = jndiResourceURL.openStream();
   // do something with the stream
   // ...
} finally {
   // close the stream!
   if (in != null) in.close();
}


Bogdan


_______________________________________________
ECM mailing list
[email protected]
http://lists.nuxeo.com/mailman/listinfo/ecm


--Florent Guillaume, Director of R&D, Nuxeo
Open Source Enterprise Content Management (ECM)
http://www.nuxeo.com   http://www.nuxeo.org   +33 1 40 33 79 87


_______________________________________________
ECM mailing list
[email protected]
http://lists.nuxeo.com/mailman/listinfo/ecm


_______________________________________________
ECM mailing list
[email protected]
http://lists.nuxeo.com/mailman/listinfo/ecm

Reply via email to