United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6660724 Lock Contention in SAX2DOM()
JDK-6660724 : Lock Contention in SAX2DOM()

Details
Type:
Bug
Submit Date:
2008-02-07
Status:
Closed
Updated Date:
2012-04-25
Project Name:
JDK
Resolved Date:
2008-05-14
Component:
xml
OS:
solaris_10
Sub-Component:
org.w3c.dom
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.4.2_25
Fixed Versions:
1.4.0 (1.4)

Related Reports
Backport:
Backport:

Sub Tasks

Description
Lock contention while running web service tests to analyze the performance of JCAPS. The web service is a very simple EJB that echoes the request back as the response. The JStack output is given below. 

"httpSSLWorkerThread-8080-58" daemon prio=3 tid=0x0a406000 nid=0x1e0 waiting for monitor entry [0x2c654000..0x2c6559f0]
  java.lang.Thread.State: BLOCKED (on object monitor)
       at com.sun.org.apache.xalan.internal.xsltc.trax.SAX2DOM.<init>(SAX2DOM.java:68)
       - waiting to lock <0x3730c410> (a java.lang.Class for com.sun.org.apache.xalan.internal.xsltc.trax.SAX2DOM)
       at com.sun.org.apache.xalan.internal.xsltc.runtime.output.TransletOutputHandlerFactory.getSerializationHandler(TransletOutputHandlerFactory.java:187)
       at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.getOutputHandler(TransformerImpl.java:392)
       at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerHandlerImpl.setResult(TransformerHandlerImpl.java:137)
       at com.sun.xml.bind.v2.runtime.unmarshaller.DomLoader$State.<init>(DomLoader.java:74)
       at com.sun.xml.bind.v2.runtime.unmarshaller.DomLoader.startElement(DomLoader.java:113)
       at com.sun.xml.bind.v2.runtime.unmarshaller.XsiTypeLoader.startElement(XsiTypeLoader.java:73)
       at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:449)
       at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:427)
       at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:71)
       at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:275)
       at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:209)
       at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:358)
       at com.sun.xml.bind.v2.runtime.BridgeImpl.unmarshal(BridgeImpl.java:120)
       at com.sun.xml.bind.api.Bridge.unmarshal(Bridge.java:233)
       at com.sun.xml.ws.message.stream.StreamMessage.readPayloadAsJAXB(StreamMessage.java:229)

                                    

Comments
SUGGESTED FIX

Kohsuke had the following comments about the problem ->    

 public SAX2DOM() throws ParserConfigurationException {
    synchronized (SAX2DOM.class) {
        _document = _factory.newDocumentBuilder().newDocument();
    }
    _root = _document;
 }
  
 In JAXP RI, "newDocumentBuilder().newDocument()" is thread-safe, so synchronization can be removed.

 _factory should be also initialized with the "new XYZ" (where
  XYZ is the DocumentBuilderFactoryImpl in JAXP RI), instead of
  DocumentBuilderFactory.newInstance(), so that you know you are
  always using the JAXP RI for this.
                                     
2008-02-07
EVALUATION

Comments from Santiago:

 I think this may be possible, but it makes JAXP a bit less flexible. The SAX2DOM class is producing the output of a transformation (with DOMResult). The way it is implemented now, you can plug in whichever DOM implementation you like, and then downcast or do whatever you want with it. I'm not saying this is desirable, but it is possible.

 If we change this to use our internal DOM, then we should probably have to change this in many other places. In general, JAXP goes through the pluggability layer to allow people to use their SAX, DOM, etc. For the reason stated above, someone could argue this change is not backward compatible too.

 On the other hand, there are clear performance advantages in implementing the suggestion and in general avoiding the pluggability layer. It's a difficult one.

Comment from Norm:
we should use the plugability layer because that's what gives programmers the ability to plug in their own code.
                                     
2008-03-11
EVALUATION

I don't think having a property makes sense. In general, the right thing 
should just happen automatically, and in this case, it can.

I read Santiago's evaluation and he has a point that while SAX2DOM class 
itself is not user visible, the DOM created by it is indeed user visible.

So my next suggestion is, check if the _factory variable is a factory 
from the JAXP RI, and if so, create a new instance without a lock. 
Otherwise, do it with a lock. You can do this by checking a property, or 
the 'instanceof' operator.

The check can be done upfront only once to avoid per invocation 
overhead, if that's helpful.

A slightly better approach is for you to write a delegating 
DocumentBuilderFactory that calls another DocumentBuilderFactory and 
hides this detail there, but that's up to you.
                                     
2008-04-01
EVALUATION

The JavaDoc for DocumentBuilderFactory was not explicit wrt thread safety. However, that in the JAXP 1.4 RI/JDK6 internal implementation is. A patch has been provided to avoid the lock when the internal implementation is used. This patch is now available in JAXP 1.4 RI and will be requested to be considered for JDK6 integration.
                                     
2008-05-14
EVALUATION

An additional fix has been added based upon Jitu's suggestion. The fix is to futher improve performance for the default JDK implementation by caching the DocumentBuilder.
                                     
2008-09-02



Hardware and Software, Engineered to Work Together