When I started this project, I had hoped to look through a whole range of tools and then compare and contrast them. I figured that with the immense amount of work that has been poured into standardizing the entire Web services industry, from SOAP to UDDI, it would be child's play to pick a few components off the shelf, slap them together, and have a working application. This is, after all, the vision of the future that has been hawked for at least five years now. All programming will be plug-and-play: End users will select from a huge variety of programming components available for lease on the Internet and, with a simple graphical tool, connect these components together into working, productive applications. By standardizing the communications between these components, custom programming would be a thing of the past, as would the jobs of most of us old dinosaur programmers.
However, something funny happened on the way to the unemployment office. It turns out that programming may indeed be a bit more complex than was first thought. It's sometimes difficult to get two companies to agree on how to format the date, much less how to represent items and customers. Not only that, but there are issues surrounding "touchpoints," which are spots along the business process flow where human interaction is needed and which often don't lend themselves to automation.
That doesn't mean that Web services aren't still a powerful technology. Even with all its warts, Web services allow an application on one computer to communicate with an application on another computer, distributing both the programming and the CPU cycle workloads. In this article, I'll introduce the consumer side of the equation: writing applications that consume existing Web services (creating your own Web services to be consumed by others is another topic for another day). I'll tell you my experiences with using two of the most popular tools, Microsoft Visual Studio .NET (VS.NET) and WebSphere Development Studio Client for iSeries (WDSC) to consume one of the most universal Web Services available: the Google search Web service.
Standard, Standard, Who's Got the Standard?
Standards are perhaps my biggest problem with the whole Web services concept and, in a broader sense, my problem with the whole direction of the industry. In a drive to remove the programmer from the mix, organizations continue to create standards that can then be used by code-generation tools. The thought process is understandable: The users know what's necessary, so why should they need a programmer to translate those requirements to the computer? It would be better to write a really intelligent computer program that could itself translate the user requirements to the computer, which would then call other computers as necessary to get the work done.
The problem with that particular statement is that, no matter what, if you want two computers to talk to one another, they have to agree on a protocol. That's enough for two companies to work with one another, and in fact many companies do just that with simple protocols like XML-RPC or even good old flat files and FTP. But this article is about tools, and in order for a tool to be profitable, everybody has to agree on the protocol. To a large part, much of this has happened through organizations such as the World Wide Web Consortium (W3C) and the Organization for the Advancement of Structured Information Standards (OASIS), which is why there are tools on the market and why this article is even being written. I may not like some of the standards, but the fact that they exist allows tooling to be created.
However, there's one little detail that's still causing grief: Unless you have some really intelligent programming, the protocol has to stay very stable, and that's where a lot of this falls down. Unfortunately, the standards aren't cast in stone; in fact, they're about as solid as Jell-o. This is where programmers and tools just don't compare. It's fairly easy for a programmer (especially a good programmer!) to write code that can be tweaked whenever standards change. But a tool (especially a code generator) is basically locked into the standard that was current at the time it was written. It's hard enough to get a code generator to generate working code under varying circumstances; it's much harder to make the generator flexible enough to change with the standards. It can be done, but not without a lot of work. Typically, a code generator will work with one set of standards, and when those standards change, the tool must be patched.
The UDDI Standard
The Universal Description, Discovery, and Integration (UDDI) standard was a doomed concept from the beginning. The idea that corporations would publish their Web services in a single repository run by IBM, Microsoft, and SAP is pretty silly in hindsight. The fact that all the public UDDIs were run by this group (with the exception of one in Japan and something called XMethods) ensured that the whole infrastructure would crumble at the first sign of friction, and it did. However, I have to give the folks behind it some kudos; the free public registries run by those partners stayed on the air for a good five years. But as I was to find out to my chagrin, as of January 2006, the public UDDI registries of IBM, Microsoft, and SAP were no more. So, when I tried to use the UDDI browsing capability of WDSC (the Web Services Explorer), I met with almost immediate failure, since six of the eight UDDI registries were no longer in service.
The loss of the UDDI as Yellow Pages is not a disaster. More troubling is the fact that the UDDI registries that IBM (and Microsoft and SAP) hosted are now discontinued and no longer available for testing—even though they 're still included in the Web services portion of the tool. I suppose they have to be included, because if they weren't, the list would have no registries, other than one that's clearly non-commercial and one in Japanese. I guess nobody likes to strip out a working feature like the Web Services Explorer, even if it's obsolete.
Even if I had been able to use the Web Services Explorer, that wouldn't have helped me in .NET, since Visual Studio has no comparable tool. (I find it interesting that IBM's IDE has this great UDDI tool, while Microsoft's does not, even though they were both part of the UDDI consortium. Did Microsoft read the writing on the wall?)
It became clear that the only way I was going to get this done was by directly accessing Web Services Description Language (WSDL) files. I would have to go out and find the appropriate WSDL by manually searching the Internet, which today is pretty much the way people do things. You find a company that you want to do business with and you see if it has a Web service for what you need. If it does, it will publish its WSDL file; you download it and either handcraft a SOAP interaction or use your favorite tool to generate a client for you. This isn't necessarily a bad thing; it's likely that in many of your applications you'll be creating specific B2B Web service connections, which means either you or your partner will be creating the WSDL. You won't be searching for it all over the Internet. But since I was doing my own personal research, I needed to find a WSDL file.
I turned to my trusty application development tools and proceeded to try to use a WSDL (which included having to find one to use!).
Web Service Access via VB.NET
With Visual Studio .NET, I tried at first to use the help documentation, and I got almost nowhere. Part of the problem is that I have to upgrade to the Gold version of VS.NET; I'll do that this week and get back to you on whether or not this makes the help a little more productive. But since I didn't have that option, I instead turned to the Internet, and lo and behold, I almost immediately found what I was looking for. I went to Google, searched on "Google Web Service VB.NET" (with no quotes) and the first hit was a pretty straightforward tutorial on accessing Google with VB.NET. Huzzah! I am saved! Microsoft advocates swear that the sheer mass of Windows desktops and the zero-price entry point of the .NET tools means that there are vast numbers of programmers out there, which in turn means that .NET programming tips and tutorials like this are everywhere on the Internet. According to the company line, this makes the .NET framework more productive than anything else. I've pooh-poohed the idea in the past, but this particular article certainly lends some credibility to the concept.
I've noticed an interesting issue with Internet VB.NET tips, though. While it's easy to copy and paste Visual Basic code, the form definitions are a different matter. It seems that the source code for the Form object is relatively fragile and difficult to copy and paste, especially via typical Internet methods such as email or online forums. This makes it difficult to give someone a complete working example online. However, creating a form with a few controls is so easy in VB.NET that it really doesn't add much time to the development cycle, and once you're done with the proof of concept, you have code that you can easily use in a real application.
So with the help of the very friendly tutorial article, I was able to knock together a working VB.NET application that accesses Google for searching and spell checking, all in about an hour, with the following results (to see the code, you can review the article; I followed it pretty faithfully):
Figure 1: This is the Search/Spell Check application in VB.NET. (Click images to enlarge.)
Web Services Access via WDSC
The second thing I tried was to use WDSC. I've long known that WDSC has many wizards designed to help you use a Web service. I even used one awhile back to successfully create a Web service and consume it all on the same workstation. But I had never tried to actually consume a commercial Web service.
Unlike VS.NET (and again, we have to be careful with comparisons since the help on the beta version of VS.NET was clearly not complete), WDSC had an excellent tutorial for creating a Web service. It explained in exact detail the steps to go through to import a WSDL file and then use it to generate a Web service client. And there was a decent generic browser test client that would allow you to test the Web service.
So I fired up WDSC and tried to import the WSDL. Luck was not with me; I kept getting an error about being unable to resolve "soapenc:Array". Here's the code in question:
Figure 2: This is the code that kept failing.
I beat at this for hours and hours, traipsing the Internet, looking through forums, and trying the old "change one line until it breaks" method, until it became clear that WDSC just wasn't going to accept this syntax. This made it seem that Microsoft had the competition all sewed up, but I remembered during my research happening upon a similar syntax that seemed like it might work.
Figure 3: This is the code I used to replace the failing code.
To be honest, I wasn't 100% sure what I was doing, but it worked! I did take a long look at the generated code and I'm fairly certain it's fine, although I'm not sure what will happen if too many values are returned. It may be smart enough to not overflow the array; on the other hand, it may cause an array index out of bounds exception. In any case, the WSDL now validated just fine and I was able to continue on and use the tool. Once I did that, I was quickly able to first test the WSDL using the browser interface:
Figure 4: This is the generic browser interface used to test any Web service.
And then I wrote a quick program that used the Web service proxy. I really like how this is handled in Java; each of the elements in the WSDL definition end up as classes, and the result is returned as a class so you can then run through the result just like you would any other complex object. The code was very simple, and I was quite happy with the result:
Figure 5: This is all the code that was required to access the generated client proxy.
You'll notice some pixellated code in the listing above; that's my personal password for accessing the Google APIs. In order to test, you'll have to get your own, but the VB.NET article I referenced at the beginning of the column will help you there.
Finally, for the fun of it, I decided to try out the modified WSDL on VS.NET. It wasn't a happy occasion. I ended up with a rather severe error message:
Figure 6. This is the error I got when I tried to use the xsd:sequence version of the Google WSDL.
Digging deeper into the message, I find this:
Cannot assign object of type Google2.Google.DirectoryCategory to an object of type Google2.Google.DirectoryCategoryArray.
It's pretty clear what's happening; the xsd:Sequence code is causing an imbalance in the code generator's mind. I think it tried to do a version of what it did for the soapenc:Array specification but only managed half of it. And since there's really no way to modify any of this code, it's clear to me that VS.NET doesn't quite support this nuance of the standard.
The Nice Thing About Web Service Standards...
...is that there are so many of them. In this particular instance, I ran across a problem with a concept that is about as fundamental as you can get in computer-to-computer programming: sending sets of similar data. Whether it's flat files or result sets, you often have to send more than one instance of data, and the SOAP folks dropped the ball. So now there are two competing methods, one that works in VS.NET and one that works in WDSC. How often have we heard this particular song?
Other Access Methods
After spending way too much time fighting with what should have been a simple task of defining more than one record in a result, I didn't have much time to do anything else. However, I did want to look into the new JAX-WS 2.0 specification from Sun to see what was going on there. This requires the latest version of the JVM, which means that WDSC can't run it, but Eclipse works just fine. Unfortunately, these new Web service extensions are stacked on top of one another, and the cross-requirements are rarely explicitly stated. It turned out that I had to add 50 JAR files to my Eclipse workspace to get the code to work. Once I did, it was pretty impressive:
Figure 7: This is the code required to access a Web service using JAX-WS 2.0 (plus 50 JAR files!).
I hope to get a better handle on this whole JAX-WS thing a little later. This is the way I like to see tooling, with code wrapping other code and exposing a simplified interface. While both WDSC and VS.NET are fairly hard-coded, my guess is that I could probably use either the xsd:sequence or soapenc:Array syntax and the JAX-WS parser would handle it.
Wrapping It Up
A quick comparison of the philosophies of the two tools is in order. With the Web Services Client wizard, IBM generates code for you to access the Web service as well as a simple Web page to use that code. You get the idea that IBM believes that everything should run in a browser. Visual Studio, on the other hand, expects you to create a specific application to test your Web service. By far the easiest path with Visual Studio is to create a simple thick-client application. I'm still not familiar with Web Forms, but I believe that my VB.NET form should translate pretty directly to a Web Form, so I am hopeful that work done in the thick client won't be lost. Similarly, the Visual Editor in Eclipse should allow creation of simple forms, but again that's not the core strength of WDSC, so I haven't really done much with it yet. But in the end, if you're looking to create a Web interface, WDSC gets points, while VB.NET definitely has the upper hand when it comes to thick clients.
A second way the tools differ is in their attitude toward programmers. VB.NET makes it very easy for a programmer to write code, provided the interfaces work. Most of the details are hidden and in fact aren't even modifiable. For example, when you import a WSDL file, an entire hierarchy of objects is built, none of which you can modify. WDSC on the other hand tends to create lots of classes using fairly straightforward syntax that a programmer can easily modify. This makes it a little easier to debug and even to modify the code when problems arise due to incompatible standards. Let me be clear, though: Many of the bits of generated code from WDSC use classes shipped from IBM without source. So while I typically have more insight into the generated code than in VB.NET, I still tend to hit dead ends when trying to understand really complex problems.
The Sun code is perhaps the most interesting of the three, especially since it was something of a dark horse. I hadn't expected it to be so powerful, yet it might be the most flexible of the bunch. I wish I had more time to show you how it works, because it has some really cool features. For example, parameters are actually stored in a separate XML file, so you don't have to hard-code passwords in your program. On the other hand, finding and including 50 JAR files just isn't my idea of a productive work environment.
Each tool has its capabilities. None of them is ready for a full production environment, in my mind, but any of the three can be used today for proof of concept and to start you on the road toward your own Web service application design.