by Bhakti Mehta JSR 109: Implementing Enterprise Web Services defines the programming model and runtime architecture for implementing web services in Java. The architecture builds on the Java EE component architecture to provide a client and server programming model that is portable and interoperable across application servers. JSR 109 defines two ways of implementing a web service. One way is based on the Java class programming model — the web service is implemented by a Java class that runs in a web container. The other way is based on the Enterprise JavaBeans (EJB) programming model — the web service is implemented as a stateless session bean that runs in an EJB container. Two previous Tech Tips covered the two techniques. The tip Developing Web Services Using JAX-WS, described how to develop a web service using the Java class programming model and Java API for XML Web Services (JAX-WS) 2.0. The tip Developing Web Services Using EJB 3.0 described how to develop a web service using the EJB programming model and JAX-WS 2.0. The following tip is a successor to those previous tips. It describes how to develop an application client that references multiple web services that implement any combination of the two web services programming models. A sample package accompanies this tip. It demonstrates a standalone Java client that accesses two web services, one implemented as a servlet and the other implemented an a stateless session bean. The example uses an open source application server called GlassFish v2, specifically GlassFish V2 UR1. You can download GlassFish v2 from the GlassFish Community Downloads page. You can find instructions on how to install and configure GlassFish here. Also see the GlassFish Quick Start Guide for the basic steps to start the server and deploy an application. Let’s start by creating the two web services. The Servlet-Based Web Service Here is the source code for WeatherService, a servlet-based web service that displays the current temperature for a given zip code. You can find the source code for Weather Service in the servlet_endpoint directory of the sample package. @WebService public class WeatherService { public float echoTemperature(String zipcode) { System.out.println("Processing the temperature for " + zipcode); //Its Beverly Hills let it be nice and sunny !! return 80; } } As you can see, JAX-WS 2.0 relies heavily on the use of annotations as specified in JSR 175: A Metadata Facility for the Java Programming Language and JSR 181: Web Services Metadata for the Java Platform, as well as additional annotations defined by the JAX-WS 2.0 specification. Notice the @WebService annotation in the WeatherService class. This is an annotation type defined in the javax.jws.WebService package and marks the class as a web service. A web service requires an endpoint implementation class, a service endpoint interface, and portable artifacts for execution. However, as specified by JSR 109, you only need to provide a javax.jws.WebService-annotated service class, as is the case here. Creating the EJB-Based Web Service Here is the code for DegreeConverter, a web service that is implemented as a stateless session bean. This web service converts a temperature value from the Fahrenheit scale to the Celsius scale. You can find the source code for DegreeConverter in the ejb_endpoint directory of the sample package. @WebService @Stateless public class DegreeConverter { public float fahrenheitToCelsius(float far){ float degCelcius; degCelcius = (far - 32) * 9/12; return degCelcius; } } One of the significant improvements in the Java EE 5 platform is a much simpler EJB programming model as defined in the EJB 3.0 specification.You can declare a class a session bean or entity bean simply by annotating it. For example, you can declare a class a stateless session bean by annotating it with the @Stateless annotation, as is the case for this web service . Again, all you need to provide is the javax.jws.WebService-annotated service class. Compiling and Deploying the Web Services After you create each web service, you need to compile it, generate portable artifacts for its execution, and deploy it. An ant task is provided in the sample package to perform these steps. See the section Running the Sample Code for details. Creating the Client After you deploy the web services, you can access them from a client program. The client uses @WebServiceRef annotations to declare references to a web service. The @WebServiceRef annotation is in the javax.xml.ws package, and is specified in JSR 181. If you examine the source code for Client, the client program used in this tip (you can find the source code for Client in the client directory of the installed sample package), you’ll notice the following: @WebServiceRefs({ @WebServiceRef(name="service/MyServletService", type=servlet_endpoint.WeatherServiceService.class, wsdlLocation="<a href="https://localhost:8080/weatherservice/GetWeather?wsdl">https://localhost:8080/weatherservice/GetWeather?wsdl</a>"), @WebServiceRef(name="service/MyEjbService", type=ejb_endpoint.DegreeConverterService.class, wsdlLocation="<a href="https://localhost:8080/DegreeConverterService/DegreeConverter?wsdl">https://localhost:8080/DegreeConverterService/DegreeConverter?wsdl</a>") }) public class Client { ... The @WebServiceRefs annotation allows multiple web service references to be declared in the class. Here the class references two web service endpoints, a servlet endpoint and an EJB endpoint. Notice that each @WebServiceRef annotation has the following properties: name. The Java Naming and Directory Interface (JNDI) name of the resource. type: The Java type of the resource. wsdlLocation. A URL pointing to the WSDL document for the web service. Here is the code in Client that looks up the servlet-based weather service, gets its port, and invokes its echoTemperature method: javax.naming.InitialContext ic = new javax.naming.InitialContext(); WeatherServiceService svc = (WeatherServiceService)ic.lookup( "java:comp/env/service/MyServletService"); float temp = svc.getWeatherServicePort().echoTemperature("90210"); Here is the code in Client that looks up the EJB-based service, gets its port, and invokes its fahrenheitToCelsius method: DegreeConverterService degConverter = (DegreeConverterService)ic.lookup( "java:comp/env/service/MyEjbService"); System.out.println("Invoking the degree converter service for zip 90210.. " ); float degree = degConverter.getDegreeConverterPort().fahrenheitToCelsius(temp); System.out.println("Temperature in degrees is " + degree); Compiling and Running the Client After you create the client, you need to generate portable artifacts required to compile the client and then compile the client. You can then run the client. An ant task is provided in the sample package to perform these steps. See the section Running the Sample Code for details. Running the Sample Code A sample package accompanies this tip. To install and run the sample: Download the sample package and extract its contents. You should now see a newly extracted directory <sample_install_dir>/webservicesrefs-techtip, where <sample_install_dir> is the directory where you installed the sample package. For example, if you extracted the contents to C: on a Windows machine, then your newly created directory should be at C:webservicesrefs-techtip. If you haven’t already done so, download GlassFish v2 UR1. Change to the webservicesrefs-techtip directory and set AS_HOME in the build.xml file to point to the location where you installed GlassFish. For example, if GlassFish is installed in a directory name mydir/glassfish, set AS_HOME as follows: <property name="AS_HOME" value="/mydir/glassfish"/> Start GlassFish by entering the following command: <GF_install_dir>/bin/asadmin start-domain domain1 where is the directory in which you installed GlassFish. Execute the following command: ant server This ant task target builds the server-side classes for the web services, that is, it compiles the classes, generates the portable artifacts, and packages the war and EJB jar files. It then deploys the web services to GlassFish. The WSDL files for the web services are published to: https://localhost:8080/weatherservice/GetWeather?wsdl https://localhost:8080/DegreeConverterService/DegreeConverter?wsdl Execute the following command: ant client This ant task target runs the wsimport utility to generate the client-side artifacts and then compiles and runs the client. You should see the following in the response: runclient: runclient-windows: runclient-non-windows: [exec] Invoking the weather service for zip 90210.. [exec] Temperature for zip 90210 is 80.0 [exec] Invoking the degree converter service for zip 90210.. [exec] Temperature in degrees is 36.0 BUILD SUCCESSFUL Note: To run the sample with JDK 6 prior to the JDK 6 Update 4 release, you need use the endorsed override mechanism by copying the webservices-api.jar file from <GF_install_dir>/lib/endorsed, where <GF_install_dir> is the directory where you installed GlassFish, to <jdk_install_dir>/jre/lib/endorsed, where <jdk_install_dir> is the directory in which the runtime software is installed. If you run the sample with JDK 6 Update 4 or later, you do not need to use the override mechanism. About the Author Bhakti Mehta is a Member of Technical Staff at Sun Microsystems. She is currently working on the implementation of JSR 109, the Web Services for Java EE specification. Previously she has worked on WS-Reliable Messaging to interoperate with the Microsoft Windows Communication Foundation, as well as the JAXB and JAXP Reference Implementations. She has a Masters Degree in Computer Science from the State University of New York at Binghamton and a Bachelors Degree in Computer Engineering from Mumbai University. —————————————————————————————————————————————————————————- Connect and Participate With GlassFish Try GlassFish for a chance to win an iPhone. This sweepstakes ends on March 23, 2008. Submit your entry today. Technology Industry