Monday December 05, 2005
Soap Must Understand?! Aaaaaargh!
While rewriting a Sun Education course ("DWS-4487: Developing Secure Java Web Services") to use NetBeans IDE, I must've come across every single unparseably bizarre error that the tiny warped minds of developers have conceived of. The one that takes the cake, as far as I'm concerned, is this one:
Exception in thread "main" javax.xml.rpc.soap.SOAPFaultException: SOAP must understand error
at com.sun.xml.rpc.client.StreamingSender._raiseFault(StreamingSender.java:528)
at com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:307)
at auctionsystem.client.AddAuctionUserServiceSEI_Stub.addUser(AddAuctionUserServiceSEI_Stub.java:79)
at auctionsystem.client.AddAuctionUserClient.main(Unknown Source)
Java Result: 1
BUILD SUCCESSFUL (total time: 4 seconds)
You see what it says?! "SOAP must understand error". How on earth is one to know what that means? The answer is simple and immediate—Google. That's where I spent many many hours, until I came across this response, by my web service colleague Rico Cruz (who, with his colleague Peter Williams, helped out the NetBeans J2EE team a lot in the 4.1 release, by providing web service functionality, in co-operation with other developers here in Prague). The thing with Google is that you can really be led up the garden path (and never find your way back), which is what I did a couple of times, but this is Rico's advice:
The SOAP "must understand" error may be indicative of an unhandled SOAP security header at the receiving end (i.e. the web service). Make sure that you have configured the SOAP message handlers at web service end correctly.
I confess that I spent a while avoiding this solution. ("Configure a SOAP message handler? Really? Sounds tough." I thought.) But then I got stuck in and remembered my earlier praise song to message handlers (here). Using the New Message Handler wizard, I generated the template code, and then added this little snippet (googled from elsewhere):
if(shd != null){
Iterator iter = shd.extractAllHeaderElements();
while(iter.hasNext()){
SOAPHeaderElement el = (SOAPHeaderElement)iter.next();
System.out.println("Extracted header: " + el.getElementName().getQualifiedName());
}
}
What's important is the "extractAllHeaderElements()" method. This detaches the element objects from the SOAP header which, apparently, is exactly what is needed when you're using web service security mechanisms such as those provided by <xwss:Sign> elements and <xwss:Encrypt> elements. Once I'd added the snippet above to the generated message handler, and configured it to insert it in all the web services involved in the security framework, the "SOAP must understand" error disappeared.
Dec 05 2005, 04:47:54 AM PST Permalink


