Bug 868136

Summary: File descriptors not closed correctly in some JRE classes
Product: Red Hat Enterprise Linux 6 Reporter: James Livingston <jlivings>
Component: java-1.7.0-openjdkAssignee: Andrew John Hughes <ahughes>
Status: CLOSED CURRENTRELEASE QA Contact: BaseOS QE - Apps <qe-baseos-apps>
Severity: low Docs Contact:
Priority: unspecified    
Version: 6.3CC: dbhole, joallen, jvanek
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: All   
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2013-08-07 11:41:36 EDT Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Description James Livingston 2012-10-19 02:31:33 EDT
Various JRE classes shipped with OpenJDK do not close FileInputStream (and similar) objects when they are finished with them. That means the file descriptors are left open until the garbage collector finalises them.

Most/all of these affect JDK 6, 7 and 8.

It is possible to locate these by using the Byteman script from https://access.redhat.com/knowledge/solutions/233633. Any "finalizing" lines it writes to the "FileInputStream.txt" file indicate a FileDescriptor object which was finalized without having it's close() method explicitly called first.

Searching back through the output file for the object id will in many cases give you the stack trace of what caused the descriptor to be opened, which can lead you to the offending code. The ones I've found so far are by running it against JBoss.

com.sun.naming.internal.ResourceManager.getApplicationResources() opens a number of input streams which it does not close with the lines:
    NamingEnumeration<InputStream> resources = helper.getResources(cl, APP_RESOURCE_FILE_NAME);
    InputStream istream = helper.getJavaHomeLibStream(JRELIB_PROPERTY_FILE_NAME);

I've created an OpenJDK bug for this, and am waiting for it to be public before posting the link here. The fix for the getJavaHomeLibStream case is trivial, closing it in a finally block.

The fix for getResources() is more complicated since if an exception is thrown, since to close all potential streams, it would need to continue to read from the enumeration closing them all. The actual implementation behind the helper does not open the stream until it's read from the enumeration however.

java.util.jar.Manifest's constructor takes an input stream which it passed to read(). It is not clear from the JavaDoc whether the caller or Manifest itself is responsible for closing the passed input stream.

Since read() wraps the passed one in a FastInputStream which does buffering, the caller can't rely on the state of the InputStream after the constuctor/read call finishes. Manifest doesn't close the stream itself however.

If Manifest should close it, it should be changed to do so. If it shouldn't close it, then I'll file a JBoss Modules bug.
Comment 1 James Livingston 2012-10-19 02:33:49 EDT
These bugs are generally not critical, since the file descriptors are closed, just not as soon as they can be. The only situation where they may cause problems is if they are called repeatedly, and it causes the file descriptor limit to be hit before the ones that are garbage are finalised.
Comment 3 Deepak Bhole 2012-10-19 11:53:58 EDT
Hi James -- Does the patch you have cover only part of the fix (getJavaHomeLibStream) or does it also address getResources())?
Comment 4 James Livingston 2012-10-22 01:25:21 EDT
I've attached the patch to the IcedTea bug, but can post it here too if you want.
Comment 5 Andrew John Hughes 2012-10-22 13:16:45 EDT
No, that's fine.
Comment 6 Andrew John Hughes 2012-11-07 16:22:25 EST
The patch is in OpenJDK8:


However, Oracle would prefer it was updated to use try-with-resources.
Comment 8 Andrew John Hughes 2013-06-26 00:03:45 EDT
Fixed in 2.4.0: http://blog.fuseyism.com/index.php/2013/06/10/icedtea-2-4-0-released/
Comment 9 Andrew John Hughes 2013-07-11 16:52:55 EDT
Jiri, please update when 2.4.x is available in RHEL 6.x.
Comment 10 Deepak Bhole 2013-08-07 11:41:36 EDT
We are currently using 2.4.1. Marking closed.