Application Architecture for the Enterprise

« Eating My Own Words | Main | XML language extension for Java »

Redeemed! JAX-WS still sucks!

Recap of the JAX-WS Debate

You may not have been following the thread of discussion about JAX-WS between Jason Greene and myself, so I'll provide a recap. On March 23rd I posted a blog entry intitled "JAX-WS is Bad, Bad!" the point of which was that JAX-WS is a small improvement over JAX-RPC (see "JAX-RPC is Bad, Bad, Bad!") but is still way too complicated. In that post I issued a challenge to the JAX-WS team to show me that it's easy to implement web services for eBay and Amazon.com using JAX-WS 2.0. Jason Green, the JBoss developer who is working on the JBoss implementation of JAX-WS posted what appeared to be a very simple solution. While he had created a client application and not a service, I decided that he had in fact met the technical requirments of the challenge and so, as promised, I eat my own words as reported in this posting "Eating My Own Words". However, in that posting I clarified the challenge to specify that the eBay and Amazon.com should implemented as web services, rather than clients (I left out the bit about eating my own words because I still wasn't feeling well from the first dead-tree breakfast).

Challenging the challenge to my challenge

Soon after my last post, Jason Greene seemed to have answered the challenge again with this post "Taking RMH's JAX-WS Challenge". It appeared that I had been outdone by the Wily Jason Greene once again. At this point I decided that I needed to try and implement these web services myself. I had taken a hard stance about JAX-WS and if I was wrong, as Jason Greene's examples suggested, I would need to make amends. A public apology and a full retraction.

So yesterday I contacted Jason and requested that he work with me to implement these solutions so I could see first hand the ease with which they are implemented. Jason was extreemly gracious and helpful. Jason provided me with a pre-packaged solution for the Java Web Service Reference Implementation and some addition instructions for how to deploy it. Although I was very grateful that he had taken the time to package up a solution, I wanted to create my own web services from scratch. Jason was more than happy to help, but I needed sometime to set up accounts. I never did get back in contact with Jason. What I discovered between then and now made it unnecessary.

For several hours yesturday I attempted to create web service clients, surely the simplest of endpoints, to connect to Amazon.com, eBay.com, Google, and a couple other web services provided by Atomic-X.com. Rather than use the Web Services Reference API I decided to use the Java EE 5 reference API which I already had installed the previous day and understood well enough to make quick progress. Or so I thought. All I wanted to do, as a first step, was create a web service client for eBay or Amazon.com but try as I might I never succeeded.

Amazon.com
At first I tried the Amazon.com web services. I wanted something really simple so I chose an operation that returns the sales rank of a book given its ISBN number. I downloaded the WSDL and used the JAX-WS utility (i.e. wsimport) to generate the package I would use to access the web service. Than I examined the WSDL document and using Jason's eBay example as a general guide attempted to implement the web service client. I never got it working. Although I figured out how to set some of the values being passed to the service, I couldn't figure out how to set all of them. I referenced this web site that Amazon.com provides so that I could see what the outgoing and incoming data would look like (funny but yesterday it showed me the actual SOAP requests, but today it shows me raw data) so I knew that the service actually works and what I might expect in terms of outgoing and incoming messages. After mucking around with it for a couple of hours I gave up. I must have chosen too complex of service to start out with. I decided to try something simpler.

Atomic-X
Next I tried a couple web services from Atomic-X, which provides publicly available and really simple web services. I had to give up on this one too because the wsimport utility provided by the JAX-WS 2.0 RI kept throwing errors when I tried to generate the JAX-WS package to access the services. It said it didn't recognize the s:schema tags. Hmm ... well I'll try Google, I thought. They have a web service.

Google
I decided to try the web service operation that lets you check the spelling of a word, it was pretty simple. Unfortunately, I couldn't get the wsimport utility to work on that web service either because it uses SOAP Encoded messages and wsimport doesn't seem to support that. Ok, that's understandable. Everyone knows that SOAP Encoding is a bad idea anyway (Hey Google guys! What's up with that?)

eBay
Having tried three public web services with no success I decided to see if I could at least generate the JAX-WS package for the eBay web services. That worked like a charm, but something bothered me. The eBay package contains hundreds of classes. That led me to investigate the WSDL/JAX-WS bindings generated by the wsimport tool and to my final conclusions that JAX-WS sucks.


WSDL/JAX-WS Bindings
Looking at the eBay WSDL and Jason's example it was pretty easy to tell that you start with the Java class that represents the wsdl:service. It's a factory from which you access port types that are essentially interfaces to the web service. Still, I thought, how would I have understood that if (a) I didn't already have a deep understanding of WSDL 1.1 and (b)I had not seen Jason's example? Also, why were there so many classes? They seemed to go on forever.

Well one explanation for all the classes was that the eBay WSDL itself was enormous. But when I looked at the Amazon.com package generated by JAX-WS it too was quite large, yet the Amazon.com WSDL seemed reasonable in size. How many classes were there and how did they compare to the WSDL? Time to start counting.

In the end I was thunderstruck by the number of classes that JAX-WS generated for both eBay and Amazon.com (the only web services I was able to generate classes for).

eBay requires 700 + Java classes
For example, the eBay WSDL includes a whopping 500 XML Complex Schema types, 200 WSDL message types, and 1 port type. That's ridiculous, but it might account for the huge package of Java classes that was generated by the JAX-WS wsimport tool. When I counted the Java source files generated from the WSDL I came up with over 700 Java classes! Maybe there is a Java class for each XML Schema type and WSDL message type? Still that seemed weird. Why would it be the sum of those and not simply be equal to the XML Complex Schema types and a couple of ancillary classes.

Amazon.com requires 124 Java classes
Next I did the same inspection of the Amazon.com WSDL and generated JAX-WS classes. The Amazon.com WSDL defines 18 XML Complex Schema types, 40 WSDL message types, and 1 port type. However, the JAX-WS generated 124 Java classes! That seemed really weird! Why so many classes? I could see 42 or 43 classes (one for each complex type plus classes representing services and port types), but 124?

The Hands Go Up
After making those counts and trying to reconcile the Java classes to WSDL documents, I threw my hands in the air. This was just way too complicated! JAX-WS was not making things simpler, any more than JAX-RPC! For every web service I wanted to use, I had to deal with an entirely new API represented by the JAX-WS packaged generated from the WSDL document. Not only that, but the generated classes were not documented! There was no tutorial that showed me how to use them and despite claims to the contrary, it wasn't self evident.

If you know WSDL (and I do) and you can study the source code closely (which I did) you could kind-of figure out how to use each new web service API. But, that's a lot of work. Too much work if you ask me. It made me understand why Google, eBay, and Amazom.com all provided their own proprietary toolkits for Java, C and C#: These web services were complex and demanded not only a straightforward API but plenty of documentation to back them up. With JAX-WS you get neither of those things.

The web service API (package) generated by JAX-WS is not straightforward unless you already have expertise in WSDL as well as other skills I'm probably taking for granted. In addition, the JAX-WS APIs being generated are not documented. The JAX-WS tools could never create a tutorial in addition to the APIs. That would require human intervention. In other words, in order for the JAX-WS to be useful when dealing with complex web services you would have to generate the classes and then write your own documentation, otherwise everyone in your organization would have to re-invent the cognitive wheel that probably took you days to grok.

This experience trying to use JAX-WS has led me to believe, more firmly than before, that JAX-WS is a crazy, awful, terrible mess of a solution for Java web services. Something much simpler is required. Think of this, I spent 18 months researching and writing a book on J2EE web services. I delved deeply into the XML, SOAP, WSLD, UDDI, JAX-RPC, SAAJ, JAXR, and JAXP APIs. With all that background you would think it would be easy, but in fact I made no progress whatsoever. How are developers who do not have the benefit of all that training supposed to use JAX-WS? Jason Greene may find it easy to create short programs for accessing and hosting web services with JAX-WS, but than again the guy is implementing the specification for JBoss. No duh! Of course its going to be easy for him to come up with a seemingly simple program. Now you try it. Just make sure you have plenty of time to waste figuring out what I did. JAX-WS sucks. There: I said it again.

Having said all that, let me take a minute to defend Jason and his co-horts in the JAX-WS specification team. I think given the objective of JAX-WS, which is to provide a comprehensive mapping between WSDL web services and Java, they have done a fine job. As I've said, JAX-WS is somewhat simpler than JAX-RPC. The problem is not with the engineering its the objective. Why are they trying to create an RPC binding for web services? Hey guys, you may have taken the RPC out of the name, but you didn't take the RPC out of the technology. JAX-WS is an inherently flawed model. Rather than simplify SOAP/WSDL based web services, they made them much more complicated. What is needed is not a better RPC style web services API, what is needed is a completely different approach.

There is a better way to do this and that's by working with web services as XML messages and not remote objects or procedures. The solution, I believe, is to scrap JAX-WS 2.0 and start over with a completely different programming model. One based on the use of native XML types in Java. Something similar E4X (ECMAScript for XML). But that is the subject of another post.

I have no illusions that JAX-WS will be scrapped in favor of something completely different. Not yet anyway; not until the masses have suffered enough to drive them to other solutions. Only then, will it become clear to the Java EE vendors (including JBoss) that JAX-WS and its ilk are, and always have been, the wrong approach to consuming and producing web service messages.

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/t/trackback/4619211

Listed below are links to weblogs that reference Redeemed! JAX-WS still sucks!:

» Quote of the Day from Stefan Tilkov's Random Stuff
Richard Monson-Haefel on JAX-WS: Hey guys, you may have taken the RPC out of the name, but you didnt take the RPC out of the technology +1.... [Read More]

» Will Java EE 5 bring REST to Java? from Noelios
JavaOne 2006 has finally seen its first persentation about REST. Dave Johnson, from Sun, has demonstrated the beauty of REST with this presentation of the Atom Publication Protocol, one of the finest REST example available. This is great! Marc Hadley, ... [Read More]

Comments

Having used JAX-WS a little myself I sympathize with your experiences. Indeed we have an integration with JAX-WS in JRules 6.0.

My feeling is that this is partly a "top-down" vs. "bottom-up" issue. JAX-WS may be an ok solution to expose a Java method as a WS (some would say this is quick-and-dirty) but that it struggles when you want to start with a clean WSDL and expose it as a WS. Here I think the RPC-model breaks down, and I would agree that you are probably better off using a message-based WS.

In a loosely coupled world it also feels wrong to be generating Java classes from the complex types in a Schema. (Good) Schema should be flexible enough to accomodate future change, and something like XPath feels like a more robust addressing solution.

Dan

I have to say that I have enjoyed watching this discussion progress, and really appreciate your breakdown. On a personal note, I don't feel quite so stupid now. I am not too familiar with the details of web services, and picked Amazon WS as my first attempt awhile back. I was humbled to say the least and finally gave up, thinking I needed to do some serious homework before my peers found me out!

Ironic that I later had an easier time calling Amazon WS from an Ajax client, but as you say that's the subject of another post.

What do you make of REST over their Web Services interface? http://www.oreillynet.com/pub/wlg/3005?wlg=yes and http://developer.amazonwebservices.com/connect/entry.jspa?externalID=19&categoryID=14

Does that eliminate any of the complexity?

I agree with Daniel that it seems like all the productitivy hype is around wrapping/exposing existing methods. That's demoware to me.

The most part of all these classes are probably related to the XML-2-Java binding? But remember, SOAP is only a simple envelope around the actual XML message.

In my world of integration (EAI, B2B), mappings (XSLT, XQuery,...) are used to transform the messages to the correct format. Some SOAP adapter adds or removes the SOAP envelope.

Richard,
It seems that you forgot to take into account the nearly 200 simpleTypes
declarations in the EBay WSDL. So the 500+ compexTypes + 200 simpleTypes equals, well all be darned 700. JAX-WS, nor any other technology cannot
compensate for extreme WSDLs such as EBays.

Can you explain the Amazon.com results using the same rational? But actually that's besides the point. It's a matter of seeing the forrest through the trees my friend. The fact that you have to redefine all those types in Java in order to accomidate the mapping is just more proof that WSDL to OO RPC mapping is the wrong approach. If my web services toolkit suppored XML Schema types natively or simply worked with text there wouldn't be a need for 700 Java types.

I tried to move a simple example from Amazon's version 3 API to their latest and greatest. I don't know whether JAX-RPC and JAX-WS are broken, but the Amazon API certainly is. It is simply not OO.

I make an itemSearch call. (In the previous version, I was able to make an authorSearch, but that and a dozen other searches have been rolled into a single call. I am sure that makes the REST crowd happy.)

I get back an ItemSearchResponse. Nowhere in the Amazon documentation does it tell me what that is. I guess the REST crowd just gazes at the output and fiddles the XML apart.

But javap can spy on the stuff that wscompile produces. An ItemSearchResponse has a method getItems that returns an ItemsGen5[]. Huh? An ItemsGen5 has a method getItem that returns another array (!) of ItemGen6. That has methods getASIN, getSalesRank etc. etc.

I wasted a couple of hours of trial and error on this festering mess, and I decided it wasn't worth it. SOAP is supposed to be an RPC mechanism, not a wrapper over a REST API. If I want to eat soup with a fork, let me use a REST API, not a SOAP API that wraps it--that's like eating soup with chopsticks.

I had another look at the festering mess with the ItemsGen5 and ItemGen6 classes. These were generated by the JAX-RPC in the JWSDP beta. With JAX-WS, things were a bit saner. All those anonymous complextype parameters named item were put inside a single monstrous class Item, with over a hundred methods, but at least not with a fragile name. I was then able to make my web service call with JAX-WS without too much trouble.

Richard,
I looked at the Amazon WSDL, it seems you forgot to count the anonymous types. Anyway, how do you write a tool kit that deals with schema-types
natively or as simple text without drastically reducing performance? It is the nature of strongly typed interfaces that allow for faster perfomance because at runtime there is little need to see if the "text" is formatted properly or represents the proper type. Granted, if the schema types were
fixed, this would be a very simple problem, however, since schema is dynamic in that web service developers can define new types, I do not know how one could give developers all of the benefits of that a stronly typed environment provides.

Wouldn't using an IDE put an end to all the complxity? Or are you averse to IDEs? Understandable, if so. Still, a lot of the problems you've had would be overcome with an IDE that generates all the basic code for you.

Hi there,

Long time reader first time poster.

>How are developers who do not have the benefit of all that training supposed to use JAX-WS?

Im quite new to JAX-WS, Ive been using the Celtix ObjectWeb project (http://celtix.objectweb.org) quite successfully, I initially came across it as the project has quite comprehensive training material available for download including extensive coverage WSDL to Java mapping with JAX-WS and reviews the generated code which was very helpful for understanding JAX-WS. I havent tried Celtix yet with an amazon or eBay WSDL yet :o)

Post a comment

This weblog only allows comments from registered users. To comment, please Sign In.