JDK-8024521 : (process) Async close issues with Process InputStream
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 7u1
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2013-09-10
  • Updated: 2014-02-12
  • Resolved: 2013-10-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7u60Fixed 8 b115Fixed
Related Reports
Relates :  
Relates :  
Description
SHORT SUMMARY:

Closing ProcessPipeInputStream at the time the process exits is racy and leads to the data corruption.

INDICATORS:
 
COUNTER INDICATORS:
 
TRIGGERS:
 
KNOWN WORKAROUND: Customer able to workaround the problem by synchronizing the inputstream.
  
PRESENT SINCE:  7
  
HOW TO VERIFY: Run the test CloseRace.java associated with the bug in bugdb
 
NOTES FOR SE: None
 
REGRESSION: No
Comments
Verified by the regression test provided with the fix. Enhancement is tracked by JDK-8027348
22-11-2013

SQE is ok to take the fix in 7u60 as it is an escalation. Please provide testing recommendations.
13-11-2013

An easy straightforward solution seems to be synchronizing ProcessPipeInputStream#close() and ProcessPipeInputStream#processExited(). However I'm not confident this doesn't have a drawback. static class ProcessPipeInputStream extends BufferedInputStream { + private Object closeLock = new Object(); + ProcessPipeInputStream(int fd) { super(new FileInputStream(newFileDescriptor(fd))); } @@ -360,6 +362,7 @@ synchronized void processExited() { // Most BufferedInputStream methods are synchronized, but close() // is not, and so we have to handle concurrent racing close(). + synchronized (closeLock) { try { InputStream in = this.in; if (in != null) { @@ -372,7 +375,14 @@ this.in = null; } } catch (IOException ignored) { - // probably an asynchronous close(). + } + } + } + + public void close() + throws IOException { + synchronized (closeLock) { + super.close(); } } }
25-09-2013

This bug is reproducible with jdk8. Raising its priority as it was escalated by the customer.
25-09-2013