Java Web services
Learn about a Web services framework based on the JAXB and JAX-WS reference implementations
This content is part # of # in the series: Java Web services
This content is part of the series:Java Web services
Stay tuned for additional content in this series.
The Metro Web services stack is an open source tool developed by Sun Microsystems. It incorporates the reference implementations of the JAXB 2.x data-binding and JAX-WS 2.x Web services standards, along with other XML-related Java standards. Metro also includes added nonstandard components to support both basic JAX-WS service definition and usage and a variety of WS-* extensions to SOAP message exchange.
Metro can be used either as a stand-alone Web services stack or as an integrated component within the open source Glassfish application server. Web service configuration is somewhat easier when you use Glassfish, especially if you're developing on the open source NetBeans IDE, which includes GUI tools for configuring both basic Web services and WS-* extensions. In keeping with the focus on Web services, this series looks only at the stand-alone use of Metro in an IDE-independent manner, just as earlier articles discussed stand-alone use of Apache Axis2 rather than application servers incorporating Axis2 and supporting GUI tools.
Metro basics vs. Axis2
Prior articles in this series have covered Axis2 in depth, so a discussion of the similarities and differences between Metro and Axis2 is a good starting point. The similarities are limited and mostly revolve around the common requirements of developing code using Web services. Both frameworks allow you either to start from existing Java code and build a Web service (though in the case of Axis2 the support for this approach is limited unless you use a separate tool such as Jibx2Wsdl) or to start from a WSDL Web service description and generate Java code to use or implement the service. Both frameworks model service operations as method calls, and service port-types as interfaces.
The differences between Metro and Axis2 are much more striking than the similarities. On a fundamental level, Metro is designed around JAXB 2.x and JAX-WS 2.x, with no interest in supporting any alternatives to these technologies (except for legacy JAX-RPC usage). Axis2 is designed to support an open-ended range of technologies, especially in the XML data-binding area; although it includes support for JAXB 2.x and JAX-WS 2.x, it doesn't give them any special status. (If anything, JAX-WS is somewhat of a second-class alternative in Axis2 because — as discussed in "JAXB and JAX-WS in Axis2" — you can't configure WS-Security or other features for a JAX-WS service.)
Structurally, both stacks use handlers as part of the request and response processing. Axis2 builds on this handler approach to implement modules : pluggable extensions to the basic SOAP message exchange that are used to implement WS-* technologies in a highly configurable manner. Metro supports a wide range of WS-* technologies with handlers, but these technologies are integrated into the Metro engine, rather than separable components. The integration approach Metro uses is not as flexible as Axis2 modules, but it does provide some advantages when it comes to configuring and using WS-* extensions.
The two stacks also differ in terms of how the client code uses WSDL service definitions. Axis2 primarily uses WSDL service definitions for client-side code generation, extracting the service configuration information from the WSDL and generating code to construct a matching Axis2 client configuration at run time (though you can also parse a WSDL service definition at run time). JAX-WS 2.x, and hence Metro, requires a WSDL service definition at run time in order to build the service configuration. This run-time WSDL usage adds some startup overhead — though only for the first service invocation — without any obvious benefits.
There are also differences on the server side. For the common case of HTTP transport, Axis2 is normally set up as a distinct Web application (a WAR file), with any number of individual services deployed to that Axis2 Web application (though it can also be packaged as part of an application WAR). You can deploy services via Web page upload, or by dropping the Axis2 service AAR file directly into the appropriate directory of the expanded Axis2 Web application. The individual service configuration information is normally generated by Axis2 from your WSDL service definition at build time, and then included in the service AAR file. The standard Axis2 Web application also provides a variety of monitoring and control tools via a Web page interface.
Metro, in contrast, requires you to build a separate WAR file for each Web service application, with the Metro library JAR files either included in the WAR or otherwise in the classpath (as part of the HTTP server installation) and a WEB-INF/web.xml file present in the WAR that references both your service and a Metro servlet. When using Metro stand-alone, you also need to create a sun-jaxws.xml configuration file, which provides additional information about the service configuration. The information from these configuration files is combined with the JAX-WS annotations in your actual Web services classes to configure Metro fully for your service. Because it's designed for use in this embedded manner, Metro does not provide any direct monitoring or control tools.
Both Axis2 and Metro also provide integrated HTTP server support. In the
Metro case, this comes by way of a JAX-WS feature, the
javax.xml.ws.Endpoint class. Both the Axis2 and Metro/JAX-WS
integrated HTTP servers are suitable for use in testing or as an
asynchronous response port, but for hosting a production Web service, a
Java application server supporting the Servlet API is the preferred
The code download provides a version of the simple library-management service used in previous articles of this series, this one modified to demonstrate Metro usage. As with the earlier versions, the WSDL service definition defines four operations:
getBookto retrieve the details for a particular book identified by International Standard Book Number (ISBN)
getBooksByTypeto retrieve the details for all books of a particular type
getTypesto find the types of books available
addBookto add a new book to the library
In "JAXB and JAX-WS in Axis2" you saw how this application worked in Axis2, first with normal Axis2 code generation using JAXB 2.x data binding, then with JAX-WS 2.x service configuration. Most of what you saw in that article also applies when using Metro. The WSDL is identical except for the service name and endpoint address, the generated JAXB data model is the same, and even the generated service classes are identical except for the Java package and the service name used in the JAX-WS annotations.
Client-side code for the sample application on Metro is identical to that for using JAX-WS with Axis2, and even the build steps are the same. See "JAXB and JAX-WS in Axis2" for details of the code and handling.
The server-side code for the sample application on Metro is also identical to that for using JAX-WS with Axis2, but the build steps are somewhat different. With Axis2, you prepared the service for deployment by creating a JAR file containing the service and data model classes, then deployed the service by dropping that JAR into the WEB-INF/servicejars directory in an Axis2 server installation.
With Metro, you instead need to create a WAR file containing the service and data model classes, the Metro library JARs (though you can instead install the Metro JARs directly into your Web server — if you're using Tomcat, the Metro download includes a metro-on-tomcat.xml Ant build file to install the JARs, with instructions in the documentation), and a pair of configuration files. The WEB-INF/web.xml file configures the actual servlet handling. Listing 1 shows the version used for the sample application:
Listing 1. Sample application web.xml
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"> <display-name>MetroLibrary</display-name> <description>Metro Library Service</description> <listener> <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener </listener-class> </listener> <servlet> <servlet-name>MetroLibraryPort</servlet-name> <display-name>MetroLibraryService</display-name> <description>Endpoint for Metro Library Service</description> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>MetroLibraryPort</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <session-config> <session-timeout>60</session-timeout> </session-config> </web-app>
If you've worked with Java Web applications before, the Listing 1 WEB-INF/web.xml file should look familiar (at least in
structure). The particular entries used tell the servlet engine to which
the WAR file is deployed to use the
class as a listener for servlet context events and to use the
com.sun.xml.ws.transport.http.servlet.WSServlet class as an
actual servlet. These classes are specific to Sun's Metro stack, and the
references to the classes are required in order to work with Metro. The
servlet is configured to receive all requests coming to this Web
application (by the
In and of itself, the Listing 1 WEB-INF/web.xml file just configures the servlet engine to use a Metro-provided listener and servlet. A separate file, WEB-INF/sun-jaxws.xml (shown in Listing 2), is used to configure Metro to route requests received by the servlet to the service-implementation code.
Listing 2. Sample application sun-jaxws.xml
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0"> <endpoint name="MetroLibraryPort" implementation="com.sosnoski.ws.library.metro.MetroLibraryImpl" url-pattern="/" wsdl-location="WEB-INF/wsdl/library.wsdl"/> </endpoints>
The Listing 2 WEB-INF/sun-jaxws.xml file is as about simple as it can get, with a single endpoint definition giving the port name, implementation class, pattern to be matched for requests, and a WSDL document location. The WSDL document location is the only optional part of this endpoint definition. If you don't specify a WSDL document for a service endpoint in the sun-jaxws.xml file, Metro automatically generates one at run time.
Building and running the sample code
Before you can try out the sample code, you need to download and install a
current version of Metro (the code was tested with the 1.5 release) on
your system (see Related topics). You also
need to edit the build.properties file in the root directory of the
unzipped sample code download to change the value of the
metro-home property to the path to your Metro installation.
If you're going to be testing with a server on a different system or port,
you may need to change the
To build the sample application using the supplied Ant build.xml, open a
console to the root directory of the download code and type
ant. This will first invoke the JAX-WS
tool (included in the Metro distribution), then compile the client and
server, and finally package the server code as a WAR. You can then deploy
the generated metro-library.war file to your test server, and finally type
ant run on the console to try running the sample client. The
sample client runs through a sequence of several requests to the server,
printing brief results for each request.
Next up on Metro
In this article, you've seen the basics of working with the Metro Web services stack. Because Metro uses JAX-WS 2.x annotations for configuration, the same JAX-WS 2.x sample application code used in "JAXB and JAX-WS in Axis2" also works with Metro. The only changes needed concern how the code is packaged and deployed on the server side, and there Metro and Axis2 are significantly different. Metro uses an embedding approach whereby you create a Web application for each service or group of services (and no control or monitoring functions are provided). Axis2 normally uses a single dedicated Web application as the host for any number of individual services (with basic control and monitoring functions provided directly via a Web page interface).
Beyond the basics of Web service message exchange, Metro also supports SOAP extensions such as WS-Security. Just as with the service-packaging issue, Metro and Axis2 take different approaches to very similar requirements in this area. In the next article, you'll see how Metro handles the same WS-Security examples previously used in this series with Axis2.