[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xmlblaster] More parsing issues



This message is (roughly speaking) a follow up to the previous message entitled "Subscription Invocation Exception".

In addition to the problem described in that message I have also seen another (possibly) similar problem.  I have a unit test which creates 100 threads which all try to make a subscription using the same xpath.  In some cases (but not always) one or more of the subscriptions fails with the following error:

java.lang.NoSuchMethodException: javax.xml.xpath.XPath.evaluate()
    at java.lang.Class.getMethod(Class.java:1581)
    at org.xmlBlaster.util.XmlNotPortable.getNodeSetFromXPath(XmlNotPortable
.java:137)
    at org.xmlBlaster.engine.xml2java.XmlKeyDom.parseKeyOid(XmlKeyDom.java:1
25)
    at org.xmlBlaster.engine.RequestBroker.queryMatchingKeys(RequestBroker.j

The intermittent nature of this problem (as well as the previously described one) suggests to me that we are looking at a synchronization issue.

I have two synchronization concerns when looking at the code.  The following snip is from org.xmlBlaster.util.XmlNotPortable

public static Enumeration getNodeSetFromXPath(String expression,                                                                       org.w3c.dom.Document document) throws XmlBlasterException {
   try {
      if (getJvmXmlVersionToUse() >= 15) {
            if (method_newXPath == null) {
               synchronized(XmlNotPortable.class) {
                  if (method_newXPath == null) {

                      ... create xpath factory and objects ...

                  }
               }
            }

            Object xpath =
               method_newXPath.invoke(instance_XPathFactory, new Object[0]);
            Object[] params =
               new Object[] { expression, document, field_NODESET };
            java.lang.reflect.Method method_evaluate =
               clazz_XPath.getMethod("evaluate", paramCls_StringDocument);
            final org.w3c.dom.NodeList nodes = (org.w3c.dom.NodeList)
               method_evaluate.invoke(xpath, params);

The issues are:
1. The null check (method_newXPath == null) is outside the synchronization block.  Thread A and thread B could both pass through the null check at the same time.  Thread A will create the xpath objects while B waits.  Then thread B will go through and recreate xpath objects while A is using them.
2. XPathFactory is, in general, not thread-safe (see http://java.sun.com/javase/6/docs/api/javax/xml/xpath/XPathFactory.html), and a method on that object is invoked outside the synchro block.

I made a local change to wrap the synchro block around the null check and the invocations following the original synchro.  Once I did that I was unable to reproduce the problem I described above.

I'd appreciate it if the xmlBlaster gurus could comment on the proposed change.  I'm happy to push the change up, but I'd like to get a little feedback first if I can.

Thanks,
John Horner

Open Roads Consulting
(757) 546-3401
www.openroadsconsulting.com