Java and Web Services - the need for a WSDL Reflection like API for clients
Web Service tools in Java are into their third generation now. Web services were introduced with the hype of a loosely coupled technology for inter connecting disparate end point systems. But it is in fact suffering from its tight coupling based on the WSDL data specifications and data types. Most of the current tools offer quick solutions to expose existing code as web services but none of them offer a simple yet intuitive and full featured client. This article shall focus on the Java based Web Service APIs and compare some of the most commonly available tools like Axis1.x, Axis2, XFire, WSIF and SAAJ, along with stating the necessity for a Java Reflection like API for Web Services based on WSDL that can retrieve the port type, operation name, service namespace, service style, method parameters, return types, Java data mappings and so on.
The first question that might pop out on everyone's mind might be about Apache WSIF. Though, WSIF mainly focuses on using the meta-information available in the WSDL, it doesn't offer a solution to directly work with the actual underlying XML message for a SOAP based WSDL service. Also, It can lookup the default port type, create default input and output messages for a specific operation, yet it does not offer a full fledged Reflection API like lookup for any and every meta information on the WSDL. Such a dynamic lookup can be used to check for available operations and exposed services at runtime and invoke them appropriately. Also, as organizations are looking forward to web services as a high volume transaction capable, reliable and interoperable work horses, a feature to turn off the java object binding becomes highly desirable. This would be handy especially in scenarios where the application is just a broker to a web service and the actual data consumers are elsewhere. WSIF also depends on stubs generated from Apache Axis WSDL2Java tool.
Apache SOAP was based on DOM and had to maintain the entire XML tree in memory and hence was not suited to handle data intensive services. Though Axis1.x which was developed from Apache SOAP was based on SAX and has enjoyed a huge volume of success in many corporate products, it also has a serious flaw with web services that serve out huge XML content. It failed miserably in handling huge XML based transactions as the SAX based parsing was tightly coupled to Java object binding. Thus, even though the SAX parsing can handle huge XML data efficiently, the data had to be stored in memory by generating and mapping to POJOs via its type mapping registry mechanism coupled with its serializers and deserializers. It did not allow for a direct method to deal with the XML content transparently. There was no way one could turn off the generation of objects and deal with the XML content in a memory efficient manner. Though, it offers handlers and handler chaining mechanisms that can subscribe to receive the XML request/response message content, the object binding was mandatory and each handler was presented with its own local copy of the message, which all add up to memory woes and hinder performance. However, Axis1.x has a very good WSDL parser tool called WSDL2Java but it does not expose a complete set of API that the client can use to lookup datatypes, method parameters, and their XML name tags or return parameters.
Axis2 has been a complete re-architecture of Axis1.x from ground up to address these issues. Axis2 is based on the new StAX (Streaming API for XML) and is significantly poised to perform better than Axis1.x because of the advantages offered by StAX based pull parsing. It provides more XML oriented approaches and it also has a good Object Model named AXIOM that revolves around StAX to provide partial or deferred building support. This dependence of Axis2 on StAX allows it to boast of a low memory foot print. Axis2 also does not depend on storing the entire XML content in object forms on memory. The Axis2 has support for pluggable data bindings and either SOAP or Java transport mechanisms can be preferred. However, one flaw with Axis2 is that is also does not allow a transparent and efficient method to dynamically invoke web services like WSIF nor any lookup methods based on the WSDL.
SAAJ1.3 from Sun is a reliable SOAP messaging API. However it does not deal with other Java based transport mechanisms like JMS, RPC, etc as dealt by Axis2. It.s surprising that SAAJ offers much better performance than most of the Axis clients though it offers a DOM based API. XFire has been developed by the Codehaus team as an alternative option to Axis1.x at the same time as Axis2 was envisioned and drafted to improve performance along with the goal of catering to SOAP1.2 and be WS-I 1.1 compliant. XFire has an embedded HTTP server (Embedded XFire HTTP Service) and can be used to easily expose Java methods as web service endpoints with an easy integration in Spring. XFire is also based on the current generation of pull parsers and incorporates StAX. However, XFire does not support encoded RPC style services and is yet to support dynamic clients which might be featured in their next release.
Conclusion
To sum up, though the performance aspect of current Java web service tools are pepped up by the use of XML pull based parsers like StAX and an more XML oriented approach with optional object endpoints, the missing link in Java based web service tools are a good Reflection API like dynamic WSDL parsing capability. It can be used to provide a handle to the meta-information available on the WSDL at runtime for clients. A mix of WSIF-like (with a more extensive WSDL parser) and Axis2 like StAX based functionality is desired. It shall not only offer a lot of possibilities like handling of small changes on the web service specification (WSDL) at runtime (an open issue would be to decide what changes are small and what can be handled?!) and empower clients at times to even ward off a complete rebuild and code changes. Another great feature would be to allow the clients to choose between options to turn on/off the WSDL parser and cache the WSDL meta-data as it need not affect the performance, every time a call to the WSDL reflection API is made. This would be useful when the web service definition is not static and is in development or re-evolving stages so that clients do not need to wait for the final release but can continue with their development and testing. It also lends much flexibility to the client design as it can transparently decide between which WSDL exposed operation to choose or which transport protocol to use at runtime. Let's do hope such a tool with the best features of all existing APIs would soon be released.
Birth of MaximusJ (MaxJ) client
This project named as MaxJ client (named after the dare devil Sydney to Hobart yacht race crew, Maximus
At this initial stage of planning, it is of paramount significance to determine a strategy to parse the WSDL file in an efficient manner and probably through a single round of parsing. The obvious idea would be to create a list of mappings (1 to 3 maps), highlighting the three prominent sections of a WSDL file.
Bindings Map -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ---------------------------------------------- name | operationName | style | wsdlInputUse | wsdlInputHeaderMsg | wsdlInputHeaderPart | wsdlInputHeaderUse | wsdlOutputUse | wsdlOutputHeaderMsg | wsdlOutputHeaderPart | wsdlOutputHeaderUse | -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ----------------------------------------------
PortType Map -------------------------------------------------- ------------------------------------------------ operationName | inputMsg | outputMsg -------------------------------------------------- ------------------------------------------------
Elements MapThese maps can be processed (consolidated further into a single mapping) and stored onto the filesystem for future/further use. The client can use this mapping for building up the XML relevant to each method to be invoked at runtime. The MaxJ client shall not create java binding for XML and also shall abstract the XML parsing from endusers and return either independent parameter values or return a customized output as per some predefined configurations. (To be considered and defined in detail)
-------------------------------------------------- ------------------------------------------------ name | type | minOccurs | maxOccurs | restriction Base | nillable | parentMethod | parentElement | -------------------------------------------------- ------------------------------------------------
This work is under progress and the most recent source code can be checked out from the project cvs. In case of any suggestions, comments or volunteer work, please do drop in a line to maxjadmin@users.sourceforge.net
Additional links: