Wednesday, August 08, 2007

Ah yes, the perils of having co-authored a Java book and now working in a .NET shop :) Whenever a Java project arises, it comes my way. (Okay, I'm not REALLY complaining, but it's humorous to me) This project seemed easy enough: someone else wrote a web service in C#. I needed to write Java code to invoke the .NET web service and package it as a small SDK of sorts. So I hit the web service, pulled down the WSDL, ran it through Axis, and I got some code. However, I didn't want the additional dependency on Axis when delivering the Java code to our customer, so I tried using wsimport, a tool that comes with the JDK. Should work right away, right?

Sadly, no. I got an error about the s:schema being undefined, so I tried passing the address of XMLSchema.xsd from w3.org as a binding via the -b option.

Then I got a confusing error that left me scratching my head for longer than I care to admit. It is because of this error that I am going to the trouble of writing this post. I found exactly one hit on Google about this error and that search result simply had someone replying "I haven't seen this before....I think you solve it by....." which unfortunately was useless to me.

To cut to the point, the issue was one of the properties on the C# object is a DataSet and wsimport ain't very happy with DataSets since the types cannot be determined until runtime. The solution is straight forward: use a typed DataSet. There's a ton of documentation online describing how to create typed DataSets in Visual Studio. I couldn't find this information, though. Nobody linked the following error with DataSet interoperability issues, for whatever reason. It's likely that this is NOT the only case where wsimport will output the error message below. If this post doesn't help you and you're getting this error, check interoperability problems, check that the XMLSchema.xsd namespace/location is correct (specify -b if needed, perhaps), and if none of this helps - take a WSDL you know wsimport will work with, compare it to the WSDL that's failing, see where the differences are and start removing constructs that seem out of place. Once the problem WSDL works, look at the last construct you removed, then you'll have your problem narrowed down.

Here's the error I received from wsimport:

C:\javacode\ws>wsimport DotNetWebService.wsdl -b http://www.w3.org/2001/XMLSchema.xsd

XML reader error: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[112,36]
Message: A '(' character or an element type is required in the declaration of element type "xs:schema".
XML reader error: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[112,36]
Message: A '(' character or an element type is required in the declaration of element type "xs:schema".
at com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil.wrapException(XMLStreamReaderUtil.java:249)

Once the DataSet was changed to a strongly typed DataSet, the additional binding option wasn't needed. You can execute wsimport DotNetWebService.wsdl and end up with your code.

I hope this helps someone out there

Wednesday, August 08, 2007 10:47:26 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  |  Trackback
Comments are closed.