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

Xalan's DOMSource is not thread-safe

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Critical
    • Resolution: Won't Fix
    • 2.3Dx
    • None
    • JAXP
    • 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
    • 13039

    Description

      When using Xalan in a multi-threaded environment and DOMSource is used for
      transformations, occasional java.lang.NullPointerException are thrown.
      A program running multiple printing threads accesses the same DOM document. The
      printing uses transformation to serialize the document content into an output
      stream. An exception is thrown when Transformer.transform() is called. Replacing
      DOMSource with StreamSource seems to alleviate the problem.

      Attached are the test results and the source used to reproduce the problem.

      Similar results (NullPointerExceptions in
      org.apache.xml.utils.TreeWalker.dispatachChars) are produced when using
      Serializer in multi-threaded environment. It might be a separate issue deserving
      it 'own' bug.

      Case 1 (exception in 2 threads)
      *******************************
      C:\CitiFile\PrintException>java TestSerializer C:\Citifile\PrintException\data.x
      ml
      Classpath: .;xalan.jar;xml-apis.jar
      Starting processing Thread ID: 0
      Enter Print Thread ID: 0
      Starting processing Thread ID: 1
      Enter Print Thread ID: 1
      Starting processing Thread ID: 2
      Enter Print Thread ID: 2
      Exception in Thread ID: 1
      java.lang.NullPointerException
      at org.apache.xml.utils.TreeWalker.dispatachChars(TreeWalker.java:275)
      at org.apache.xml.utils.TreeWalker.startNode(TreeWalker.java:419)
      at org.apache.xml.utils.TreeWalker.traverse(TreeWalker.java:183)
      at org.apache.xalan.transformer.TransformerIdentityImpl.transform(Transf
      ormerIdentityImpl.java:325)
      at SerializerThread.printXMLdocument(SerializerThread.java:46)
      at SerializerThread.run(SerializerThread.java:26)
      Exception in Thread ID: 0
      java.lang.NullPointerException
      at org.apache.xml.utils.TreeWalker.dispatachChars(TreeWalker.java:275)
      at org.apache.xml.utils.TreeWalker.startNode(TreeWalker.java:419)
      at org.apache.xml.utils.TreeWalker.traverse(TreeWalker.java:183)
      at org.apache.xalan.transformer.TransformerIdentityImpl.transform(Transf
      ormerIdentityImpl.java:325)
      at SerializerThread.printXMLdocument(SerializerThread.java:46)
      at SerializerThread.run(SerializerThread.java:26)
      Exit Print Thread ID: 2
      Completed Thread ID: 2

      Case 2 (exception in 1 thread)
      ******************************
      C:\CitiFile\PrintException>java TestSerializer C:\Citifile\PrintException\data.x
      ml
      Classpath: .;xalan.jar;xml-apis.jar
      Starting processing Thread ID: 0
      Enter Print Thread ID: 0
      Starting processing Thread ID: 1
      Enter Print Thread ID: 1
      Starting processing Thread ID: 2
      Enter Print Thread ID: 2
      Exception in Thread ID: 1
      java.lang.NullPointerException
      at org.apache.xml.utils.TreeWalker.dispatachChars(TreeWalker.java:275)
      at org.apache.xml.utils.TreeWalker.startNode(TreeWalker.java:419)
      at org.apache.xml.utils.TreeWalker.traverse(TreeWalker.java:183)
      at org.apache.xalan.transformer.TransformerIdentityImpl.transform(Transf
      ormerIdentityImpl.java:325)
      at SerializerThread.printXMLdocument(SerializerThread.java:46)
      at SerializerThread.run(SerializerThread.java:26)
      Exit Print Thread ID: 0
      Completed Thread ID: 0
      Exit Print Thread ID: 2
      Completed Thread ID: 2

      Case 3 (no exceptions, successful processing)
      *********************************************
      C:\CitiFile\PrintException>java TestSerializer C:\Citifile\PrintException\data.x
      ml
      Classpath: .;xalan.jar;xml-apis.jar
      Starting processing Thread ID: 0
      Enter Print Thread ID: 0
      Starting processing Thread ID: 1
      Enter Print Thread ID: 1
      Starting processing Thread ID: 2
      Enter Print Thread ID: 2
      Exit Print Thread ID: 0
      Completed Thread ID: 0
      Exit Print Thread ID: 1
      Completed Thread ID: 1
      Exit Print Thread ID: 2
      Completed Thread ID: 2

      *****************************************************************************
      import org.w3c.dom.Document;

      import javax.xml.parsers.DocumentBuilder;
      import javax.xml.parsers.DocumentBuilderFactory;

      import java.io.FileInputStream;

      public class TestSerializer {
      public static void main (String[] args) {
      try {
      System.out.println("Classpath: " +
      System.getProperty("java.class.path"));
      DocumentBuilderFactory dbFactory =
      DocumentBuilderFactory.newInstance();
      DocumentBuilder dBuilder =
      dbFactory.newDocumentBuilder();
      Document xmlDocument = dBuilder.parse(new
      FileInputStream("data.xml"));
      for (int i=0; i < 3; i++)

      { new SerializerThread(xmlDocument, i).start(); }

      }
      catch (Exception ex)

      { ex.printStackTrace(); }

      }
      }
      *****************************************************************************

      import org.w3c.dom.Document;

      import javax.xml.transform.dom.DOMSource;
      import javax.xml.transform.stream.StreamSource;
      import javax.xml.transform.stream.StreamResult;
      import javax.xml.transform.TransformerFactory;
      import javax.xml.transform.Transformer;

      import java.io.FileInputStream;
      import java.io.FileOutputStream;

      public class SerializerThread extends Thread {

      private Document xmlDocument;
      private int threadId;

      public SerializerThread(Document xmlDocument, int threadId)

      { this.xmlDocument = xmlDocument; this.threadId = threadId; }

      public void run() {
      try

      { System.out.println("Starting processing Thread ID: " + this.threadId); printXMLdocument(this.xmlDocument); System.out.println("Completed Thread ID: " + this.threadId); }

      catch (Exception ex)

      { System.out.println("Exception in Thread ID: " + this.threadId); ex.printStackTrace(); }

      }

      private void printXMLdocument(Document xmlDocument) throws Exception

      { System.out.println("Enter Print Thread ID: " + this.threadId); StreamResult result = new StreamResult(new FileOutputStream("out" + this.threadId + ".xml")); /*** replacing DOMSource with StreamSource works *******/ DOMSource source = new DOMSource(xmlDocument); // StreamSource source = new StreamSource(new FileInputStream("data.xml")); /*******************************************************/ TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(source, result); System.out.println("Exit Print Thread ID: " + this.threadId); }

      }

      *****************************************************************************

      I use:
      Sun JVM (java version "1.3.1_02", Java(TM) 2 Runtime Environment, Standard
      Edition (build 1.3.1_02-b02), Java HotSpot(TM) Client VM (build 1.3.1_02-b02,
      mixed mode))
      Xalan J 2.3.1

      Attachments

        Activity

          People

            Unassigned Unassigned
            vlad.mamut@citicorp.com Vlad Mamut
            Votes:
            1 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: