JDK-6539065 : XMLStreamReader close the underlaying stream
  • Type: Bug
  • Component: xml
  • Sub-Component: jaxp
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Future Project
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-03-26
  • Updated: 2021-05-27
  • Resolved: 2007-09-17
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Windows XP, Windows 200

A DESCRIPTION OF THE PROBLEM :
XMLStreamReader close the underlying stream when next method is called and the node type is "End Document".

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Read more than one XML from the same stream. (See source code)




EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
XMLStreamReader never close the underlying stream as says the documentation.
ACTUAL -
XMLStreamReader close the stream

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.io.IOException: Stream closed
	at java.util.zip.ZipInputStream.ensureOpen(ZipInputStream.java:44)
	at java.util.zip.ZipInputStream.closeEntry(ZipInputStream.java:91)
	at XMLStreamReaderBug.main(XMLStreamReaderBug.java:47)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

public class XMLStreamReaderBug {
	
	private static String FILENAME = "XMLStreamReaderBug.zip";
	
	public static void main(String[] args) throws IOException, XMLStreamException {
		
		ZipOutputStream zos = new ZipOutputStream(
				new FileOutputStream(FILENAME));
		
		zos.putNextEntry(new ZipEntry("a.xml"));
		writeXML(zos);
		zos.closeEntry();

		zos.putNextEntry(new ZipEntry("b.xml"));
		writeXML(zos);
		zos.closeEntry();
		
		zos.close();
		
		ZipInputStream zis = new ZipInputStream(
				new FileInputStream(FILENAME));
		
		for(ZipEntry entry = zis.getNextEntry();
			entry != null;
			entry = zis.getNextEntry()){
			
			readXML(zis);
			
			zis.closeEntry();
		}
		zis.close();
	}
	
	private static void writeXML(OutputStream os) throws XMLStreamException{
		XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
		XMLStreamWriter writer = outputFactory.createXMLStreamWriter(os);
		writer.writeStartDocument();
		writer.writeStartElement("test");
		writer.writeCharacters("test");
		writer.writeEndElement();
		writer.writeEndDocument();
		writer.close();
	}
	
	private static void readXML(InputStream is) throws XMLStreamException{
		
		XMLInputFactory factory = XMLInputFactory.newInstance();
		XMLStreamReader reader = factory.createXMLStreamReader(is);
				
		for (int nodeType = reader.next();
			nodeType != XMLStreamReader.END_DOCUMENT;
			nodeType = reader.next()) {
			//BUG: When nodeType == END_DOCUMENT -> Reader close stream
			System.out.println(nodeType);
		}
		reader.close();
	}
	
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Overload  Stream  close method:
FileInputStream fis = new FileInputStream(FILENAME);
ZipInputStream zis = new ZipInputStream(fis){
	public void close() throws IOException {
	//Do nothing
	}
};
		
//Do something
		
fis.close();

Comments
EVALUATION The recommended change, that is, the stream reader not to close the underlying stream, is regarded as a non-backward compatible change. This issue will be analyzed further in future jaxp release.
17-09-2007

EVALUATION This is a known issue and added to the JAXP release notes (https://jaxp.dev.java.net/1.4/1.4.2/ReleaseNotes.html). The JavaDoc indeed indicates that the reader does not close the underlying input source. However, the current behavior, that is, closing the underlying stream is compatible with other popular implementations. Furthermore, changing the behavior could potentially cause problems to applications that have been designed to rely on the stream reader to close the stream. Note that this issue is produciable using ZipInputStream, but not FileInputStream since calling close() has no effect when the stream has already been closed. When using ZipInputStream and others that do, please refer to the customer-submitted workaround at the end of the description.
19-07-2007