Hi all,
I did some additional testing related to the EMPTY_DOC problem. Therefore I set
up a test where multiple threads created new EPRs based on a set of existing
(shared) EPRs. Such shared EPRs are resource EPRs (e.g. notification producer
EPR). In this test two different kinds of exceptions are thrown:
1.)
java.lang.NullPointerException
at org.apache.xerces.dom.ParentNode.nodeListItem(Unknown Source)
at org.apache.xerces.dom.ParentNode.item(Unknown Source)
at org.apache.muse.util.xml.XmlUtils.getAllElements(XmlUtils.java:932)
at org.apache.muse.util.xml.XmlUtils.getElement(XmlUtils.java:1144)
at org.apache.muse.util.xml.XmlUtils.getElement(XmlUtils.java:1119)
at
org.apache.muse.test.case1.TestEndpointReference.initializeFromXML(TestEndpointReference.java:560)
at
org.apache.muse.test.case1.TestEndpointReference.<init>(TestEndpointReference.java:193)
at org.apache.muse.test.case1.TestThread.run(TestThread.java:60)
This exception relates to the following code parts in the EPR implementation:
...
Document doc = XmlUtils.EMPTY_DOC;
_xml = XmlUtils.createElement(doc, typeName);
NodeList children = copy.toXML().getChildNodes();
int length = children.getLength();
for (int n = 0; n < length; ++n)
{
Node next = doc.importNode(children.item(n), true);
_xml.appendChild(next);
}
try
{
initializeFromXML();
}
...
The reason for the exception is that multiple threads import
nodes into the SHARED document. Later on in initializeFromXML()
the different element nodes within the SHARED document are traversed
simulations, which leads to the threading issue. The usage of
ThreadLocal WILL eliminate such errors, since no SHARED document is
used between the different threads to create XML elements. In fact
each thread has its own document that is used for this. This is shown
in the sample thread local.
2.)
java.lang.NullPointerException
at org.apache.xerces.dom.ParentNode.nodeListItem(Unknown Source)
at org.apache.xerces.dom.ParentNode.item(Unknown Source)
at
org.apache.muse.test.case1.TestEndpointReference.<init>(TestEndpointReference.java:187)
at org.apache.muse.test.case1.TestThread.run(TestThread.java:60)
The second exception has a similar background. In the test case
the initial EPRs are created in the class Test via the
TestEndpointReference(URI address, QName typeName)
constructor. This constructor creates the internal XML representation
by using EMPTY_DOC. The original EPR is copied by the following code:
NodeList children = copy.toXML().getChildNodes();
int length = children.getLength();
for (int n = 0; n < length; ++n)
{
Node next = doc.importNode(children.item(n), true);
_xml.appendChild(next);
}
The copy.toXML() method simply returns the XML element created with
EMPTY_DOC. Here again multiple thread try to traverse the same node
concurrently which leads to the exception.
Therefore, in my point of view we have two different problems:
1.) Multiple threads must not use the same target document to import nodes.
This means XML elements, that are only used within a request/response
cycle (e.g. for de-/serialization) can use ThreadLocal mechnisms.
It is not necessary to create new documents all the way for this purpose.
2.) XML elements, that have a lifetime longer than a request/response
cycle, must be created by using new (not shared) documents. This I already
pointed out in my first mail. This is especially true for EPRs, that are
I attached a number of test cases that illustrate my point.
To Rich:
>>The default implementation creates a thread for processing the
>>notify request, and then immediately releases the thread that called it.
You are right: in this special case the objects need to be copied
by using a separate document, since here the message objects leave the
request/response cycle. This has to be taken into account.
Finally, the usage of createDocument() compared to the solution I presented
adds a performance overhead of more than 50%. This can simply be verified
with the tests I attached. However, I admit that my solution requires more
attention by the programmers than simply replacing EMPTY_DOC, but I think
it is worth.
Interestingly, I still found that sometimes exceptions will occur, even when
using new documents for every XML operation. This is really rare, but in my
opinion this results from the âstillâ shared usage of DOM objects within
the EPR (the _xml element). Therefore, concurrent read access to this instance
variable can still occour. To solve the problem with the EPR completely, this
instance variable should perhaps be removed from the EPR implementation.
Regards,
Oliver
p.s. unfortunatelly I could not attach the test files, since this is rejected
by the mailer deamon. However, I could provide the test in the JIRA.
--
Psssst! Schon vom neuen GMX MultiMessenger gehört?
Der kanns mit allen: http://www.gmx.net/de/go/multimessenger
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]