You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by bu...@apache.org on 2002/09/26 18:54:53 UTC

DO NOT REPLY [Bug 13039] New: - Xalan's DOMSource is not thread-safe

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13039>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13039

Xalan's DOMSource is not thread-safe

           Summary: Xalan's DOMSource is not thread-safe
           Product: XalanJ2
           Version: 2.3Dx
          Platform: PC
        OS/Version: Windows NT/2K
            Status: NEW
          Severity: Critical
          Priority: Other
         Component: javax.xml
        AssignedTo: xalan-dev@xml.apache.org
        ReportedBy: vlad.mamut@citicorp.com


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