We recently upgraded our message processing application from Java 7 to Java 8.  Since the upgrade, we get an occasional exception that a stream has been closed while it is being read from.  Logging shows that the finalizer thread is calling finalize() on the object that holds the stream (which in turn closes the stream).
The basic outline of the code is as follows:
MIMEWriter writer = new MIMEWriter( out );
in = new InflaterInputStream( databaseBlobInputStream );
MIMEBodyPart attachmentPart = new MIMEBodyPart( in );
writer.writePart( attachmentPart );
MIMEWriter and MIMEBodyPart are part of a home-grown MIME/HTTP library.  MIMEBodyPart extends HTTPMessage, which has the following:
public void close() throws IOException
{
    if ( m_stream != null )
    {
        m_stream.close();
    }
}
protected void finalize()
{
    try
    {
        close();
    }
    catch ( final Exception ignored ) { }
}
The exception occurs in the invocation chain of MIMEWriter.writePart, which is as follows:
- MIMEWriter.writePart()writes the headers for the part, then calls- part.writeBodyPartContent( this )
- MIMEBodyPart.writeBodyPartContent()calls our utility method- IOUtil.copy( getContentStream(), out )to stream the content to the output
- MIMEBodyPart.getContentStream()just returns the input stream passed into the contstructor (see code block above)
- IOUtil.copyhas a loop that reads an 8K chunk from the input stream and writes it to the output stream until the input stream is empty.
The MIMEBodyPart.finalize() is called while IOUtil.copy is running, and it gets the following exception:
java.io.IOException: Stream closed
    at java.util.zip.InflaterInputStream.ensureOpen(InflaterInputStream.java:67)
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:142)
    at java.io.FilterInputStream.read(FilterInputStream.java:107)
    at com.blah.util.IOUtil.copy(IOUtil.java:153)
    at com.blah.core.net.MIMEBodyPart.writeBodyPartContent(MIMEBodyPart.java:75)
    at com.blah.core.net.MIMEWriter.writePart(MIMEWriter.java:65)
We put some logging in the HTTPMessage.close() method that logged the stack trace of the caller and proved that it is definitely the finalizer thread that is invoking HTTPMessage.finalize() while IOUtil.copy() is running.
The MIMEBodyPart object is definitely reachable from the current thread's stack as this in the stack frame for MIMEBodyPart.writeBodyPartContent.  I don't understand why the JVM would call finalize().
I tried extracting the relevant code and running it in a tight loop on my own machine, but I cannot reproduce the problem. We can reliably reproduce the problem with high load on one of our dev servers, but any attempts to create a smaller reproducible test case have failed. The code is compiled under Java 7 but executes under Java 8. If we switch back to Java 7 without recompiling, the problem does not occur.
As a workaround, I've rewritten the affected code using the Java Mail MIME library and the problem has gone away (presumably Java Mail doesn't use finalize()).  However, I'm concerned that other finalize() methods in the application may be called incorrectly, or that Java is trying to garbage-collect objects that are still in use.
I know that current best practice recommends against using finalize() and I will probably revisit this home-grown library to remove the finalize() methods.  That being said, has anyone come across this issue before?  Does anyone have any ideas as to the cause?
 
     
     
     
    