Well I had a 9 hour flight today so I thought I'd try and get AXIS2 working... it must be something I've done... right?
I'm using a simple WSDL file with 3 methods, used the WSDL2Java to generate the stub and the skeleton and the test code. This didn't work, however thank god for open source as this meant I could trudge through the code to understand why on earth things didn't work properly. So the service was basically
interface GeoLocation{
GeoLocation findByIATA(iata String);
GeoLocation findByICAO(icao String);
GeoLocation[] findByName(geoName String);
}
And no matter which method I called it ALWAYS saw it as findByIATA on the server, a bit of a challenge as the SOAP message and responses are typed to the specific request, so SOAPFaults abounded as it complained I was passing the wrong information to the method, in fact I was getting the wrong method for the request!
First top tip is that Axis2 doesn't have hot deploy, if you upload the same WebService archive this doesn't take effect until you restart tomcat, which is a bit naff.
Second top tip is download the Java VM documentation, being at 35,000 feet over Iran isn't the best point to forget the arcane syntax for starting tomcat remotely in debug mode.
Third tip is that when Tomcat says "Failed to shutdown" its lying, its shutdown, dead gone, buried and out of there.
These two combined led to a very painful cycle of adding logging messages through the code in a great bug hunt. First off I thought it was a client side problem, this was denied by the client by the cunning rouse of actually having the right SOAP envelope. So this meant that the fault was on the more painful to debug element, the server. A quick cointreau to stiffen my resolve and it was confirmed that all of the right information was passing across the wire.
Next up the great issue of the Axis 2 src build not actually producing something that runs. So its the world's nastiest development approach, taking a working jar file, exploding it and inserting a new .class file... nice. This narrowed it down further to say that the loading of the different end-points was being done correctly but it was the mapping of the request on to the end-point that was going horribly wrong
Landing in Mumbai brought up the solution for the debugger, setting JAVA_OPTS in Tomcat to be -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n, the problem I'd had on the flight was that I'd put the address in as localhost:8000 and it didn't work.
So surely now moving down the home straight for debugging, a simple watch expression helped to determine when the AxisOperation was set to the wrong thing... oh wait it wasn't 100% simple because the naming conventions are all over the place, msgContext, msgctx, messageContext... this is why naming conventions do actually matter. The target then was identified as the SOAPActionBasedDispatcher from axis2.
Then we find it after a couple of step intos, surely this must be the answer "findOperation"... ummm but SOAPAction is a blank string. I hate it when the problem is actually right at the start but you find it at the point where the variable is finally processed. The reason its finding SOMETHING to call is that the mapping table in AXIS2 has a bunch of options including "" which is assigned to (I assume and now I've got to find out) the first operation it gets.
So now its about debugging right from the start again and finding out why that SOAPAction isn't being set correctly.... oh great we are into the servlet API now, but its now looking like I'm back to square 1 and it might actually be an issue on the client side after all (the HTTPHeader doesn't appear to have the SOAPAction set it in to anything). Then its down to MessageContext, oh yes, here we have a cracker.
MessageContext.getSoapAction() returns options.getAction(), this is null. However msgContext.getAxisOperation().getSoapAction() returns the right value. Another cracking example of how not to code, having two different variables with the same name that aren't actually the same variable isn't a bright idea.
Now we move onto another patch on Axis2, and I run into another annoyance, the maven build is now farting over some test element it can't do, something to do with jibx... errr I don't care if jibx tests fail, I want my sodding jar file, so its explode and combine time again....
And then it all works fine. So to the chaps at Axis, the fix is to modify MessageContext.getSoapAction() to just reference the SoapAction of the AxisOperation. Bug raised and reference here, but it really was a bit worrying to see some basic development practice errors, particularly the thing that the bug turned out to be, duplicate places where information could be stored.
The worst bit about this is that I've just wasted 4 hours that I should have been asleep because I just couldn't let it lie.
Technorati Tags: AXIS2, Java, Web Service