Uploaded image for project: 'XalanJ2'
  1. XalanJ2
  2. XALANJ-78

OutputStream or Writer inside StreamResult always get flushed by Transformer.transform()

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Resolution: Won't Fix
    • 2.0.1
    • None
    • Serialization
    • Security Level: No security risk; visible to anyone (Ordinary problems in Xalan projects. Anybody can view the issue.)
    • None
    • Operating System: Windows NT/2K
      Platform: PC
    • 1083

    Description

      This test class is based on the sample SimpleTransform class. I enxtended
      BufferedOutputStream and BufferedWriter so we know when they get flushed.

      import javax.xml.transform.*;
      import javax.xml.transform.stream.*;
      import java.io.*;

      public class TestXalanFlush {
      public static void main(String[] args)
      throws TransformerException, TransformerConfigurationException,
      FileNotFoundException,
      IOException
      {
      TransformerFactory tFactory = TransformerFactory.newInstance();
      Transformer transformer = tFactory.newTransformer(new
      StreamSource("birds.xsl"));
      OutputStream myOutputStream =
      new BufferedOutputStream ( new FileOutputStream
      ("birds.out") ) {
      public void flush() throws
      IOException

      { System.out.println ("\nflush called on OutputStream:"); Thread.dumpStack(); super.flush(); }

      };
      transformer.transform(new StreamSource("birds.xml"), new
      StreamResult(myOutputStream) );
      myOutputStream.flush();

      BufferedWriter myWriter =
      new BufferedWriter( new FileWriter
      ("birds.out") ) {
      public void flush() throws
      IOException

      { System.out.println ("flush called on Writer:"); Thread.dumpStack(); super.flush(); }

      };
      transformer.transform(new StreamSource("birds.xml"), new
      StreamResult(myWriter) );
      myWriter.flush();

      }
      }

      The output is:
      flush called on OutputStream:
      java.lang.Exception: Stack trace
      at java.lang.Thread.dumpStack(Thread.java:993)
      at TestXalanFlush$1.flush(TestXalanFlush.java:16)
      at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:245)
      at org.apache.xalan.serialize.SerializerToXML.flushWriter
      (SerializerToXML.java:147
      1)
      at org.apache.xalan.serialize.SerializerToXML.endDocument
      (SerializerToXML.java:662
      )
      at org.apache.xalan.transformer.ResultTreeHandler.endDocument
      (ResultTreeHandler.ja
      va:193)
      at org.apache.xalan.transformer.TransformerImpl.transformNode
      (TransformerImpl.java
      :1224)
      at org.apache.xalan.transformer.TransformerImpl.run
      (TransformerImpl.java:2942)
      at java.lang.Thread.run(Thread.java:484)

      flush called on OutputStream:
      java.lang.Exception: Stack trace
      at java.lang.Thread.dumpStack(Thread.java:993)
      at TestXalanFlush$1.flush(TestXalanFlush.java:16)
      at TestXalanFlush.main(TestXalanFlush.java:22)
      flush called on Writer:
      java.lang.Exception: Stack trace
      at java.lang.Thread.dumpStack(Thread.java:993)
      at TestXalanFlush$2.flush(TestXalanFlush.java:28)
      at org.apache.xalan.serialize.SerializerToXML.flushWriter
      (SerializerToXML.java:147
      1)
      at org.apache.xalan.serialize.SerializerToXML.endDocument
      (SerializerToXML.java:662
      )
      at org.apache.xalan.transformer.ResultTreeHandler.endDocument
      (ResultTreeHandler.ja
      va:193)
      at org.apache.xalan.transformer.TransformerImpl.transformNode
      (TransformerImpl.java
      :1224)
      at org.apache.xalan.transformer.TransformerImpl.run
      (TransformerImpl.java:2942)
      at java.lang.Thread.run(Thread.java:484)
      flush called on Writer:
      java.lang.Exception: Stack trace
      at java.lang.Thread.dumpStack(Thread.java:993)
      at TestXalanFlush$2.flush(TestXalanFlush.java:28)
      at TestXalanFlush.main(TestXalanFlush.java:34)

      We see that the OutputStream and Writer are automatically flushed by
      org.apache.xalan.serialize.SerializerToXML.flushWriter(). This should not
      happen.

      In terms of the Writer, the SerializerToXML class has a flag m_shouldFlush
      which tells if flushWriter() should flush the writer, and its init(Writer,
      Properties) method does set the flag to false. However, when
      Transformer.tranform(StreamSource, StreamResult) method is called the
      SerializeToXML.init(Writer, Properties) method is never called, instead
      setWriter(Writer) is called, which does nothing with the flag. And the
      m_shouldFlush flag defaults to true. Thus the flush. I think the fix should
      be to add

      m_shouldFlush = false;

      to setWriter(Writer) method. (Or does it make more sense to let m_shouldFlush
      flag default to false?)

      In terms of the OutputStream, org.apache.xalan.serialize.Encodings.getWriter
      (OutputStream output, String encoding) method is called to construct a writer
      to wrap around the OutputStream, and certainly SerializerToXML should flush the
      writer. However the constructed wrapper Writer is of class
      java.io.OutputStreamWriter, whose flush() method calls flush() on the
      underlying OutputStream. It is arguable if this is desirable. If this is
      considered acceptable, then it should be documented that any OutputStream
      passed in SerializerToXML or StreamResult will be flushed automatically in the
      end. If this is considered unacceptable, then we should implement our own
      version of OutputStreamWriter which in its flush() method does not call flush()
      on the underlying OutputStream.

      Attachments

        Activity

          People

            Unassigned Unassigned
            czhao@commonvision.com Chuck H. Zhao
            Votes:
            1 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: