Monday, 28 May 2007

Encoding style 'http://schemas.xmlsoap.org/soap/encoding/' not supported


This is one that gave me grief today. The above is not the full error message, but it should give you an idea of where to start.

The scenario is as follows:

I have a trivial RPC based web service intended to run locally with no WSSE enhancements or any such add-ons. Stub and Skeleton files are generated via the Wscompile tool, using JAX-RPC (version unknown, supplied with (I think) JBoss 3.2.6). Stubs and skeletons deploy correctly, but JBoss logs the following warnings:

2007-05-28 16:14:56,060 WARN [org.jboss.ws.metadata.wsdl.WSDL11Reader] Encoding style 'http://schemas.xmlsoap.org/soap/encoding/' not supported for: {urn:}methodName


Then, when one tries to execute a client call to the above webservice, one gets the following exception:

java.rmi.RemoteException: Runtime exception; nested exception is:
unexpected encoding style: expected=http://schemas.xmlsoap.org/soap/encoding/, actual=
at com.sun.xml.rpc.client.StreamingSender._handleRuntimeExceptionInSend(StreamingSender.java:331)
at com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:313)
at ws.client.RPCBillingInterface_Stub.isCompleted(RPCInterface_Stub.java:176)
at ws.client.RPCmain(RPCBiller.java:14)


Suffice to say, there's not a lot of help from Google. However, I remember finding a page somewhere, possibly on the Sun Java forums, which dealt with this issue. My searches this time didn't find it, but luckilly I had another Web Service which used the same methodology above and worked. eventually I tracked it down.

Basically, from what I can tell, there's some mismatch in the XML encoding provided by the SOAP messages between what the local client expects from JAX-RPC, SAAJ and whatever else is used, and what JBoss sends out from SOAP / RPC enabled webservices. The way to circumvent it is as follows.

1) Locate the _Stub classes for your webservice.
2) Locate the _deserialize_* methods in each _Stub class. These will correspond to the methods declared in your Webservice implementation classes; for example if your Webservice exposes a method called void foo(int bar), you should find a method named _deserialize_foo(...).
3) add the following line to the method, as the first method call within the method:

deserializationContext.pushEncodingStyle(SOAPConstants.NS_SOAP_ENCODING);


This, as far as I can tell, forces the expected soap encoding, namely http://schemas.xmlsoap.org/soap/encoding/, onto the deserialization stack and neatly sidesteps the above 'feature'.

I hope this saves whoever finds it some time and sanity.

An explanation of what this blog is

Throughout my time as a developer I've relied heavilly on Google when it comes to forensic development - that is, development where one is trying to decode arcane, non-obvious and hair-tearingly frustrating errors in third party APIs.

Frequently, however, Google points to mailing list archives which are not sorted by thread; making them frustrating to use. Also, depending on the newness of the API, Google sometimes provides no responses whatsoever.

So, in the hopes that future googlers may find something of interest here, I present bugs that I find during my development travails. I'm an SCJD, but am by no means a brilliantly competent programmer. I present all of these bugs and (potential) workarounds in the hope they'll be useful rather than out of any belief that they are the correct way to go about things.