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]

Using SOAP with Attachments in WebSphere Studio Application Developer

Kyle Brown (mailto:brownkyl@us.ibm.com), Senior Technical Staff Member, IBM Software Services for WebSphere
Kyle Brown is a Senior Technical Staff Member with IBM Software Services for WebSphere. Kyle provides consulting services, education, and mentoring on object-oriented topics and Java 2 Enterprise Edition (J2EE) technologies to Fortune 500 clients. He is a co-author of Enterprise Java Programming with IBM WebSphere, the WebSphere AEs 4.0 Workbook for Enterprise Java Beans, 3rd Edition, and The Design Patterns Smalltalk Companion. He is also a frequent conference speaker on the topics of Enterprise Java, OO design, and design patterns. You can reach Kyle at brownkyl@us.ibm.com.

Summary:  The W3C SOAP with Attachments specification lets you send complex binary files together with SOAP messages in a Web Services environment.

Date:  11 Dec 2002
Level:  Intermediate

Activity:  2788 views
Comments:  

© Copyright International Business Machines Corporation 2002. All rights reserved.

Introduction

SOAP with Attachments [W3C] is a useful tool for conveying binary or "raw" XML data together with SOAP messages in a Web Services environment. It can help you, for example, if you need to use Web Services to transfer the contents of a binary file, or if you need to convey a large binary object like a JPEG or CAD drawing along with a SOAP message containing instructions for processing the binary information.

SOAP with attachments gets around some of the limitations of the SOAP specification in dealing with binary data -- since all data in a SOAP message must be represented as XML, which means that binary data sent inside a SOAP envelope needs to be encoded as text so that it can be included within the XML. However, this makes the XML extremely difficult to read, as the huge base-64 encoded segments complicate debugging. So, SOAP with attachments lets you circumvent these problems by using multipart MIME messages to carry both the SOAP envelope and the binary file as MIME messages.

A great article by Joshy Joseph entitled Handling attachments in SOAP describes Apache support for SOAP with Attachments. However, implementing the concepts outlined in this article in WebSphere Studio Application Developer 4.0.X (hereafter called Application Developer) has proven to be challenging, because Application Developer has a few limitations in its support for SOAP with Attachments.

First, the Web Services Wizard in Application Developer does not support the MIME extension bindings in WSDL. For instance, if you take the WSDL files included in Joshy's article and try to import them into the Application Developer Web Services Wizard, you will get the following error message:



Failing in that path, most developers then turn to the Apache documentation and discover the support (hinted at in Joshy's article) for serializing javax.activation.DataHandlers. For those unfamiliar with the JavaBeans Activation Framework (JAF) [Sun], a DataHandler is a way of wrapping an arbitrary data source so that it can be sent in a MIME message. The JAF framework is an important part of the support for the JavaMail API, and it is also a key constituent of the SOAP with Attachments support in Apache SOAP. According to the Apache SOAP documentation [Apache] all you have to do when using RPC-style SOAP messages is to use the special serializers for DataHandlers (the MimePartSerializer) that are provided by Apache SOAP.

However, even though SOAP with attachments has been supported in Apache SOAP through the special MimePartSerializer since Apache SOAP 2.1, the Web Services Wizard in Application Developer also does not provide automatic support for the javax.activation.DataHandler mappings in Apache SOAP. If you try to include a javax.activation.DataHandler as a parameter or return value from a method, and then run the Application Developer Web Services Wizard, then you will find the following mappings in the Java-to-XML mappings screen:



Note the profusion of classes in the list of classes to map -- and this is for a method that has only a String as a parameter and a javax.activation.DataHandler as a return value! In fact, what is happening is that the Wizard is trying to treat the DataHandler as a Java bean, and is thus breaking down the DataHandler into its constituent parts. In fact, even if you click Next on this screen, the Wizard will fail on the following screen. (This problem continues in Application Developer 5.0 Early Availability version, though it should be fixed in a later version.)

What we need to do is to "trick" the Application Developer Web Services Wizard into doing what we want -- build most of the Web Service for us, and then to edit the code and configuration files that it generates so that we can take advantage of the SOAP with Attachments support.


What the Web Services Wizard gives us

Why do we need to do this? Wouldn't it just be easier to build this all by hand and avoid the Wizard? Not really. The Wizard does a lot for you when you are building RPC-style Web Services from a Java bean or EJB (this is described in more depth in [Wizardry]):

  • It generates the appropriate Apache SOAP deployment descriptor (an ISD file) for the Web Service.
  • It can generate a "proxy" class that a client can use to invoke the Web service from a remote Java process. This class is a lot of code to create by hand, and because it's "boilerplate" code, it would be nice to have it generated automatically.
  • It can generate a "sample" JSP application that lets you test the Web Service.
  • It can generate a WSDL document that describes your Web service.
  • It updates that classpath of the Application Developer Web Project with additional references to the needed Apache SOAP classes. This is a subtle point, and one that can cause consternation to people just getting acquainted with Web Services in Application Developer. In particular, it adds the following entries into the .classpath file:
 
<classpathentry kind="var" path="SOAPJAR"/> 
<classpathentry kind="var" path="XERCESJAR"/> 
<classpathentry kind="lib" path="webApplication/WEB-INF/lib/soapcfg.jar"/> 
<classpathentry kind="lib" path="webApplication/WEB-INF/lib/xsd.bean.runtime.jar"/> 

While you could add all of these yourself, in my opinion it's much easier to let the Wizard to it. Even though in our case we won't be able to take advantage of all of these features (for instance, as we've seen, the Wizard doesn't currently support the WSDL tags for MIME encoding) it's still worthwhile to use the Wizard in most cases.


Tricking the Web Services Wizard

Let's start by examining the class we want to make into our Web Service:

 
package com.ibm.soap.attachments.demo; 
import javax.activation.*; 
public class FileTransferService { 
  public FileTransferService() {} 
  public javax.activation.DataHandler getFileNamed(String name) { 
    try { 
      FileDataSource datasource = new FileDataSource(name); 
      DataHandler handler = new DataHandler(datasource); 
      java.io.InputStream stream = handler.getInputStream(); 
      return handler; 
    } catch (Exception e) { 
      System.out.println("Exception caught on file " + name + " "+ e); 
      return null; 
    } 
  } 
} 

This is a very simple class that returns a DataHandler on a file named by the String parameter that is passed in. By making this class a Web Service, you can transfer the contents of any file from the server to the client. In other words, this service is basically doing FTP over SOAP. You could argue that there are better ways to do this (and you'd be right), but the point of this exercise is to show how to make Application Developer work with SOAP with Attachments, not to debate the merits of file transfer mechanisms.

Since we have found that the Application Developer Web Services Wizard will fail on processing the java.activation.DataHandler, we must instead temporarily change the return type to java.lang.Object in order to run the Web Services Wizard to create a Java bean Web Service. Then we can modify the ISD (deployment descriptor) file and the generated proxy file to correctly use the right serializer.

You can begin by creating a new Web project in Application Developer. I named my project SOAPWithAttachmentsProject and created it by using the Create a Web Project Wizard in Application Developer. I then added a Java package named com.ibm.soap.attachments.demo to the source folder of the project in the Java perspective using the New => Package Wizard from the context menu of the packages view.

Then I used New => Class, created the class FileTransferService, and then filled in the code above. It should compile without any red "x" marks indicating errors. Next, simply change the external interface (temporarily) by changing the method signature of the getFileNamed method from:

 
public javax.activation.DataHandler getFileNamed(String name) 
     to: 
public java.lang.Object getFileNamed(String name) 

Now your ready to run the Web Services Wizard. Switch over to the Web Perspective, select the FileTransferService file, and choose New => Web Service. In the Wizard's first page, select Generate a Proxy and Overwrite files without Warning and click Finish:



At this time Application Developer will publish the Web project to the default server and start the server (switching you to the Servers Perspective in the process). Go ahead and switch to the servers page in the Server Perspective and stop the server -- we're not ready to test this yet.

After stopping the server, make sure you go back and change the signature of the getFileNamed() method so that it returns a javax.activation.DataHandler -- we're now done with the Wizard and won't use it again.


Updating the Apache deployment descriptor

The next thing you need to do is change the ISD file so that the service will correctly use the MimePartSerializer to serialize instances of javax.activation.DataHandler. In the folder webApplication/WEB-INF/isd/java/com/ibm/soap/attachments/demo, examine the file FileTransferService.ISD:

 
<root> 
<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment" 
  id="http://tempuri.org/com.ibm.soap.attachments.demo.FileTransferService" 
  checkMustUnderstands="false"> 
  <isd:provider type="java" scope="Application" methods="getFileNamed"> 
    <isd:java class="com.ibm.soap.attachments.demo.FileTransferService" 
                 static="false"/> 
  </isd:provider> 
  <isd:mappings> 
    <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:x="http://www.filetransferservice.com/schemas/
                   FileTransferServiceRemoteInterface" 
    qname="x:java.lang.Object" 
    javaType="java.lang.Object" 
    xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanSerializer" 
    java2XMLClassName="org.apache.soap.encoding.soapenc.BeanSerializer"/> 
  </isd:mappings> 
</isd:service> 
</root> 

This ISD file is using the BeanSerializer to serialize any instances of type Object in the method getFileNamed. You need to change that so that it instead serializes instances of javax.activation.DataHandler in the same method. Update the ISD file to match the following changes:

 
<root> 
<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment" 
  id="http://tempuri.org/com.ibm.soap.attachments.demo.FileTransferService" 
  checkMustUnderstands="false"> 
  <isd:provider type="java" scope="Application" methods="getFileNamed"> 
    <isd:java class="com.ibm.soap.attachments.demo.FileTransferService" 
                 static="false"/> 
  </isd:provider> 
  <isd:mappings> 
    <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:x="http://www.filetransferservice.com/schemas/
                   FileTransferServiceRemoteInterface" 
    qname="x:javax.activation.DataHandler" 
    javaType="javax.activation.DataHandler" 
    xml2JavaClassName="org.apache.soap.encoding.soapenc.
                       MimePartSerializer" 
    java2XMLClassName="org.apache.soap.encoding.soapenc.
                       MimePartSerializer"/> 
  </isd:mappings> 
</isd:service> 
</root> 

All we've done is change the qname and javaType attributes to reflect the new type, and update the xml2JavaClassName and java2XMLClassName attributes to reflect the right serializer class.


Updating the generated proxy class

The next step is to update the proxy class so it will return an instance of javax.activation.DataHandler from its getFileNamed() method, and also correctly use the right serializer (similar to what we accomplished by rewriting the deployment descriptor earlier). Luckily, our modifications are quite limited, and similar to the ones made to the deployment descriptor. As an example, here is the getFileNamed() method from the originally generated proxy class:

 
public synchronized java.lang.Object getFileNamed(java.lang.String name) 
  throws Exception 
  { 
    String targetObjectURI = "http&colon;//tempuri.org/
                             com.ibm.soap.attachments.demo.FileTransferService"; 
    String SOAPActionURI = ""; 
    if(getURL() == null) 
    { 
      throw new SOAPException(Constants.FAULT_CODE_CLIENT, 
      "A URL must be specified via FileTransferServiceProxy.setEndPoint(URL)."); 
    } 
 
    call.setMethodName("getFileNamed"); 
    call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); 
    call.setTargetObjectURI(targetObjectURI); 
    Vector params = new Vector(); 
    Parameter nameParam = new Parameter("name", 
      java.lang.String.class, name, Constants.NS_URI_SOAP_ENC); 
      params.addElement(nameParam); 
      call.setParams(params); 
      Response resp = call.invoke(getURL(), SOAPActionURI); 
 
    //Check the response. 
    if (resp.generatedFault()) 
    { 
      Fault fault = resp.getFault(); 
     call.setFullTargetObjectURI(targetObjectURI); 
     throw new SOAPException(fault.getFaultCode(), fault.getFaultString()); 
    } 
    else 
    { 
      Parameter refValue = resp.getReturnValue(); 
      return ((java.lang.Object)refValue.getValue()); 
    } 
  } 

As you can see above, the only references to the return type lie in the cast of the return value from the Call object, and also in the signature of the method itself. In addition to modifying these lines, you also need to change the registration of the type of the return value. Look at the following static initializer generated in the Proxy class to place the right type-serializer mapping in the Apache SOAP Mapping registry on the client:

 
{ 
  org.apache.soap.encoding.soapenc.BeanSerializer ser_1 = 
    new org.apache.soap.encoding.soapenc.BeanSerializer(); 
  org.apache.soap.encoding.soapenc.BeanSerializer deSer_1 = 
    new org.apache.soap.encoding.soapenc.BeanSerializer(); 
  smr.mapTypes("http://schemas.xmlsoap.org/soap/encoding/", 
    new QName("http://www.filetransferservice.com/schemas/
    FileTransferServiceRemoteInterface", 
    "java.lang.Object"),java.lang.Object.class, ser_1, deSer_1) 
} 

Our first update is to change the return value of the getFileNamed() method, and update cast to cast the result value to a javax.activation.DataHandler:

 
public synchronized javax.activation.DataHandler getFileNamed
                                                    (java.lang.String name) 
  throws Exception 
  { 
    String targetObjectURI = "http://tempuri.org/com.ibm.soap.attachments.demo.
                              FileTransferService"; 
    String SOAPActionURI = ""; 
    if(getURL() == null) 
    { 
      throw new SOAPException(Constants.FAULT_CODE_CLIENT, 
      "A URL must be specified via FileTransferServiceProxy.setEndPoint(URL)."); 
    } 
    call.setMethodName("getFileNamed"); 
    call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); 
    call.setTargetObjectURI(targetObjectURI); 
    Vector params = new Vector(); 
    Parameter nameParam = new Parameter("name", java.lang.String.class, 
      name, Constants.NS_URI_SOAP_ENC); 
    params.addElement(nameParam); 
    call.setParams(params); 
    Response resp = call.invoke(getURL(), SOAPActionURI); 
   //Check the response. 
    if (resp.generatedFault()) 
    { 
      Fault fault = resp.getFault(); 
      call.setFullTargetObjectURI(targetObjectURI); 
      throw new SOAPException(fault.getFaultCode(), fault.getFaultString()); 
    } 
    else 
    { 
      Parameter refValue = resp.getReturnValue(); 
      return ((javax.activation.DataHandler)refValue.getValue()); 
    } 
  } 

Next, we need to update the static initializer to change the two serializers (the serializer and deserializer instances) to be instances of MimePartSerializer, and also change the mapping of the XML type and class to be javax.activation.DataHandler:

 
{ 
  org.apache.soap.encoding.soapenc.MimePartSerializer ser_1 = 
    new org.apache.soap.encoding.soapenc.MimePartSerializer(); 
  org.apache.soap.encoding.soapenc.MimePartSerializer deSer_1 = 
    new org.apache.soap.encoding.soapenc.MimePartSerializer(); 
  smr.mapTypes("http://schemas.xmlsoap.org/soap/encoding/", 
    new QName("http://www.filetransferservice.com/schemas/
    FileTransferServiceRemoteInterface", 
    "javax.activation.DataHandler"), 
     javax.activation.DataHandler.class, ser_1, deSer_1); 
} 

Now that you're done updating the client, you're almost ready to test the Web Service. First, add a simple client. Create the following class in the package com.ibm.soap.attachments.clients:

 
package com.ibm.soap.attachments.clients; 
import proxy.soap.com.ibm.soap.attachments.demo.*; 
import javax.activation.*; 
import java.io.*; 
public class FileTransferClient { 
  public static boolean DEBUG = true; 
  public static void main(String[] args) { 
    try { 
      if (args.length != 2) { 
        System.out.print("Improper number of arguments."); 
        System.out.println("Syntax: java FileTransferclient inp_file out_file"); 
      } else { 
        FileTransferServiceProxy proxy = new FileTransferServiceProxy(); 
        DataHandler handler = proxy.getFileNamed(args[0]); 
        if (DEBUG) 
          printContents(handler); 
        else 
          writeContents(handler, args[1]); 
      } 
    } catch (Exception e) { 
      System.out.println("Exception e " + e); 
    } 
  } 
  public static void printContents(DataHandler handler) throws IOException{ 
    InputStream strm = handler.getInputStream(); 
    while (true) { 
      int c = strm.read(); 
      if (c == -1) 
        break; 
      System.out.print((char) c); 
    } 
  } 
  public static void writeContents(DataHandler handler, String outputName) 
         throws IOException { 
    OutputStream out = new FileOutputStream(outputName); 
    handler.writeTo(out); 
  } 
} 

Before running this client you need to add the JavaMail JAR file to the Web project properties. Classes in this file are used for base-64 serialization. You have to do this because the Web Services Wizard doesn't add the mail.jar file (which is shipped with Apache SOAP, but is not used unless you're using SOAP with Attachments).

To do this, go to the Packages window, and from the Properties dialog, select Java build Path in the left-hand menu. Then select the Libraries tab, select Add External Jar, and add the following path (where <installroot> is the directory where you installed WebSphere Studio):

<installroot>/plugins/com.ibm.etools.server.jdk/jre/lib/ext/mail.jar

You're now ready to test your server and client. First, switch to the Server perspective and start the default server (or the server with which the SOAPAttachmentsProject is associated). If you want to, you can also start the TCP/IP monitor to watch the SOAP messages flying over the wire. If you do so, update the URL in the Proxy class to use port 8081 instead of port 8080, or to add the following statement after the creation of the Proxy to your client:

proxy.setEndpointURL("http://localhost:8080/SOAPWithAttachmentsProject/
                      servlet/rpcrouter")

Next, open a properties dialog on your new client class and set the input and output files (enter these in the Program Arguments entry field). If everything works, you should see something like this in the TCP/IP monitor (assuming that the file you're reading contains the text "This is it.":

Request:

 
POST /SOAPAttachmentsProject/servlet/rpcrouter HTTP/1.0 
Host: localhost:8080 
Content-Type: text/xml; charset=utf-8 
Content-Length: 514 
SOAPAction: "" 
 
<?xml version='1.0' encoding='UTF-8'?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<SOAP-ENV:Body> 
<ns1:getFileNamed xmlns:ns1= 
   "http://tempuri.org/com.ibm.soap.attachments.demo.FileTransferService" 
   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
<name xsi:type="xsd:string">c://temp.txt</name> 
</ns1:getFileNamed> 
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

Response:

 
HTTP/1.1 200 OK 
Server: WebSphere Application Server/4.0 
Content-Type: 
  multipart/related; boundary=633956732.1036640469055.JavaMail.kbrown.Melnibone; 
  type="text/xml"; start="653371772.1036640469055.apache-soap.Melnibone" 
Set-Cookie: JSESSIONID=0000WQWSUHQVZ3B02KA3BJLAWUY:-1;Path=/ 
Cache-Control: no-cache="set-cookie,set-cookie2" 
Expires: Thu, 01 Dec 1994 16:00:00 GMT 
Content-Length: 1006 
Content-Language: en 
Connection: close 
 
--633956732.1036640469055.JavaMail.kbrown.Melnibone 
Content-Type: text/xml; charset=utf-8 
Content-Transfer-Encoding: 8bit 
Content-ID: <653371772.1036640469055.apache-soap.Melnibone> 
Content-Length: 552 
 
<?xml version='1.0' encoding='UTF-8'?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<SOAP-ENV:Body> 
<ns1:getFileNamedResponse 
  xmlns:ns1="http://tempuri.org/com.ibm.soap.attachments.demo.FileTransferService" 
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
<return href ="cid:622176636.1036640469055.apache-soap.Melnibone"/> 
</ns1:getFileNamedResponse> 
 
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 
 
--633956732.1036640469055.JavaMail.kbrown.Melnibone 
Content-Type: text/plain 
Content-Transfer-Encoding: 7bit 
Content-ID: <622176636.1036640469055.apache-soap.Melnibone> 
 
This is it. 
--633956732.1036640469055.JavaMail.kbrown.Melnibone-


Summary

You've now seen some ways to make SOAP with Attachments work in Application Developer. It may seem like a lot of steps, but the procedure is not really that difficult, and along the way you've been able to see some of the "hidden corners" in the way Web Services are implemented in Application Developer. Hopefully this will be enough for you to start using SOAP with Attachments in your own projects.

Acknowledgements

Thanks to Maya Menon for prompting me to write this article with a question on JavaRanch, and for contributing to the sample client code.


Resources

About the author

Kyle Brown is a Senior Technical Staff Member with IBM Software Services for WebSphere. Kyle provides consulting services, education, and mentoring on object-oriented topics and Java 2 Enterprise Edition (J2EE) technologies to Fortune 500 clients. He is a co-author of Enterprise Java Programming with IBM WebSphere, the WebSphere AEs 4.0 Workbook for Enterprise Java Beans, 3rd Edition, and The Design Patterns Smalltalk Companion. He is also a frequent conference speaker on the topics of Enterprise Java, OO design, and design patterns. You can reach Kyle at brownkyl@us.ibm.com.

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=WebSphere
ArticleID=13972
ArticleTitle=Using SOAP with Attachments in WebSphere Studio Application Developer
publish-date=12112002
author1-email=mailto:brownkyl@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