Wednesday, 30 June 2010

JDOM & XPath Contexts

Second post today - its been a week of minor but frustrating issues so far and I want to publish as many solutions as I can find time for.

This issue had me scratching my head for a good few hours, and there didn't seem to be much solid documentation online to help out. I was using a combination of JDOM 1.0 and XPath to manipulate a short XML document (arriving via a SOAP interface). Here's the basic document structure that was the subject (Names have been changed to protect the innocent):

<srv:Root>
<srv:Name>Overall Name</srv:Name>
<srv:Items>
<srv:Item>
<srv:ItemName>Name 1</srv:ItemName>
<srv:ItemPrice>20</srv:ItemPrice>
</srv:Item>
<srv:Item>
<srv:ItemName>Name 2</srv:ItemName>
<srv:ItemPrice>30</srv:ItemPrice>
</srv:Item>
</srv:Items>
</srv:Root>

The above conforms to the schema set out for the message, everything validates fine. I was using the following to extract the Items, then iterate through each Item and print out the ItemName and the ItemPrice:


XPath itemXpression = XPath.newInstance("//srv:Item");
itemXpression.addNamespace(ns);
XPath itemXpression = XPath.newInstance("//srv:ItemName");
itemnameXpression.addNamespace(ns);
XPath itemXpression = XPath.newInstance("//srv:ItemPrice");
itempriceXpression.addNamespace(ns);

List nodes = itemXpression.selectNodes(document);

// Ensure we have some items to iterate through
if(!nodes.isEmpty()) {

Iterator it = nodes.iterator();

//Init list of Item
List items = new ArrayList();

//Iterate through all items
while(it.hasNext()) {

Element item = (Element)it.next();

Item i = new Item();

// Evaluate XPath expressions for values
String itemname = itemnameXpression.valueOf(item);
String itemprice = itempriceXpression.valueOf(item);

System.out.println(itemname);
System.out.println(itemprice);

}
}
}


However, the code always prints out the Name and Price of the first item twice, rather than the details of the first and then the details of the second.
I tried mixing it up with using pure JDOM to no avail, tried numerous different approaches, and ether got NPEs or that first item repeated twice. In the end, the solution was simply to adjust the XPath search expression from "//srv:Item..." to "/srv:Item...". It seems that despite the fact I'm explicitly passing in an Element containing only one Item (and using an XMLOutputter verifies this), preceeding the expression with // resets the search context to the overall document root. Strange behaviour, but there you go.

Useless Eclipse Error Messages

I had an absolute nightmare the other day with a web services project I was working on in Eclipse (actually Spring STS). I had written a WSDL file and accompanying Schema, and Eclipse was giving me a warning triangle at the very top of the document with the following useless error message:

WS-I: A problem occured while running the WS-I WSDL conformance check:
org.eclipse.wst.wsi.internal.analyzer.WSIAnalyzerException:
The conformance validation process failed.

The only further detail available is:

Nested exception is:
java.lang.NullPointerException The WSDLAnalyzer was unable to
validate the given WSDL File.

No indication of where there might be an error, or what might be causing the problem. After much removing and replacing of segments of the file, and external validation of the Schema document, my advice to anyone else facing this error is to double, triple and quadruple check the spelling and capitalisation of the name fields in the operations within the definition. Changing a few 'c's to 'C's sorted the issue out for me, but methinks its time for some more informative error messages Eclipse Team!

Tuesday, 8 June 2010

What's the time?

I've been having issues with a number of CentOS hosts not holding the correct time - they seem to be drifting incessantly, despite the fact that they should be syncing to a number of NTP servers. Looking at the output of an ntpdate, I get the following error:

[root@nx-01 ~]# ntpdate
8 Jun 09:29:09 ntpdate[4267]: no servers can be used, exiting

Although the log messages are showing that the server is quite happily synchronised to its NTP peers:

Jun 8 09:08:20 nx-01 ntpd[1698]: synchronized to LOCAL(0), stratum 10
Jun 8 09:09:25 nx-01 ntpd[1698]: synchronized to 77.75.105.150, stratum 2
Jun 8 09:13:41 nx-01 ntpd[1698]: synchronized to 62.84.188.34, stratum 2

Forcing ntp to update by shutting down the daemon and passing a server as an argument to ntpdate also has no effect - the drift remains.

After some head scratching, I've come across the root cause of this issue. The servers in question are actually DomU instances on a Xen host, and by default they attempt to synchronize their clocks with the Dom0. I've since updated my Dom0's to use correct NTP settings, but for reference if you need to break this dependency you can do it with the following command:

echo 1 > /proc/sys/xen/independent_wallclock

To make it permanent you can append that line to the bottom of /etc/rc.d/rc.local.