6 Replies Latest reply on May 1, 2005 8:22 PM by jason.greene

    Problems with ThreadLocal Document use in SAAJ

    jason.greene

      I noticed a problem with document handling in our current SAAJ design. I had a need to locate the root element of the SAAJ tree via the DOM API. I started to implement getDocumentElement() on SOAPPartImpl, when I noticed that currently all nodes are allocated from a single threadlocal document (I assume this was done for performance reasons?). The problem with this is that I can't, of course, attach an element to the threadlocal document because there could be many active SOAPMessage objects within the same thread.

      If possible, I would like to change the design to a one-to-one relationship between a SOAPPart and a Document. This would allow the following operations to work correctly:

      part.getDocumentElement()


      and

      element.getOwnerDocument().getDocumentElement()


      Can anyone think of a problem with switching to this approach?

      -Jason

        • 1. Re: Problems with ThreadLocal Document use in SAAJ
          anil.saldhana

          If there are multiple SOAP messages possible in a single thread, the use of threadlocal to hold the root may not be suitable, because SAAJ is all about working on a SOAP message top to bottom. I will be interested to know Thomas's thoughts on this issue.

          I am thinking of scenarios where there can be multiple SOAP messages per thread at any instance of time. Jason, refresh me on this! On the client side, the client may create multiple SOAP messages in a single thread of execution. Then it will be difficult for the client to change the SOAP messages. Correct?

          • 2. Re: Problems with ThreadLocal Document use in SAAJ
            thomas.diesler

            The reason why there is a ThreadLocal association for the Document is that there are many many invocation points where it is necessary to create a DOM Element in order to add it to the current Document. As you know, you can't associate an Element with Document A that was created for Document B.

             org.jboss.ws.soap ( in D:\projects\jboss-head\webservice\src\main ) ( 11 occurrences in 4 files )
             SOAPElementImpl.java ( 3 occurrences )
             (48, 23) super(DOM2Utils.createElement(localPart));
             (55, 23) super(DOM2Utils.createElement(localPart, prefix, namespace));
             (62, 23) super(DOM2Utils.createElement(name));
             SOAPFactoryImpl.java ( 3 occurrences )
             (21, 23) public SOAPElement createElement(Name name) throws SOAPException
             (26, 23) public SOAPElement createElement(String localName) throws SOAPException
             (31, 23) public SOAPElement createElement(String localName, String prefix, String uri) throws SOAPException
             SOAPFaultImpl.java ( 3 occurrences )
             (49, 43) addChildElement(faultcode = factory.createElement("faultcode"));
             (50, 45) addChildElement(faultstring = factory.createElement("faultstring"));
             (118, 47) addChildElement(faultactor = factory.createElement("faultactor"));
             SOAPPartImpl.java ( 2 occurrences )
             (146, 19) public Element createElement(String tagName) throws DOMException
             (181, 19) public Element createElementNS(String namespaceURI, String qualifiedName) throws DOMException
            


            Currently the Thread is the owner of that Document because I could not identify another entity that is reachable from all createElement invocation points. The SOAPPart is not reachable from all these invocation points.

            You say


            The problem with this is that I can't, of course, attach an element to the threadlocal document because there could be many active SOAPMessage objects within the same thread.


            Why is that? Can you show me a valid use case where there are multiple SOAPMessages per Thread? The current WS4EE implemenation in Branch_4_0 works with the same ThreadLocal construct.

            • 3. Re: Problems with ThreadLocal Document use in SAAJ
              jason.greene

               



              The problem with this is that I can't, of course, attach an element to the threadlocal document because there could be many active SOAPMessage objects within the same thread.


              Why is that? Can you show me a valid use case where there are multiple SOAPMessages per Thread?


              Sure, what about an SAAJ client application that communicates with 2 webservices and then analyzes the results afterwords.

              The current WS4EE implemenation in Branch_4_0 works with the same ThreadLocal construct.


              Correct me if I am wrong, but it looks like the current implementation doesn't use a threadlocal implementation, but instead just spawns multiple document instances. It looks like the Axis implementation attempts to solve the problem I mentioned by maintaining a back reference to the SOAPPart. By glancing through the code it does look like 4.0 could suffer from the problem of assigning one document element to another document.

              The design method I mention could still work by importing nodes if they are from a different document (this is what the RI appears to do).

              -Jason



              • 4. Re: Problems with ThreadLocal Document use in SAAJ
                jason.greene

                 

                "jason.greene@jboss.com" wrote:

                -snip-
                Correct me if I am wrong, but it looks like the current implementation doesn't use a threadlocal implementation, but instead just spawns multiple document instances. It looks like the Axis implementation attempts to solve the problem I mentioned by maintaining a back reference to the SOAPPart. By glancing through the code it does look like 4.0 could suffer from the problem of assigning one document element to another document.

                The design method I mention could still work by importing nodes if they are from a different document (this is what the RI appears to do).


                Alternatively we could do the same the thing that the axis implementation does, and hold a reference to the SOAPPart in every Node, and then when getOwnerDocument is called we return the SOAPPart. The SOAPPart implementation would then always return the envelope as the owner. Then the fact that all nodes are allocated via a threadlocal document doesn't matter. It is probably better implemented this way anyways because returning the actual DOM document can be problematic since each the NodeImpl is not actually stored in the document (its aggregate org.w3c.Node) is, which could lead to confusion.

                What do you think?

                -Jason




                • 5. Re: Problems with ThreadLocal Document use in SAAJ
                  jason.greene

                  So, to summarize this approach more clearly:


                  • Continue using thread local document behind the scenes to ensure that all nodes are allocated from the same document instance.
                  • Make SOAPPartImpl.getDocumentElement() return its nested SOAPEvelopeImpl.
                  • Maintain a reference to the associated SOAPPartImpl in every child NodeImpl.
                  • Make NodeImpl.getOwnerDocument() return the SOAPPartImpl reference
                  • Create an implementation of org.w3c.Document with create methods that return SAAJ elements and nodes instead of DOM elements/nodes.
                  • Delegate to the above implementation from SOAPPartImpl.
                  • Change the ThreadLocal reference to reference this new Document implementation

                    This should allow for efficient DOM access (read and write) on the SAAJ tree.

                    -Jason


                  • 6. Re: Problems with ThreadLocal Document use in SAAJ
                    jason.greene

                    I just made these changes in head. There is still some more DOM compatibility work to be done. In particular attributes need to be revisited. Currently, if you call any of the getAttributeXXX methods, our Attribute implementation is returned. However they are not reachable via node traversal calls, since the current Node implementation effectively skips them since they are not added to its soapChildren list. Also the getAttributes() method returns a NamedNodeList which, of course, contains the xerces implementation.

                    -Jason