[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xmlbeans-dev
Subject:    [jira] [Updated] (XMLBEANS-477) Piccolo parser improperly retains and re-closes InputStream from pre
From:       "Robby Morgan (Updated) (JIRA)" <xmlbeans-dev () xml ! apache ! org>
Date:       2012-01-19 14:10:41
Message-ID: 1704243890.56159.1326982241682.JavaMail.tomcat () hel ! zones ! apache ! org
[Download RAW message or body]


     [ https://issues.apache.org/jira/browse/XMLBEANS-477?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel \
]

Robby Morgan updated XMLBEANS-477:
----------------------------------

    Description: 
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 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}

  was:
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}

    
> 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 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: dev-unsubscribe@xmlbeans.apache.org
For additional commands, e-mail: dev-help@xmlbeans.apache.org


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic