Piccolo parser improperly retains and re-closes InputStream from previous
invocation
------------------------------------------------------------------------------------
Key: XMLBEANS-477
URL: https://issues.apache.org/jira/browse/XMLBEANS-477
Project: XMLBeans
Issue Type: Bug
Affects Versions: Version 2.4 , Version 2.5
Reporter: Robby Morgan
I have uncovered odd behavior within the Piccolo parser when XMLBeans is asked
to parse a second document on the same thread. What I have observed is that,
while the Piccolo parser closes the input stream after parsing the first
document, it retains a reference to the input stream and closes it again
immediately before parsing the input stream for the second document. If the
input stream reference is the same for the two documents, as is the case when a
request is processed on the same thread in Tomcat, then the second document
will fail to parse.
Here is sample code that demonstrates the issue:
{code}
import my.xmlbeans.ServerDocument;
import org.apache.commons.io.input.ProxyInputStream;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Issue: XmlBeans (when using the Piccolo SAX parser) retains a reference to
the previous input stream on the
* current thread, and if that stream is reopened and passed back into
XmlBeans, then the stream will be closed
* prior to parsing any of the contents, producing the following exception:
*
* Exception in thread "main" java.lang.IllegalStateException: Stream is
already closed
* at
com.bazaarvoice.pacman.tools.XmlBeansReclosingIssue$ReopenableInputStream.beforeRead(XmlBeansReclosingIssue.java:50)
* at
org.apache.commons.io.input.ProxyInputStream.read(ProxyInputStream.java:98)
* at
org.apache.xmlbeans.impl.piccolo.xml.XMLStreamReader.fillByteBuffer(XMLStreamReader.java:209)
* at
org.apache.xmlbeans.impl.piccolo.xml.XMLStreamReader.reset(XMLStreamReader.java:97)
* at
org.apache.xmlbeans.impl.piccolo.xml.DocumentEntity.open(DocumentEntity.java:94)
* at
org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.reset(PiccoloLexer.java:982)
* at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.parse(Piccolo.java:709)
* at org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:3454)
* at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1276)
* at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1250)
* at
org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:345)
* at my.xmlbeans.ServerDocument$Factory.parse(Unknown Source)
* at XmlBeansReclosingIssue.main(XmlBeansReclosingIssue.java:40)
*/
public class XmlBeansReclosingIssue {
public static void main(String[] args) throws IOException, XmlException {
File inputFile = new File(args[0]);
ReopenableInputStream reopenableInputStream = new
ReopenableInputStream(new FileInputStream(inputFile));
ServerDocument.Factory.parse(reopenableInputStream, new
XmlOptions().setUnsynchronized());
reopenableInputStream.reopen(new FileInputStream(inputFile));
ServerDocument.Factory.parse(reopenableInputStream, new
XmlOptions().setUnsynchronized());
}
private static class ReopenableInputStream extends ProxyInputStream {
private boolean _closed;
public ReopenableInputStream(FileInputStream inputStream) {
super(inputStream);
_closed = false;
}
public void reopen(InputStream in) {
if (!_closed) {
throw new IllegalStateException("Stream is not closed");
}
_closed = false;
this.in = in;
}
@Override
protected void beforeRead(int n) throws IOException {
if (_closed) {
throw new IllegalStateException("Stream is already closed");
}
}
@Override
public void close() throws IOException {
if (_closed) {
throw new IllegalStateException("Stream is already closed");
}
_closed = true;
super.close();
}
}
}
{code}
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]