Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Web services interoperability, Part 2

Do it yourself

Andre Tost, Solution Architect, EMC
André Tost works as a Solution Architect in the WebSphere Business Development group, where he helps IBM's Strategic Alliance partners integrate their applications with WebSphere. His special focus is on Web services technology throughout the WebSphere product family. Before his current assignment, he spent ten years in various development and architecture roles in IBM software development, most recently for the WebSphere Business Components product. Originally from Germany, he now lives and works in Rochester, Minnesota. In his spare time, he likes to spend time with his family and play and watch soccer whenever possible.

Summary:  In Part 1 of this series, André Tost presented a demo application that was implemented across several vendors' web services environments and highlighted one very important aspect of web services technology: interoperability. In this article, he will show you how you can download a version of the application for IBM WebSphere and run it on your own local computer. The application runs both in connected and non-connected modes, meaning that you can interact with other service implementations that exist on the Internet, or you can run all of the services locally. He will also show you how you can import the application into the IBM WebSphere Studio Application Developer and run and debug it from within the tool.

Date:  01 Jan 2003
Level:  Introductory
Also available in:   Korean

Activity:  3465 views
Comments:  

Introduction

In the first article, you learned that the demo application implements a buyer-seller scenario. It consists of a number of roles, which are all designed as web services, with service interfaces defined in WSDL. Only the Customer role is not implemented as a web service, because it serves as the client for your application. Figure 1 shows this structure.


Figure 1. Roles and operations
Roles and operations

(Figure 1 is Copyright © XMethods and has been used with permission).

The application that I will describe in this article implements the roles Supplier, Warehouse, and Bank as web services running on WebSphere. The business logic of these services is represented by JavaBeans. The Customer role is implemented as a set of Java Server Pages (JSPs). Both the service implementations and the JSPs are bundled into one Web module. Besides the Java and JSP code, this Web module also contains a number of configuration files as well as the WSDL service definitions for all services. Finally, this Web module is packaged into a J2EE Enterprise Archive (EAR) file. You can install this EAR file on any J2EE compliant application server. Before continuing, you should download the complete EAR file, including source code from the demo home page.

Figure 1 also shows that some of the services act as clients to other services. For example, the Supplier service uses the Warehouse service to ensure that an order can be fulfilled. Each service implementation uses a mapping file to identify where the services it uses can be found. This mechanism was described in the previous article. (See Resources.)

Web services in Axis/JAX-RPC

Before you start importing and running the actual code, let me walk you through a little bit of theory. This will help you to understand the content of the application package.

The web services in this application have been implemented following the JAX-RPC specification. This means that each <portType> element that is defined in the WSDL document is mapped to a Java interface. For example, the Supplier web service is mapped to an interface called net.xmethods.www.ISupplierSoap. The interface name is taken from the <portType> name ('ISupplierSoap' in this case), and the package name from the namespace of the <portType> element in WSDL. However, the specification does not mandate how the namespace to package name mapping is done. Listing 1 shows the ISupplierSoap interface, which was generated from the WSDL service definition using the Apache Axis WSDL2Java tool.


Listing 1. ISupplierSoap interface
		
package net.xmethods.www;

public interface ISupplierSoap extends java.rmi.Remote {
    public java.lang.String sendPO(net.xmethods.www.PO po)
      throws java.rmi.RemoteException;
    public void shipConfirm(java.lang.String customerID, java.lang.String poNumber) 
      throws java.rmi.RemoteException;
    public java.lang.String 
    getPOStatus(java.lang.String customerID, java.lang.String poNumber) 
      throws java.rmi.RemoteException;
    public net.xmethods.www.Invoice 
    getInvoice(java.lang.String customerID, java.lang.String poNumber) 
      throws java.rmi.RemoteException;
    public net.xmethods.www.Catalog getCatalog() throws java.rmi.RemoteException;
}

Note that the JAX-RPC specification also states that each method in the interface must throw java.rmi.RemoteException.

The Apache Axis WSDL2Java tool also generates a number of additional classes:

  • The net.xmethods.www.ISupplierSoapImpl class contains the actual implementation of the service. It implements the service interface class.
  • The net.xmethods.www.ISupplierSoapStub class also implements the service interface, but acts as a proxy to the actual service. It is used by a client.
  • The net.xmethods.www.SupplierService class represents the <service> element in the WSDL document (it is also called the 'generated service interface'). It contains a number of methods that make it easier for a client to obtain a client side stub to the service. Its methods make it possible to define the actual endpoint location of the service at runtime.
  • The net.xmethods.www.SupplierServiceLocator class implements the generated service interface above.

You will find these classes for all of the services in our application.


Running the application in WebSphere Studio Application Developer

In the following sections, I will show you how you can install the application in WebSphere Studio Application Developer (Application Developer). You can run and debug it in the WebSphere Test Environment within the tool, or on a stand alone application server, which I will describe towards the end of the article.

To import the application into Application Developer, open the tool in the J2EE perspective (Figure 2). Then select the File -> Import option.


Figure 2. Application Developer Import
Application Developer Import

Click on the 'Next' button. In the next dialog, specify the location where you downloaded the EAR file with the application. Enter 'WSIDEAR' as the Enterprise Application project name, as shown in Figure 3.


Figure 3. EAR Import
EAR Import

Now click on 'Finish', which will start the import process. After completion, you will see that a new Enterprise Application, named wsidEAR, has been created, which contains one Web module called wsid.war. The Web module is represented by a Web project called 'wsid' (see Figure 4).


Figure 4. wsid.war
wsid.war

Before you can have a closer look at the new Web project, you have to make one change to its build path properties, in order to remove one compile problem. You have to add an XML parser library to the classpath; you will use the Apache Xerces library here, which is already included with WebSphere. To make this change, open a 'web' perspective in Application Developer and select the 'wsid' Web project. Click on the right mouse button and select 'Properties' from the pop-up menu. Then click on the 'Java Build Path' entry on the left and select the Libraries tab. Your window should now look like Figure 5.


Figure 5. Java Build Path
XML error: The image is not displayed because the width is greater than the maximum of 580 pixels. Please decrease the image width.

Now click on the 'Add External JARs' button and add the xerces.jar file from the \plugins\org.apache.xerces directory in your WebSphere Studio install directory. After you have added the jar file, click on OK in the project properties window. This will resolve the compile problem.

Running the application

There are some configuration options that let you control how the application is run, and I will explore these in a minute, but first let's simply run the application as is. To do so, open the Web perspective in Application Developer, right click the 'wsid' Web project and select 'Run on Server' from the pop-up menu as shown in Figure 6.


Figure 6. Run on Server
Run on Server

This will publish the new application to the WebSphere Test Environment. After that, the server is started and the application is activated. Your Web module is defined with a base context root definition of '/wsid', which means it can be accessed as http://localhost:8080/wsid/. The tool will start a browser window and load this URL (causing the welcome.jsp page to be loaded, because that is the default starting page for this Web module). The result is shown in Figure 7.


Figure 7. WebSphere Test Environment
XML error: The image is not displayed because the width is greater than the maximum of 580 pixels. Please decrease the image width.

Don't worry if you see several exception messages in the Console window -- this will be explained shortly. The application itself should work as you have seen it on the IBM developerWorks server described in the first article, so I won't cover it in detail here again. The only difference is that you are running the services locally on your machine instead of on the IBM server!

Deploying a service

In order to make a service implementation available on the application server, you must make this service known to the Axis runtime. Without going into too much detail, this process involves storing information about a service, its interface, its ID, and its implementation class in a file that the Axis runtime uses to resolve incoming requests to the right target.

There are two ways of 'deploying' a service into Axis. One is to use a JSP-base administration application that lets you specify all of the required values through a user interface. The second approach is to do the same thing programmatically, using a class that Axis provides called org.apache.axis.client.AdminClient. You will use this second option in your application and deploy the services on the fly whenever the application is first used.

The first page that is loaded as part of the application is the welcome.jsp page, and thus the code for deployment of the supported services is placed in this file. All of the required values are passed to the Axis runtime in the form of a file with the extension .wsdd. In other words, there is one such file for each service. Listing 2 contains an example which shows the deployment file for the Bank service.


Listing 2. Bank service deployment file
		
<deployment
    xmlns="http://xml.apache.org/axis/wsdd/"
    xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

  <!-- Services from bankService WSDL service -->

  <service name="bank" provider="java:RPC" style="document">
      <parameter name="wsdlTargetNamespace" value="http://www.xmethods.net/ws-demo/"/>
      <parameter name="wsdlServiceElement" value="bankService"/>
      <parameter name="wsdlServicePort" value="bank"/>
      <parameter name="className" value="net.xmethods.www.IBankSoapImpl"/>
      <parameter name="wsdlPortType" value="IBankSoap"/>
            <operation name="charge" qname="operNS:chargeRequest" 
                    xmlns:operNS="http://www.xmethods.net/ws-demo/" returnQName="retNS:chargeResponse"         
                    xmlns:retNS="http://www.xmethods.net/ws-demo/" 
                    returnType="rtns:>chargeResponse" 
                    xmlns:rtns="http://www.xmethods.net/ws-demo/" >
      <parameter qname="pns:chargeRequest" 
                    xmlns:pns="http://www.xmethods.net/ws-demo/" type="tns:>chargeRequest" 
                    xmlns:tns="http://www.xmethods.net/ws-demo/"/>
      </operation>
      <parameter name="allowedMethods" value="charge"/>

      <typeMapping
        xmlns:ns="http://www.xmethods.net/ws-demo/"
        qname="ns:>chargeResponse"
        type="java:net.xmethods.www.ChargeResponse"
        serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
        deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
        encodingStyle=""
      />
      <typeMapping
        xmlns:ns="http://www.xmethods.net/ws-demo/"
        qname="ns:>chargeRequest"
        type="java:net.xmethods.www.ChargeRequest"
        serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
        deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
        encodingStyle=""
      />
  </service>
</deployment>

Deploying this information through the org.apache.axis.clientAdminClient class is fairly straightforward; Listing 3 shows the code extracted from the welcome.jsp file.


Listing 3. Code from welcome.jsp
		
    // auto deploy the web services
    if (!init) {
        // deploy
        AdminClient ac = new AdminClient();
        String[] wsdds = {"warehouse.wsdd", "bank.wsdd", "supplier.wsdd", "logger.wsdd"};
        String[] args = new String[3];
        for (int i=0; i<wsdds.length; i++) {
	        args[0] = "-l";
	        args[1] = net.xmethods.www.Data.local + "services/AdminService";
            args[2] = getServletContext().getRealPath(wsdds[i]);
            try {
                ac.process(args); 
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        init = true;
    }

The Admin service is itself deployed as a web service. It is preinstalled into the Axis runtime. After running this code, the services can be accessed locally on your application server.

Using remote services

The application is set up so that it can be run with or without access to the Internet. By default, (that is, after you installed the EAR file without change), it runs without requiring any remote resources. However, since this is an interoperability demonstration, you want to be able to test multiple remote web services with it.

At startup time, the application loads information about available services and their endpoints from a configuration file called ROLES.php. Typically, this configuration file is located on a server at the XMethods web site, namely at http://www.xmethods.net/wsid/online/app/ROLES.php. However, to allow you to make changes to your local configuration (you don't have write access to the file at XMethods), the code will check if a local copy of this file exists, and if it does, it will use this local file. The application looks for this file in the '/app' directory of the Web module, and if you installed the EAR file for this application, you can find it there, with only the local service configured. This is why you can run the application without connectivity to the Internet.

Once you rename this file and restart the Web application (you have to restart the application, reloading the welcome.jsp is not sufficient), and you are connected to the Internet, you will use the configuration file from the XMethods server. You will note this change when you run the application in that you will have more combinations of suppliers and customers available in the drop-down list on the first page of the application. You are then using the endpoints as defined in the remote configuration file. The only exception is the 'local' supplier and customer roles, which are always using the local application server. In the 'local' case, you will still access the supplier through its web services interface, even though the customer application and the service run on the same server in this case.

You can manipulate the mapping of warehouses and banks to certain suppliers and customers too. These mappings are read from files called xml\CREDITMAPS.xml and xml\WAREHOUSEMAPS.xml. If you rename the local copies of these files and restart the Web application, you will use the remote copies of the files at the XMethods web site. Feel free to make changes to the content of these files and see what, if any, impact this has on the application.

Finally, the content of the local product catalog is taken from a file called xml\CATALOG.xml. Normally you won't change the content of this file, the local copy mainly exists to allow you to run the application without being connected to the Internet.

Debugging and tracing the application

If you want to step through certain areas of the code, you can do so by setting breakpoints and reloading the application. Make sure that you have started the server in debug mode. Obviously, you can only debug services that you run locally.

The application will also write logs of certain events to a log file, which you can use for tracing purposes. Logging is also done via a web service, namely the Logger service. This service is different from the others in that only one real implementation of this service exists on the XMethods server. Its URL is http://www.xmethods.net/wsid/online/log. You will not find a configuration option for this endpoint in the ROLES.php file as it is hardcoded in the application. You can view the log file at the XMethods site under http://www.xmethods.net/wsid/online/log.cgi.

If you run your application locally, without a connection to the Internet, you cannot access this service, and thus cannot trace what is going on. To allow tracing when running without a connection, the application contains a simple log service that will print log requests to the screen (the implementation class for this is net.xmethods.www.ILoggerImpl). This log service is deployed to the server together with the other services, as part of the code that exists in the welcome.jsp file. However, some log requests are already sent by the application before the local log service is deployed. This leads to the exception messages that you might have noticed when you ran the application for the first time.

Whether the local or the remote log service is used depends on a flag that is set in the net.xmethods.www.Data class called 'useLocalLogger'. If set to true, the local logger service is accessed, and if you change it to false, it will go to the XMethods logger service.

Another method of tracing what data are exchanged between the services is the 'tcpmon' tool that comes with Apache Axis. This tool allows you to trace data packages that are exchanged over HTTP. You use it by directing your service requests to the address and port under which the tool was started, and then forward the requests to the actual endpoint from there. The local ROLES.php file comes in handy at this point, because it lets us change the port under which the local service is available.

To start the tcpmon tool from within Application Developer, find the class org.apache.axis.utils.tcpmon in the axis.jar file (which is stored in our application in the \WEB-INF\lib directory). Select the class and use the 'Run' icon to start this class as a Java Application, as shown in Figure 8.


Figure 8. tcpmon from Application Developer
tcpmon from Application Developer

Once the tool has started, specify a new port to receive requests (for example, 12345) and forward them to the actual service endpoint, namely 'localhost' as the hostname and 8080 for the port (this is where the WebSphere Test Environment runs), as shown in Figure 9.


Figure 9. tcpmon from Application Developer
XML error: The image is not displayed because the width is greater than the maximum of 580 pixels. Please decrease the image width.

Click on the Add button to add this new listener. Now change the endpoint address of the ROLES.php file to use the same port you have used in the tcpmon tool, 12345 in our case. The updated file now looks like Listing 4.


Listing 4. ROLES.php
		
<roles updatecode="20021027083911" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:noNamespaceSchemaLocation="ROLES.xsd">
   <role participant="ibm">
              <type>customer</type>
              <id>ibm-customer</id>
   </role>
   <role participant="ibm">
              <type>supplier</type>
              <id>ibm-supplier</id>
              <endpoint>http://localhost:12345/wsid/services/supplier</endpoint>
    </role>
    <role participant="ibm">
              <type>bank</type>
              <id>ibm-bank</id>
              <endpoint>http://localhost:8080/wsid/services/bank</endpoint>
    </role>
    <role participant="ibm">
              <type>warehouse</type>
              <id>ibm-warehouse</id>
              <endpoint>http://localhost:8080/wsid/services/warehouse</endpoint>
    </role>
</roles>

Now start the application in the test environment, and you will notice that all requests to the Supplier service are now routed through the tcpmon tool, as shown in Figure 10.


Figure 10. Requests routed through tcpmon
XML error: The image is not displayed because the width is greater than the maximum of 580 pixels. Please decrease the image width.

This way, you can examine the actual SOAP messages that are sent to and from the service. Note that in this example, you only monitor the Supplier service. The tcpmon tool lets you set up additional listeners, and by configuring these in the ROLES.php file, you can separately monitor all of the services in the application.


Installing the application in WebSphere Application Server Version 4

So far, I have shown you how you can install, run, and debug the application in the WebSphere Test Environment of WebSphere Studio Application Developer. If you want to install and run it in a separately installed application server, you need to make one change to the code. This is due to the fact that you need to define under which URL the locally deployed services can be accessed. The original EAR file contains code that assumes that it will be installed under port 8080, which is what the test environment uses by default. If you run your WebSphere Application Server with a plugin and a web server on port 80, which is the most common case, then you need to change the static 'local' variable in the net.xmethods.www.Data class to http://localhost:80/wsid. Once you have made that change, you can export the application as an EAR file from WebSphere Studio Application Developer and directly install it into your WebSphere Application Server.

The application has also been successfully tested and run in both Application Developer version 5 and WebSphere Application Server version 5, so if you happen to run those newer versions of the product, feel free to install and run it there.


Acknowledgements

Sam Ruby developed the original IBM implementation of this application for the Web Services One conference in Boston. Richard Bonneau from IONA, David Rees from Amberpoint and Hoa Nguyen from webMethods own their respective companies' implementation and were very helpful in testing the application. Finally, Tony Hong from XMethods was the initiator of this activity and hosts the demonstration's homepage at http://www.xmethods.net/wsid/online.


Resources

About the author

André Tost works as a Solution Architect in the WebSphere Business Development group, where he helps IBM's Strategic Alliance partners integrate their applications with WebSphere. His special focus is on Web services technology throughout the WebSphere product family. Before his current assignment, he spent ten years in various development and architecture roles in IBM software development, most recently for the WebSphere Business Components product. Originally from Germany, he now lives and works in Rochester, Minnesota. In his spare time, he likes to spend time with his family and play and watch soccer whenever possible.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and web services
ArticleID=11752
ArticleTitle=Web services interoperability, Part 2
publish-date=01012003
author1-email=atost@us.ibm.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Try IBM PureSystems. No charge.

Special offers