We started a new project this week at my day job, where we are creating a common set of services using WCF in .NET 3.5 SP1, and in addition to the .NET applications making use of them, we wanted some Java systems to communicate with them. The Java systems are an ESB running in Apache ServiceMix, and some other as yet undefined Java systems running on Solaris boxes.
We chose WCF for the ease of creating new web services, where it does all the heavy lifting for you and allows you to swap protocols and addresses transparently. We chose .NET 3.5 SP1 both because it is new and shiny, and because it offers the entity framework, and we like the entity framework.
But now we were faced with the question: How do we make the java code call the services? And indeed, since we are a bunch of java noobs, how do you call web services in java? We called on the great google, and it showed that apache axis seemed to be a popular tool to both publish and call web services with. So, deciding that who were we to argue,axis it was.
I created a default web service, ran it from the IDE, and pointed Axis at it to generate a stub from the WSDL with the WSDL2Java program included in the Axis distribution. The location of the WSDL is available from the test page that Visual Studio brings up when you run your service.
Oh-oh, no luck. The axis client complained of a problem with its understanding. I’ll reproduce it and post the exact error message here. When I googled that error message, I found a whole bunch of interesting pages, but nothing that helped me understand what the problem was.
Then I thought about it for a while and remembered that the WCF web services were supposed to ship with all the WS standards enabled, and reasoned that maybe Axis did not like these newfangled things, and wanted a simpler SOAP interface.
After a dead end or two, I realised that you can change the port mapping in the WCF config file to use a basicHTTPMapping, and that this then publishes the web service as an old style SOAP service, which Axis was happy to generate clients for.
I tested the clients, and hey presto! We could invoke the WCF web services from the Java code.
But, never being content to leave well enough alone, I decided that I wanted to remove the WCF webservices from the tempuri.org namespace, and put them in a more appropriate one. I added namespace information to the service by modifying the service interface, the service implementation and the binding namespace in the web.config file.
These are the things I changed:
Then I attempted to regenerate the clients with the axis tool, and it complained. The error message was about invalid WSDL structure. After thinking on this for a bit, and comparing the original tempuri.org namespaces in the WSDL to my new ones, I realised that axis was expecting certain relationships between the namespaces on the three attributes, and then I realised that the namespace in each of the three places mentioned above must be EXACTLY the same.
I changed them all to be identical, and there it was. The client stubs generated correctly, and they were able to successfully invoke the services.
As our good friend Borat says so wonderfully “great success!”