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 <[email protected]> Date: Sat, Aug 25, 2012 at 10:07 PM Subject: Re: [xmlblaster] server side exception: Can't process XPath expression To: Marcel Ruff <[email protected]> Cc: xmlblaster <[email protected]> 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 <[email protected]> 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 Marcelhas 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
