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

Re: Fwd: [xmlblaster] server side exception: Can't process XPath expression



Am 26.08.2012 05:51, schrieb Andrew Yinger:
marcel: here is some more information.
The server has a
  e.printStackTrace();
in XmlNotPortable.java
can you provide that output please as well?

To simplify I have removed the reflection code in XmlNotPortable.java and have added a logging output.
Can you please do a svn update and try your testing with this and provide me the result?

Thank you
Marcel

here is the stack trace i'm seeing that says it's a server-side error (note the "location=[XmlNotPortable]"):

     [junit] Caused by: errorCode=user.query.invalid message=#exported
Sorry, can't access, query syntax of
'/xmlBlaster/key[messageType='MSG_TYPE']' is wrong :
XmlBlasterException errorCode=[resource.configuration]
serverSideException=true location=[XmlNotPortable] message=[#exported
Can't process XPath expression
'/xmlBlaster/key[messageType='MSG_TYPE']' :
java.lang.reflect.InvocationTargetException] [See URL
http://www.xmlblaster.org/xmlBlaster/doc/requirements/admin.errorcodes.listing.html#resource.configuration]
     [junit] 	at
org.xmlBlaster.util.XmlBlasterException.parseByteArr(XmlBlasterException.java:677)
     [junit] 	at
org.xmlBlaster.util.xbformat.MsgInfo.getException(MsgInfo.java:589)
     [junit] 	at
org.xmlBlaster.util.protocol.RequestReplyExecutor.receiveReply(RequestReplyExecutor.java:538)
     [junit] 	at
org.xmlBlaster.client.protocol.socket.SocketCallbackImpl.run(SocketCallbackImpl.java:225)
     [junit] 	at java.lang.Thread.run(Thread.java:662)



(i know that xpath syntax is correct, and it only happens when a lot
messages subscriptions are processed on the server)

on the client, i am testing subscription (using xpath) by doing
something like this in a unit test:

		int quantity = 90;
		final List<MessageContainer<String>> msgs = new
ArrayList<MessageContainer<String>>(quantity);
		// here, we use custom client code to subscripe using XPATH
expression: "/xmlBlaster/key[messageType='MSG_TYPE']"
		String subId = newVectorsClient.subscribeToMessageType("MSG_TYPE",
new MessagingClientCallback<String>()
				{
					public void processSubscribedMessage(MessageContainer<String>
msg) throws IOException
					  {
						// producer
						synchronized (this)
						{
							msgs.add(msg);
							notify();
						}
					  }
				});
		Thread.sleep(200);
		for (int i=0; i < quantity; i++)
			setClient.publishMessageType("MSG_TYPE", "["+i+"]" + MSG_CONTENT);

		// consumer (here we wait to make sure we received all 90 msgs)
		synchronized (this)
		{
			while (msgs.size() != quantity)
				wait(10); // wait until async. producer finished...
		}
		// check it out
		assertTrue("msgs size should have been " + quantity, msgs.size() == quantity);
		newVectorsClient.unsubscribe(subId);


the problem occurs less frequently with version 2.1.0, but i can still get it to occur by publishing a flood (90) of messages.

i think that maybe the synchronization should be even more
conservative in XmlNotPortable.getNodeSetFromXPath.  starting around
line 111, maybe something like:

             synchronized(XmlNotPortable.class) {
                Object myxpath = null;
                if (method_newXPath == null) {
                   clazz_XPathFactory =
java.lang.Class.forName("javax.xml.xpath.XPathFactory");
                   Class[] paramCls = new Class[0];
                   Object[] params = new Object[0];
                   java.lang.reflect.Method method =
clazz_XPathFactory.getMethod("newInstance", paramCls);
                   instance_XPathFactory =
method.invoke(clazz_XPathFactory, params);
                   method_newXPath =
clazz_XPathFactory.getMethod("newXPath", paramCls);

                   clazz_XPath =
java.lang.Class.forName("javax.xml.xpath.XPath");

                   Class clazz_XPathConstants =
java.lang.Class.forName("javax.xml.xpath.XPathConstants");
                   clazz_QName =
java.lang.Class.forName("javax.xml.namespace.QName");
                   java.lang.reflect.Field field =
clazz_XPathConstants.getDeclaredField("NODESET");
                   field_NODESET = field.get(null);
                   paramCls_StringDocument = new Class[] {
                                    java.lang.String.class,
                                    java.lang.Object.class, //
org.w3c.dom.Document.class,
                                    clazz_QName };
                }
                myxpath = 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(myxpath, params);

                final int length = nodes.getLength();
                return new java.util.Enumeration() {
                   int i=0;
                   public boolean hasMoreElements() {
                      return i<length;
                   }
                   public Object nextElement() {
                      i++;
                      return nodes.item(i-1);
                   }
                };
             }



thanks for looking into this,
andrew




---------- Forwarded message ---------- From: Andrew Yinger <andrew.yinger at gmail.com> Date: Sat, Aug 25, 2012 at 10:07 PM Subject: Re: [xmlblaster] server side exception: Can't process XPath expression To: Marcel Ruff <mr at marcelruff.info> Cc: xmlblaster <xmlblaster at server.xmlblaster.org>


with version 2.1.0 of the server, i still (although rarely) see the server-side error. it seems to be encountered only during unit testing, when many simultaneous publish/subscribe events are triggered. is it possible that there is an XPathFactory instance somewhere else that is not properly synchronized? (i am not positive that the error is caused by an XPathFactory synchronization issue -- i'm just basing that diagnosis on earlier post regarding sporadic, invalid, server-side xpath expression errors).

regards,
andrew


On Sat, Aug 25, 2012 at 2:07 AM, Marcel Ruff <mr at marcelruff.info> wrote:
Am 24.08.2012 05:01, schrieb Andrew Yinger:

i believe this issue was identified before, but i occasionally see a
server-side exception that starts off like:

     errorCode=user.query.invalid message=#exported Sorry, can't access,
query syntax of
     ....
     XmlBlasterException errorCode=[resource.configuration]
serverSideException=true location=[XmlNotPortable]
      message=[#exported Can't process XPath expression .....


it was first suggested that this was a parsing issue -- a possible xml parser library conflict. (i have verified that i do *not* have any extraneous xml parsing libs in my 'java\lib\endorsed' directory.)

later, a user noticed that a similar error was happening during unit
testing, and that it was a bug on the server:

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.
In the current code it looks like this:

             Object xpath = null;
             synchronized(XmlNotPortable.class) {
                if (method_newXPath == null) {
                   clazz_XPathFactory =
java.lang.Class.forName("javax.xml.xpath.XPathFactory");
                   Class[] paramCls = new Class[0];
                   Object[] params = new Object[0];
                   java.lang.reflect.Method method =
clazz_XPathFactory.getMethod("newInstance", paramCls);
                   instance_XPathFactory = method.invoke(clazz_XPathFactory,
params);
                   method_newXPath = clazz_XPathFactory.getMethod("newXPath",
paramCls);

                   clazz_XPath =
java.lang.Class.forName("javax.xml.xpath.XPath");

                   Class clazz_XPathConstants =
java.lang.Class.forName("javax.xml.xpath.XPathConstants");
                   clazz_QName =
java.lang.Class.forName("javax.xml.namespace.QName");
                   java.lang.reflect.Field field =
clazz_XPathConstants.getDeclaredField("NODESET");
                   field_NODESET = field.get(null);
                   paramCls_StringDocument = new Class[] {
                                    java.lang.String.class,
                                    java.lang.Object.class, //
org.w3c.dom.Document.class,
                                    clazz_QName };
                }
                xpath = method_newXPath.invoke(instance_XPathFactory, new
Object[0]);
             }

so it seems to be correctly synchronized, or do I overlook your issue?

Thank you
Marcel

has this bug been fixed?  if so, what version should i be using now?
(i am currently using xmlBlaster version 1.6.2 2007-12-03
'Openroads'.)

a response to this ongoing issue would be greatly appreciated, as it
is impacting our automated unit tests.


thanks, andrew yinger




--
Marcel Ruff
http://www.xmlBlaster.org
http://watchee.net
Phone: +49 7551 309371