In a discussion on interoperability of modern day enterprise applications, Web Services naturally joins the party. Web Service technologies provides J2EE with an opportunity to become truly inter operable with any other system. This is because, Web service technologies are platform-agnostic; in other words, the medium used to communicate is not specific to any combination of programming language, operating system, and hardware.

After reading this article you should be able to deploy web services in the form of servlets in Apache Geronimo and access them with different sorts of clients. This will be a good starting point to web services in the Geronimo server and to getting familiar with cumbersome JAX-RPC technologies.

This article is organized into the following sections : -

Overview of Web Services Features in Geronimo

According to J2EE 1.4 standard there are several options for consuming web services :

  1. A servlet may act as a Web service.
  2. A session bean may act as a Web service.
  3. Any J2EE component may act as a Web service client, using a reference to an external Web service.

Apache Geronimo supports JAX-RPC based Web services according to J2EE 1.4 standard. This means that a Web service application developed for the Geronimo should run on any application server. But JAX-RPC is a technology that is cumbersome and difficult to deal with.

Application Overview

The sample application referred in this article is a simple calculator which performs addition of two integers. The client application referred here is not a J2EE application, which will call a web service to carry out application functionality. Web service is exposed as a servlet in the Geronimo application server.

The following figure illustrates overview of calculator application :

The Web services deployed in the server uses CalculatorService interface as service end point interface. The important thing in this interface is it extends java.rmi.Remote interface and throws java.rmi.RemoteException from exposed methods.

CalculatorService.java
public interface CalculatorService extends java.rmi.Remote
{
   public int addition( int x,int y ) throws java.rmi.RemoteException;
}

The service implementation class for the web service is CalculatorServiceServlet. It implements all the methods in the service end point interface. This class will be exposed as a servlet in the web.xml file eventhough it is not necessary to extend javax.servlet.Servlet class.

CalculatorServiceServlet.java
public class CalculatorServiceServlet {	
	public int addition(int x, int y){
		return x + y;
	}	
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:calc="urn:geronimo-samples" 
		xmlns="http://java.sun.com/xml/ns/j2ee"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
		version="2.4">
	<servlet>
		<display-name>CalculatorServiceServlet</display-name>
		<servlet-name>CalculatorServiceServlet</servlet-name>
		<servlet-class>
			org.apache.geronimo.samples.calc.web.CalculatorServiceServlet
		</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>CalculatorServiceServlet</servlet-name>
		<url-pattern>/calculator</url-pattern>
	</servlet-mapping>
	
</web-app>

Note the dependencies section of the geronimo-web.xml file. Those dependencies are mandotory to deploy web services in your web archive.

geronimo-web.xml
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1" xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.1">
  <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1">
    <dep:moduleId>
      <dep:groupId>org.apache.geronimo.samples</dep:groupId>
      <dep:artifactId>Calculator</dep:artifactId>
      <dep:version>1.0</dep:version>
      <dep:type>car</dep:type>
    </dep:moduleId>
    <dep:dependencies>
	<dep:dependency>
           <dep:groupId>geronimo</dep:groupId>
           <dep:artifactId>geronimo-webservices</dep:artifactId>
           <dep:type>jar</dep:type>
        </dep:dependency>
	<dep:dependency>
           <dep:groupId>geronimo</dep:groupId>
           <dep:artifactId>geronimo-axis</dep:artifactId>
           <dep:type>jar</dep:type>
        </dep:dependency>
    </dep:dependencies>	
    <dep:hidden-classes/>
    <dep:non-overridable-classes/>
  </dep:environment>
 <context-root>/Calculator</context-root> 
</web-app>

To deploy a JAX-RPC based web service, three additional configuration files have to be added into your archive. Those are WSDL file , jaxrpc-mapping file and web service description file. Those configuration files can be found under the config/servlet folder of the application.

WSDL file describes about the web service as given in the below :

CalculatorServiceServlet.wsdl
<?xml version="1.0" encoding="UTF-8"?>

<definitions name="CalculatorServiceServlet" targetNamespace="urn:geronimo-samples" xmlns:tns="urn:geronimo-samples"
 xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
  <types/>
  <message name="CalculatorService_addition">
    <part name="int_1" type="xsd:int"/>
    <part name="int_2" type="xsd:int"/>
  </message>
  <message name="CalculatorService_additionResponse">
    <part name="result" type="xsd:int"/>
  </message>
  <portType name="CalculatorService">
    <operation name="addition" parameterOrder="int_1 int_2">
      <input message="tns:CalculatorService_addition"/>
      <output message="tns:CalculatorService_additionResponse"/>
     </operation>
  </portType>
  <binding name="CalculatorServiceBinding" type="tns:CalculatorService">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
    <operation name="addition">
      <soap:operation soapAction=""/>
      <input>
        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded"
 namespace="urn:geronimo-samples"/>
      </input>
      <output>
        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded"
 namespace="urn:geronimo-samples"/>
      </output>
    </operation>
  </binding>
  <service name="CalculatorServiceServlet">
    <port name="CalculatorServicePort" binding="tns:CalculatorServiceBinding">
      <soap:address location="REPLACE_WITH_ACTUAL_URL"/>
    </port>
  </service>
</definitions>

jaxrpc-mapping file will map the information with service implementation.

jaxrpc-mapping.xml
<?xml version="1.0" encoding="UTF-8"?>
<java-wsdl-mapping xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
version="1.1" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee    
http://www.ibm.com/webservices/xsd/j2ee_jaxrpc_mapping_1_1.xsd">
  <package-mapping>
    <package-type>org.apache.geronimo.samples.calc</package-type>
    <namespaceURI>urn:geronimo-samples</namespaceURI>
  </package-mapping>
  <package-mapping>
    <package-type>org.apache.geronimo.samples.calc</package-type>
    <namespaceURI>urn:geronimo-samples</namespaceURI>
  </package-mapping>
  <service-interface-mapping>
	<service-interface>
		org.apache.geronimo.samples.calc.CalculatorService
	</service-interface>
    <wsdl-service-name xmlns:serviceNS="urn:geronimo-samples">serviceNS:CalculatorServiceServlet</wsdl-service-name>
    <port-mapping>
      <port-name>CalculatorServicePort</port-name>
      <java-port-name>CalculatorServicePort</java-port-name>
    </port-mapping>
  </service-interface-mapping>
  <service-endpoint-interface-mapping>
    <service-endpoint-interface>org.apache.geronimo.samples.calc.CalculatorService</service-endpoint-interface>
    <wsdl-port-type xmlns:portTypeNS="urn:geronimo-samples">portTypeNS:CalculatorService</wsdl-port-type>
    <wsdl-binding xmlns:bindingNS="urn:geronimo-samples">bindingNS:CalculatorServiceBinding</wsdl-binding>
    <service-endpoint-method-mapping>
      <java-method-name>addition</java-method-name>
      <wsdl-operation>addition</wsdl-operation>
      <method-param-parts-mapping>
        <param-position>0</param-position>
        <param-type>int</param-type>
        <wsdl-message-mapping>
          <wsdl-message xmlns:wsdlMsgNS="urn:geronimo-samples">wsdlMsgNS:CalculatorService_addition</wsdl-message>
          <wsdl-message-part-name>int_1</wsdl-message-part-name>
          <parameter-mode>IN</parameter-mode>
        </wsdl-message-mapping>
      </method-param-parts-mapping>
      <method-param-parts-mapping>
        <param-position>1</param-position>
        <param-type>int</param-type>
        <wsdl-message-mapping>
          <wsdl-message xmlns:wsdlMsgNS="urn:geronimo-samples">wsdlMsgNS:CalculatorService_addition</wsdl-message>
          <wsdl-message-part-name>int_2</wsdl-message-part-name>
          <parameter-mode>IN</parameter-mode>
        </wsdl-message-mapping>
      </method-param-parts-mapping>
      <wsdl-return-value-mapping>
        <method-return-value>int</method-return-value>
        <wsdl-message xmlns:wsdlMsgNS="urn:geronimo-samples">wsdlMsgNS:CalculatorService_additionResponse</wsdl-message>
        <wsdl-message-part-name>result</wsdl-message-part-name>
      </wsdl-return-value-mapping>
    </service-endpoint-method-mapping>
  </service-endpoint-interface-mapping>
</java-wsdl-mapping>

webservices.xml file gives the locations of WSDL and jaxrpc-mapping files to services. The developer needs to have a good understanding of this file than the others given above.

webservices.xml
<?xml version="1.0" encoding="UTF-8"?>
<webservices xmlns="http://java.sun.com/xml/ns/j2ee" version="1.1">
 <webservice-description>
  <webservice-description-name>
		CalculatorServiceServlet
  </webservice-description-name>
  <wsdl-file>WEB-INF/wsdl/CalculatorServiceServlet.wsdl</wsdl-file>
  <jaxrpc-mapping-file>WEB-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file>
  <port-component>
	  <port-component-name>CalculatorServicePort</port-component-name>
	  <wsdl-port>CalculatorServicePort</wsdl-port>
	  <service-endpoint-interface>
		org.apache.geronimo.samples.calc.CalculatorService
	  </service-endpoint-interface>
	  <service-impl-bean>
	  <servlet-link>CalculatorServiceServlet</servlet-link>
	  </service-impl-bean>
  </port-component>
 </webservice-description>
</webservices>

How to access the Web service deployed in the server in tool independent manner? CalculatorClient.java file demonstrates how to achieve this function.

CalculatorClient.java
	
String urlstr   = "http://localhost:8080/Calculator/calculator?wsdl";

URL url =  new URL(urlstr);

QName qname = new QName("urn:geronimo-samples","CalculatorServiceServlet");

ServiceFactory factory = ServiceFactory.newInstance();
Service  service = factory.createService(url, qname);
			
CalculatorService calc = (CalculatorService)service.getPort(CalculatorService.class);
			
int sum = calc.addition(x, y);
			
System.out.println("Sum of "+x+" and "+y+" is "+sum);

Tools used

The tools used for developing and building the Calculator sample application are:

Java Web Services Developer Kit

The Java Web Services Developer Pack (Java WSDP) is used for simplified development of secure and interoperable Web services applications. The Java WSDP is an integrated toolkit for developing, building, testing, and deploying web services, as well as web and XML-based applications. WSDP has been used to generate jaxrpc-mapping and WSDL files for the Calculator application. WSDP can be downloaded from the following URL:
http://java.sun.com/webservices/jwsdp/index.jsp

Eclipse

The Eclipse IDE was used for development of the sample application. This is an extremely powerful and popular open source development tool. Integration plug-ins are available for Geronimo. Eclipse can be downloaded from the following URL:
http://www.eclipse.org

Apache Ant

Ant is a pure Java build tool. It is used for building the Calculator application. Ant can be downloaded from the following URL:
http://ant.apache.org

Back to Top

Configuring, Building and Deploying Sample Application

Download the Calculator application from the following link:
Calculator

After extracting the zip file, the Calculator directory is created.

Configuring

Calculator application comes with an Ant script to help users to build from source code. It has to be properly configured before using it to build from source. build.properties file in the config directory has to be modified according to your environment. Set the correct path to the <geronimo_home> directory.

This build script depends on Geronimo 1.1.1. Also make sure to use "/" as you directory separator in Windows environment when you are setting the <geronimo_home> directory.

Building

Compile Source Code

Use a command prompt and navigate to the Calculator directory and just give ant compile-web command to build. It will compile the source code into the Calculator/releases/war folder. From these compiled classes we are going to create jaxrpc-mapping and WSDL.

Generate WSDL and jaxrpc-mapping files

We have tested this application with Java WSDP 2.0 and it needs JDK 1.5

If you are not happy with given configuration files in Calculator/config/servlet and want to do some experiments, use the Java WSDP to generate jaxrpc-mapping and WSDL files. Follow these steps to generate those files.

  1. Copy Calculator/config/servlet/config-interface.xml to the WSDP_HOME/jaxrpc/bin.
  2. Create a folder called build under WSDP_HOME/jaxrpc/bin and copy classes folder from Calculator/releases/ear/war/classes.
  3. From command prompt issue the following command in WSDP_HOME/jaxrpc/bin.
    Linux
    ./wscompile.sh -define -mapping build/jaxrpc-mapping.xml -d build -nd build -classpath build config-interface.xml
    Windows
    wscompile -define -mapping build/jaxrpc-mapping.xml -d build -nd build -classpath build config-interface.xml
  4. Previous step will generate both WSDL and jaxrpc-mapping file in the WSDP_HOME/jaxrpc/bin/build folder. The next step is to edit jaxrpc-mapping.xml file according to our services. Change the service-interface to org.apache.geronimo.samples.calc.CalculatorService.
  5. Now copy those files to the Calculator/config/servlet folder.
  6. Remove the build file from WSDP_HOME/jaxrpc/bin.

Create WAR file

To create WAR file use ant command while you are in the Calculator folder, from command prompt. This will create Calculator.war file under the Calculator/releases folder.

Deploying

Deploying sample application is pretty straight forward, since we are going to using Geronimo Console.

  1. Scroll to Deploy New from the Console Navigation panel.
  2. Load Calculator.war from Calculator/releases folder in to the Archive input box.
  3. Press Install button to deploy application in the server.

Testing of the Sample Application

To test this sample application we are going to run the CalculatorClient application as given below.

ant run-client -Dval1=<num1> -Dval2=<num2>

lsf@lsf-laptop:~/workspace/Calculator$ ant run-client -Dval1=1 -Dval2=12
Buildfile: build.xml
run-client:
     [java] Working directory ignored when same JVM is used.
     [java] Sum of 1 and 12 is 13

Summary

This article has shown, how to deploy a simple web service in J2EE specific manner. The highlights of this article :

  • As a J2EE 1.4 certified application server Apache Geronimo supports JAX-RPC based Web service deployment.
  • Deploy simple Web service in Geronimo as a servlet.
  • Generate Web service related configuration files from Java WSDP.
  • Access a deployed Web service from a client other than J2EE.
  • No labels