Monday May 05, 2008

Glassfish v2 Clustering Testsuite

For about the last 6 months I have been working with the Glassfish clustering development team. I've been doing some amount of test execution and some test development. Most recently, I have been helping the development team by writing a set of tests to verify that session replication is working for a three instance glassfish cluster. The instances of the cluster are installed on the same machine and does not require the use of a load balancer. The load balancer is not necessary since this testsuite uses a testing technique called port hopping to simulate failover.

The tests that have been created make use of servlets and stateful session beans to do the testing. The tests verify various combinations of persistence-frequency and persistence-scope along with two kinds of EJB transactions (end-of-method or end-of-transaction)

There are two main ant targets that can be used to run the tests (quicklooktests and all). The quicklooktests ant target runs four tests and the all ant target runs sixteen tests. There are actually a total of 40 tests that have been developed, but this suite of tests were designed to be run in less then 15 to 20 minutes therefore some number of tests have been disabled. If a person wishes, then can enable all the tests to run by modifying an ant xml file to enable them.

This entire testsuite can be found on the Glassfish website at:
http://fisheye5.cenqua.com/browse/glassfish/appserv-tests/devtests/replication

In order to help people out, I've also created a self contained zip file that bundles the entire replication testsuite. This allows someone to download the testuite without the need to download the entire workspace.

This zip file can be found on the Glassfish website at:
http://fisheye5.cenqua.com/browse/glassfish/appserv-tests/devtests/replication/glassfish_replication.zip

I hope that people will find this testsuite a useful starting point to understanding how clustering works with glassfish.

If, during your use of the testsuite you encounter issues, please email me so that I can resolve them and enhance the usefulness of the testsuite.

Stephen DiMilla

stephen.dimilla@sun.com

Monday Jul 17, 2006

Sending and Receiving attachments using the SOAP MessageTransmission Optimization Mechanism (MTOM) in JAX-WS 2.0

This techtip will focus on how to send and receive attachments using the SOAP MessageTransmission Optimization Mechanism (MTOM) feature in JAX-WS 2.0. The example code below was developed and tested using a GlassFish implementation. A downloadable zip file that contains everything necessary to build and run this example is provided at the end of this techtip.

To understand the attachments based on MTOM in JAX-WS 2.0 you will need to be familiar with the following specifications:
http://www.w3.org/TR/soap12-mtom/

This MTOM example will demonstrate the sending of multiple types of attachments and verify their contents. Along with sending/receiving the attachments, there is a server side handler that is configured which will display the contents of the HTTP request and response to the GlassFish webserver log. It is done so that you can see the Content-type header contains the entry "type="application/xop+xml" which indicates that MTOM is being used. This example makes use of customization files to configure package names and the server side handler. There is also a directory named contentRoot which contains the various documents that will be used by this example. Although this is a very simplistic example it does show the use of MTOM and the sending and receiving of various kinds of documents. Certainly a user could expand and enhance this example to do far greater things.

Developing the WebService Server Side Endpoint

Step 1

Create your wsdl description for your webservices endpoint which will send and receive messages.

a) MTOMTestService.wsdl

The following wsdl was used to develop this example. Notice that there are three operations MTOMIn, MTOMInOut, and MTOMTestOut and one port MTOMPort that have been specified for the three tests that will be run.


<?xml version="1.0" encoding="UTF-8"?>
<!--
  Copyright 2006 Sun Microsystems, Inc. All rights reserved.
  SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
-->

<definitions
    name="MTOMTestService"
    targetNamespace="http://MTOMTestService.org/wsdl"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://MTOMTestService.org/wsdl"
    xmlns:s="http://MTOMTestService.org/types"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

    <types>
          <schema xmlns="http://www.w3.org/2001/XMLSchema"
               targetNamespace="http://MTOMTestService.org/types"
               xmlns:xmime="http://www.w3.org/2005/05/xmlmime" 
               elementFormDefault="qualified">

                 <complexType name="DataType">
                     <sequence>
                         <element name="docName1" type="string"/>
                         <element name="docName2" type="string"/>
                         <element name="docName3" type="string"/>
                         <element name="docName4" type="string"/>
                         <element name="docUrl1" type="string"/>
                         <element name="docUrl2" type="string"/>
                         <element name="docUrl3" type="string"/>
                         <element name="docUrl4" type="string"/>
                         <element name="doc1" type="base64Binary" xmime:expectedContentTypes="text/xml"/>
                         <element name="doc2" type="base64Binary" xmime:expectedContentTypes="application/xml"/>
                         <element name="doc3" type="base64Binary" xmime:expectedContentTypes="text/html"/>
                         <element name="doc4" type="base64Binary" xmime:expectedContentTypes="image/jpeg"/>
                     </sequence>
                 </complexType>
                 <complexType name="DataType2">
                     <sequence>
                         <element name="docName1" type="string"/>
                         <element name="docName2" type="string"/>
                         <element name="docName3" type="string"/>
                         <element name="docName4" type="string"/>
                         <element name="docUrl1" type="string"/>
                         <element name="docUrl2" type="string"/>
                         <element name="docUrl3" type="string"/>
                         <element name="docUrl4" type="string"/>
                         <element name="docUrl11" type="string"/>
                         <element name="docUrl12" type="string"/>
                         <element name="docUrl13" type="string"/>
                         <element name="docUrl14" type="string"/>
                         <element name="doc1" type="base64Binary" xmime:expectedContentTypes="text/xml"/>
                         <element name="doc2" type="base64Binary" xmime:expectedContentTypes="application/xml"/>
                         <element name="doc3" type="base64Binary" xmime:expectedContentTypes="text/html"/>
                         <element name="doc4" type="base64Binary" xmime:expectedContentTypes="image/jpeg"/>
                         <element name="result" type="string"/>
                     </sequence>
                 </complexType>
                 <complexType name="DataType3">
                     <sequence>
                         <element name="doc" type="base64Binary" xmime:expectedContentTypes="image/jpeg"/>
                     </sequence>
                 </complexType>
                 <element name="MTOMIn" type="s:DataType"/>
                 <element name="MTOMInResponse" type="xsd:string"/>
                 <element name="MTOMInOut" type="s:DataType2"/>
                 <element name="MTOMInOutResponse" type="s:DataType2"/>
                 <element name="MTOMOut" type="xsd:string"/>
                 <element name="MTOMOutResponse" type="s:DataType"/>
          </schema>
    </types>
    <message name="MTOMInRequest">
        <part name="data" element="s:MTOMIn"/>
    </message>
    <message name="MTOMInResponse">
        <part name="result" element="s:MTOMInResponse"/>
    </message>
    <message name="MTOMInOutRequest">
        <part name="data" element="s:MTOMInOut"/>
    </message>
    <message name="MTOMInOutResponse">
        <part name="data" element="s:MTOMInOutResponse"/>
    </message>
    <message name="MTOMOutRequest">
        <part name="urls" element="s:MTOMOut"/>
    </message>
    <message name="MTOMOutResponse">
        <part name="data" element="s:MTOMOutResponse"/>
    </message>

     <portType name="MTOMPortType">
          <operation name="MTOMIn">
               <input message="tns:MTOMInRequest"/>
               <output message="tns:MTOMInResponse"/>
          </operation>
          <operation name="MTOMInOut">
               <input message="tns:MTOMInOutRequest"/>
               <output message="tns:MTOMInOutResponse"/>
          </operation>
          <operation name="MTOMOut">
               <input message="tns:MTOMOutRequest"/>
               <output message="tns:MTOMOutResponse"/>
          </operation>
     </portType>

     <binding name="MTOMBinding" type="tns:MTOMPortType">
          <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
          <operation name="MTOMIn">
               <soap:operation soapAction=""/>
               <input>
                    <soap:body use="literal"/>
               </input>
               <output>
                    <soap:body use="literal"/>
               </output>
          </operation>
          <operation name="MTOMInOut">
               <soap:operation soapAction=""/>
               <input>
                    <soap:body use="literal"/>
               </input>
               <output>
                    <soap:body use="literal"/>
               </output>
          </operation>
          <operation name="MTOMOut">
               <soap:operation soapAction=""/>
               <input>
                    <soap:body use="literal"/>
               </input>
               <output>
                    <soap:body use="literal"/>
               </output>
          </operation>
     </binding>

  <service name="MTOMTestService">
    <port name="MTOMPort" binding="tns:MTOMBinding">
      <soap:address location="http://localhost:8080/MTOMTestService/jaxws/MTOMTest"/>
    </port>
  </service>
</definitions>

Step 2

Create a customization file for the server side generation.

a) customfile-server.xml


<!--
  Copyright 2006 Sun Microsystems, Inc. All rights reserved.
  SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
-->

<jaxws:bindings wsdlLocation="wsdl/MTOMTestService.wsdl"  version="2.0"
    xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb">

    <jaxws:bindings node="wsdl:definitions">
        <jaxws:package name="mtomtest.server"/>
    </jaxws:bindings>

    <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='http://MTOMTestServ
ice.org/types']" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl
/">
        <jxb:schemaBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
            <jxb:package name="mtomtest.server"/>
        </jxb:schemaBindings>
    </jaxws:bindings>
    <jaxws:bindings>
        <handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
           <handler-chain>
              <handler>
                  <handler-name>ServerLogicalHandler
                  <handler-class>mtomtest.server.ServerLogicalHandler
              </handler>
           </handler-chain>
        </handler-chains>
    </jaxws:bindings>
</jaxws:bindings>

b) Run wsimport to generate the server side artifacts using the above customization file.


Ensure you are in the directory: mtomtest/src/mtomtest

Execute the command: ant import-wsdl-server

The output follows:

Buildfile: build.xml

import-wsdl-server:

do-wsdl2java:

     [echo] Invoking WsImport task (WSDL-to-Java mapping)
 [wsimport] command line: wsimport /files/jdk/jdk1.5.0_06/jre/bin/java -classpath /sun/appserver9/lib/javaee.jar:/sun/appserver9/lib/appserv-ws.jar com.sun.tools.ws.WsImport -d /home/user/mtomtest/classes -keep -s /home/user/mtomtest/generated -verbose wsdl/MTOMTestService.wsdl -wsdllocation WEB-INF/wsdl/MTOMTestService.wsdl -b /home/user/mtomtest/src/mtomtest/customfile-server.xml
 [wsimport] mtomtest/server/DataType.java
 [wsimport] mtomtest/server/DataType2.java
 [wsimport] mtomtest/server/DataType3.java
 [wsimport] mtomtest/server/MTOMPortType.java
 [wsimport] mtomtest/server/MTOMTestService.java
 [wsimport] mtomtest/server/ObjectFactory.java
 [wsimport] mtomtest/server/package-info.java
 [wsimport] mtomtest/server/DataType.java
 [wsimport] mtomtest/server/DataType2.java
 [wsimport] mtomtest/server/DataType3.java
 [wsimport] mtomtest/server/MTOMPortType.java
 [wsimport] mtomtest/server/MTOMTestService.java
 [wsimport] mtomtest/server/ObjectFactory.java
 [wsimport] mtomtest/server/package-info.java

Step 3

Create and implement a common class that will be used to deal with the various attachments.

a) AttachmentHelper.java


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package mtomtest.common;


import java.awt.\*;
import java.util.\*;
import java.io.\*;
import java.net.URL;
import java.awt.image.\*;
import javax.xml.soap.AttachmentPart;
import javax.xml.transform.stream.StreamSource;
import javax.activation.DataHandler;
import javax.xml.transform.Source;

public class AttachmentHelper {
    public static Iterator getAttachments(Iterator iter) {
        while(iter.hasNext()) {
            Object obj = iter.next();
            if(!(obj instanceof AttachmentPart)) {                    
                return null;                    
            }
        }
        return iter;
    }
    
    public static AttachmentPart getAttachment(java.net.URI ref, Iterator iter) {
        if(iter == null || ref == null) {
            System.out.println("null Iterator for AttachmentPart");
            return null;
        }
        while(iter.hasNext()) {
            AttachmentPart tempAttachment = (AttachmentPart)iter.next();            
            if(ref.isOpaque() && ref.getScheme().equals("cid")) {
                String refId = ref.getSchemeSpecificPart();
                String cId = tempAttachment.getContentId();
                if(cId.equals("<"+refId+">") || cId.equals(refId)) {
                    return tempAttachment;
                }                
            }
        }
        return null;
    }
    
    public static boolean compareStreamSource(StreamSource src1, StreamSource src2, int length) throws Exception {
        if(src1 == null || src2 == null) {
            System.out.println("compareStreamSource - src1 or src2 null!");
            return false;
        }
        String in = getStringFromStreamSource(src1, length);
        String out = getStringFromStreamSource(src2, length);
        if(in == null) 
            System.out.println("src1 is null");
        if(out == null) 
            System.out.println("src2 is null");
        return in.equals(out);
    }
    
    private static String getStringFromStreamSource(StreamSource src, int length) throws Exception {
        byte buf[]=null;
        if(src == null)
            return null;
        InputStream outStr = src.getInputStream();
        if(outStr != null) {                   
            int len = outStr.available(); if(outStr.markSupported())outStr.reset();
            buf = new byte[len];
            outStr.read(buf, 0, len);
            System.out.println("From inputstream: "+new String(buf));
            return new String(buf);
        }else {
            char buf1[] = new char[length];
            Reader r = src.getReader();
            if(r == null)
                return null;
            r.reset();                                  
            r.read(buf1);
            System.out.println("From Reader: "+new String(buf));
            return new String(buf1);
        }
    }
    
    public static boolean compareImages(Image image1, Image image2) throws IOException {
        if (image1 == null || image2 == null)
            return false;

        boolean matched = false;
        Rectangle rect = new Rectangle(0, 0, convertToBufferedImage(image1).getWidth(), convertToBufferedImage(image1).getHeight());
        Iterator iter1 = handlePixels(image1, rect);
        Iterator iter2 = handlePixels(image2, rect);

        while (iter1.hasNext() && iter2.hasNext()) {
            Pixel pixel = (Pixel) iter1.next();
            if (pixel.equals((Pixel) iter2.next())) {
                matched = true;
            } else {
                matched = false;
            }
        }
        if (matched)
            return true;
        return false;
    }

    public static boolean compareImages(Image image1, Image image2, Rectangle rect) {
        if(image1 == null || image2 == null)
            return false;
        
        boolean matched = false;
        
        Iterator iter1 = handlePixels(image1, rect);
        Iterator iter2 = handlePixels(image2, rect);
        
        while(iter1.hasNext() && iter2.hasNext()) {
            Pixel pixel = (Pixel)iter1.next();
            if(pixel.equals((Pixel)iter2.next())) {
                matched = true;
            }else {
                matched = false;
            }
        }
        if(matched)
            return true;
        return false;        
    }

     public static Iterator handlePixels(Image img, Rectangle rect) {
         int x = rect.x;
         int y = rect.y;
         int w = rect.width;
         int h = rect.height;
         
        int[] pixels = new int[w \* h];
        PixelGrabber pg = new PixelGrabber(img, x, y, w, h, pixels, 0, w);
        try {
            pg.grabPixels();
        } catch (InterruptedException e) {
            System.err.println("interrupted waiting for pixels!");
            return null;
        }
        if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
            System.err.println("image fetch aborted or errored");
            return null;
        }
        ArrayList tmpList = new ArrayList();
        for (int j = 0; j < h; j++) {
            for (int i = 0; i < w; i++) {
              tmpList.add(handleSinglePixel(x+i, y+j, pixels[j \* w + i]));
            }
        }
        return tmpList.iterator();
     }

     private static Pixel handleSinglePixel(int x, int y, int pixel) {
        int alpha = (pixel >> 24) & 0xff;
        int red   = (pixel >> 16) & 0xff;
        int green = (pixel >>  8) & 0xff;
        int blue  = (pixel      ) & 0xff;
        return new Pixel(alpha, red, green, blue);
     }

    private static class Pixel {
        private int a;
        private int r;
        private int g;
        private int b;

        Pixel(int a, int r, int g, int b) {
            this.a = a;
            this.r = r;
            this.g = g;
            this.b = b;
        }

        protected boolean equals(Pixel p) {
            if(p.a == a && p.r == r && p.g == g && p.b == b)
                return true;
            return false;
        }
    }
    private static BufferedImage convertToBufferedImage(Image image) throws IOException {
        if (image instanceof BufferedImage) {
            return (BufferedImage)image;

        } else {
            MediaTracker tracker = new MediaTracker(null/\*not sure how this is used\*/);
            tracker.addImage(image, 0);
            try {
                tracker.waitForAll();
            } catch (InterruptedException e) {
                throw new IOException(e.getMessage());
            }
            BufferedImage bufImage = new BufferedImage(
                    image.getWidth(null),
                    image.getHeight(null),
                    BufferedImage.TYPE_INT_RGB);

            Graphics g = bufImage.createGraphics();
            g.drawImage(image, 0, 0, null);
            return bufImage;
        }
    }
    public static Image getImageDoc(URL url) throws Exception {
        System.out.println("url="+url);
        return javax.imageio.ImageIO.read(url);
    }
    public static String getStringDoc(URL url) throws Exception {
        System.out.println("url="+url);
        DataHandler dh = new DataHandler(url);
        byte[] bytes = new byte[8192];
        int count = dh.getInputStream().read(bytes, 0, 8192);
        String string = new String(bytes, 0, count);
        return string;
    }

    public static StreamSource getSourceDoc(URL url) throws Exception {
        System.out.println("url="+url);
        DataHandler dh = new DataHandler(url);
        StreamSource source = new StreamSource(dh.getInputStream());
        return source;
    }
    public static DataHandler getDataHandlerDoc(URL url) throws Exception {
        System.out.println("url="+url);
        DataHandler dh = new DataHandler(url);
        return dh;
    }

    public static String ValidateAttachmentData(String expectedDoc, String actualDoc, String whichAttachment)
    {
         String result = null;
         if (actualDoc != null){
             if (!actualDoc.equals(expectedDoc)){
               result = "FAILURE: "+whichAttachment+" String documents did not compare correctly";
               System.out.println("========================");
               System.out.println(whichAttachment+" comparison failed");
               System.out.println("expected:");
               System.out.println("------------------------");
               System.out.println(expectedDoc);
               System.out.println("------------------------");
               System.out.println("actual:");
               System.out.println("------------------------");
               System.out.println(actualDoc);
               System.out.println("------------------------");
           }
         } else {
             result = "FAILURE: "+whichAttachment+" actual String document was null";
         }
         if(result != null) result += "\\n";
            return result;
    }

    public static String ValidateAttachmentData(DataHandler expectedDoc, DataHandler actualDoc, String whichAttachment) throws Exception    {
         byte data[] = new byte[4096];
         int count = expectedDoc.getInputStream().read(data, 0, 4096);
         String strExpected = new String(data, 0, count);
         count = actualDoc.getInputStream().read(data, 0, 4096);
         String strActual = new String(data, 0, count);
         String result = ValidateAttachmentData(strExpected, strActual, whichAttachment);
         return result;
    }

    public static String ValidateAttachmentData(Source expectedDoc, Source actualDoc, String whichAttachment) throws Exception {
         String result = null;
         boolean debug = false;
         if (actualDoc!= null){
             byte data1[] = new byte[8192];
             byte data2[] = new byte[8192];
             int count1 = 0;
             int count2 = 0;
             int tmpcount = 0;
             InputStream is = ((StreamSource)expectedDoc).getInputStream();
             while(tmpcount != -1) {
                 tmpcount = is.read(data1, count1, 8192-count1);
                 if(tmpcount != -1) count1 += tmpcount;
                 if(tmpcount == 0) break;
             }
             if(count1 == 0) count1 = -1;
             tmpcount = 0;
             is = ((StreamSource)actualDoc).getInputStream();
             while(tmpcount != -1) {
                 tmpcount = is.read(data2, count2, 8192-count2);
                 if(tmpcount != -1) count2 += tmpcount;
                 if(tmpcount == 0) break;
             }
             if(count2 == 0) count2 = -1;
             if(debug) {
                 System.out.println("Sending doc1 to file /tmp/"+whichAttachment);
                 FileOutputStream fos = new FileOutputStream("/tmp/"+whichAttachment);
                 fos.write(data1, 0, count1);
                 fos.close();
                 System.out.println("Sending doc2 to file /tmp/"+whichAttachment+".mtom");
                 fos = new FileOutputStream("/tmp/"+whichAttachment+".mtom");
                 fos.write(data2, 0, count2);
                 fos.close();
             }
         } else {
             result = "FAILURE: "+whichAttachment+" actual XML document was null";
         }
         if(result != null) result += "\\n";
         return result;
    }

    public static String ValidateAttachmentData(Image image1, Image image2, String whichAttachment) throws IOException {
        String result = null;
        if (image2 != null){
             if (!compareImages(image1, image2, new Rectangle(0,0,100,120))) {
                 System.out.println(whichAttachment+" comparison failed");
                 result="FAILURE: "+whichAttachment+" Image documents did not compare correctly";
             }
        } else {
             result = "FAILURE: "+whichAttachment+" actual Image document was null";
        }
        if(result != null) result += "\\n";
           return result;
    }

    public static void dumpByteArrays(byte[] b1, int c1, byte[] b2, int c2, String whichAttachment)
    {
        System.out.println("in dumpByteArrays");
        boolean error_found=false;
        StringBuffer s1 = new StringBuffer();
        StringBuffer s2 = new StringBuffer();
        int nexti = 0;
        for(int i=0; i c1 || i > c2) {
               nexti = i;
               break;
           }
           s1.append((char)b1[i]);
           s2.append((char)b2[i]);
           if(b1[i] != b2[i]) {
               if (!error_found){
                  System.out.println("FAILURE begins at (index="+i+")"); 
                  System.out.printf("byte1[%d]=0x%x|0%o|%d,  byte2[%d]=0x%x|0%o|%d,  count1=%d,  count2=%d\\n",
                  i, b1[i], b1[i], b1[i], i, b2[i], b2[i], b2[i], c1, c2);
                  error_found=true;
               }
               nexti = i+1;
               break;
           }
        }
        int i = nexti;
        int count =0;
        while(i < c1 && count < 10) {
           s1.append((char)b1[i++]);
           count++;
        }
        i = nexti;
        count = 0;
        while(i < c2 && count < 10) {
           s2.append((char)b2[i++]);
           count++;
        }
        System.out.println("--------------------------------------------");
        System.out.println("doc1 upto point of error (Expected "+whichAttachment+" document)\\n"+s1.toString());
        System.out.println("--------------------------------------------");
        System.out.println("doc2 upto point of error (Actual "+whichAttachment+" document)\\n"+s2.toString());
        System.out.println("========================================================================");
    }

    public static void dumpSourceDoc(Source s) throws Exception
    {
       System.out.println("in dumpSourceDoc");
       byte data[] = new byte[8192];
       int c1 = 0;
       int tmpcount = 0;
       InputStream is = ((StreamSource)s).getInputStream();
       while(tmpcount != -1) {
           tmpcount = is.read(data, c1, 8192-c1);
           if(tmpcount != -1) c1 += tmpcount;
           if(tmpcount == 0) break;
       }
       System.out.println("========================================================================");
       String tmpStr = new String(data, 0, c1);
       System.out.println(""+tmpStr);
       System.out.println("========================================================================");
    }
}

Step 4

Create and implement the code for the webservices server side endpoint along with the server side handler.

Notice the annotation: @BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING) which is one of the ways to enable MTOM on the server side.

a) MTOMTestImpl.java


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package mtomtest.server;

import javax.jws.WebService;
import javax.xml.ws.WebServiceException;

import javax.xml.ws.Holder;

import java.awt.Image;
import mtomtest.common.AttachmentHelper;
import java.net.URL;
import javax.activation.DataHandler;
import javax.xml.transform.Source;


import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;


@WebService(
    portName="MTOMPort",
    targetNamespace="http://MTOMTestService.org/wsdl",
    serviceName="MTOMTestService",
    wsdlLocation="WEB-INF/wsdl/MTOMTestService.wsdl",
    endpointInterface="mtomtest.server.MTOMPortType")

@BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING)


public class MTOMTestImpl implements MTOMPortType {


    public String mtomIn(mtomtest.server.DataType data)  {
      System.out.println("--------------------------");
      System.out.println("In mtomIn");

      String result = "";
     
      try { 

          String docName1 = data.getDocName1();
          String docName2 = data.getDocName2();
          String docName3 = data.getDocName3();
          String docName4 = data.getDocName4();
          System.out.println("docName1="+docName1);
          System.out.println("docName2="+docName2);
          System.out.println("docName3="+docName3);
          System.out.println("docName4="+docName4);

          URL docURL1 = new URL(data.getDocUrl1());
          URL docURL2 = new URL(data.getDocUrl2());
          URL docURL3 = new URL(data.getDocUrl3());
          URL docURL4 = new URL(data.getDocUrl4());
          System.out.println("docURL1="+docURL1.toString());
          System.out.println("docURL2="+docURL2.toString());
          System.out.println("docURL3="+docURL3.toString());
          System.out.println("docURL4="+docURL4.toString());

          Source doc1 = AttachmentHelper.getSourceDoc(docURL1);
          Source doc2 = AttachmentHelper.getSourceDoc(docURL2);
          DataHandler doc3 = AttachmentHelper.getDataHandlerDoc(docURL3);
          Image doc4 = AttachmentHelper.getImageDoc(docURL4);
          String tmpRes = AttachmentHelper.ValidateAttachmentData(doc1,data.getDoc1(),docName1);
          if (tmpRes != null){
              result = result + tmpRes;
          }
          tmpRes = AttachmentHelper.ValidateAttachmentData(doc2,data.getDoc2(),docName2);
          if (tmpRes != null){
              result = result + tmpRes;
          }
          tmpRes = AttachmentHelper.ValidateAttachmentData(doc3,data.getDoc3(),docName3);
          if (tmpRes != null){
              result = result + tmpRes;
          }
          tmpRes = AttachmentHelper.ValidateAttachmentData(doc4, data.getDoc4(),docName4);
          if (tmpRes != null){
              result = result + tmpRes;
          }
      } catch (Exception e) {
         throw new WebServiceException(e.toString());
      }
      return result;
    }

    public void mtomInOut(
                          Holder<String> hDocName1,
                          Holder<String> hDocName2,
                          Holder<String> hDocName3,
                          Holder<String> hDocName4,
                          Holder<String> hDocUrl1,
                          Holder<String> hDocUrl2,
                          Holder<String> hDocUrl3,
                          Holder<String> hDocUrl4,
                          Holder<String> hDocUrl11,
                          Holder<String> hDocUrl12,
                          Holder<String> hDocUrl13,
                          Holder<String> hDocUrl14,
                          Holder<Source> hDoc1,
                          Holder<Source> hDoc2,
                          Holder<DataHandler> hDoc3,
                          Holder<Image> hDoc4,
                          Holder<String> hResult)  {

      System.out.println("--------------------------");
      System.out.println("In mtomInOut");
      String result= "";
      try {

          String docName1 = hDocName1.value;
          String docName2 = hDocName2.value;
          String docName3 = hDocName3.value;
          String docName4 = hDocName4.value;
          System.out.println("docName1="+docName1);
          System.out.println("docName2="+docName2);
          System.out.println("docName3="+docName3);
          System.out.println("docName4="+docName4);

          URL docURL1 = new URL(hDocUrl1.value);
          URL docURL2 = new URL(hDocUrl2.value);
          URL docURL3 = new URL(hDocUrl3.value);
          URL docURL4 = new URL(hDocUrl4.value);

          System.out.println("docURL1="+docURL1.toString());
          System.out.println("docURL2="+docURL2.toString());
          System.out.println("docURL3="+docURL3.toString());
          System.out.println("docURL4="+docURL4.toString());

          Source doc1 = AttachmentHelper.getSourceDoc(docURL1);
          Source doc2 = AttachmentHelper.getSourceDoc(docURL2);
          DataHandler doc3 = AttachmentHelper.getDataHandlerDoc(docURL3);
          Image doc4 = AttachmentHelper.getImageDoc(docURL4);
          String tmpRes = AttachmentHelper.ValidateAttachmentData(doc1,hDoc1.value, docName1);
          if (tmpRes != null){
              result = result + tmpRes;
          }
          tmpRes = AttachmentHelper.ValidateAttachmentData(doc2,hDoc2.value,docName2);
          if (tmpRes != null){
              result = result + tmpRes;
          }
          tmpRes = AttachmentHelper.ValidateAttachmentData(doc3,hDoc3.value,docName3);
          if (tmpRes != null){
              result = result + tmpRes;
          }
          tmpRes = AttachmentHelper.ValidateAttachmentData(doc4,hDoc4.value,docName4);
          if (tmpRes != null){
              result = result + tmpRes;
          }
         
          URL docURL11 = new URL(hDocUrl11.value);
          URL docURL12 = new URL(hDocUrl12.value);
          URL docURL13 = new URL(hDocUrl13.value);
          URL docURL14 = new URL(hDocUrl14.value);

          System.out.println("docURL11="+docURL11.toString());
          System.out.println("docURL12="+docURL12.toString());
          System.out.println("docURL13="+docURL13.toString());
          System.out.println("docURL14="+docURL14.toString());

          hDoc1.value = AttachmentHelper.getSourceDoc(docURL11);
          hDoc2.value = AttachmentHelper.getSourceDoc(docURL12);
          hDoc3.value = AttachmentHelper.getDataHandlerDoc(docURL13);
          hDoc4.value = AttachmentHelper.getImageDoc(docURL14);

          hResult.value = result;
      } catch (Exception e) {
         throw new WebServiceException(e.toString());
      }
    }
    public mtomtest.server.DataType mtomOut(String urls)  {
      System.out.println("--------------------------");
      System.out.println("In mtomOut");

      System.out.println("urls="+urls);
      String[] tmpUrls = urls.split(",");

      for (int i=0;i<tmpUrls.length;i++){
          System.out.println("url["+i+"]="+tmpUrls[i]);
      }

      DataType d = new DataType();
      try {
         URL docURL1 = new URL(tmpUrls[0]);
         URL docURL2 = new URL(tmpUrls[1]);
         URL docURL3 = new URL(tmpUrls[2]);
         URL docURL4 = new URL(tmpUrls[3]);

         d.setDocUrl1(docURL1.toString());
         d.setDocUrl2(docURL2.toString());
         d.setDocUrl3(docURL3.toString());
         d.setDocUrl4(docURL4.toString());

         Source doc1 = AttachmentHelper.getSourceDoc(docURL1);
         Source doc2 = AttachmentHelper.getSourceDoc(docURL2);
         DataHandler doc3 = AttachmentHelper.getDataHandlerDoc(docURL3);
         Image doc4 = AttachmentHelper.getImageDoc(docURL4);

         d.setDoc1(doc1);
         d.setDoc2(doc2);
         d.setDoc3(doc3);
         d.setDoc4(doc4);

      } catch (Exception e) {
         throw new WebServiceException(e.toString());
      }
      return d;
    }

}

b) ServerLogicalHandler.java

This is the handler that will display the HTTP header to the webserver log.


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package mtomtest.server;

import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.LogicalHandler;
import javax.xml.ws.handler.LogicalMessageContext;
import javax.xml.ws.LogicalMessage;

public class ServerLogicalHandler implements LogicalHandler
{

    public boolean handleMessage(LogicalMessageContext context)
    {
        boolean direction= ((Boolean)context.get(LogicalMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();
        if (direction) {
            System.out.println("direction = outbound");
        } else {
            System.out.println("direction = inbound");
        }
        displayHeaders(context);
        return true;
    }

    public void close(MessageContext context)
    {
    }

    public boolean handleFault(LogicalMessageContext context)
    {
        return true;
    }

    public void displayHeaders(MessageContext context) {
       System.out.println("HTTP Headers =|"+ context.get(MessageContext.HTTP_REQUEST_HEADERS)+"|");
       return;
    }
}

Step 4

Build and compile the webservices server side endpoint code and package it in a war file.


Ensure you are in the directory: mtomtest/src/mtomtest

Execute the command:ant compile-server create-war

The output follows:

compile-server:
     [echo] compile-server
    [javac] Compiling 3 source files to /home/user/mtomtest/classes
    [javac] Note: /home/user/mtomtest/src/mtomtest/common/AttachmentHelper.java uses unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.

compile-server-w2j:
     [echo] compile-server-w2j

create-war:
     [echo] create-war
     [echo] Creating war file /home/user/mtomtest/dist/mtomtest/MTOMTestService.war
    [mkdir] Created dir: /home/user/mtomtest/dist/mtomtest
      [war] Building war: /home/user/mtomtest/dist/mtomtest/MTOMTestService.war
     [echo] Created war file /home/user/mtomtest/dist/mtomtest/MTOMTestService.

build-server-w2j:

build-server:
Step 5

Deploy the webservices endpoint packaged in the war to a GlassFish appserver environment.


Ensure you are in the directory: mtomtest/src/mtomtest

Execute the command:ant deploy

The output follows:

Buildfile: build.xml

checkPlatform:

configUnix:

configWindows:

filter.password.file:
     [copy] Copying 1 file to /home/user/mtomtest/build

configPlatform:

deploy:
     [echo] deploy
     [echo] Deploying /home/user/mtomtest/dist/mtomtest/MTOMTestService.war.
     [echo] asadmin deploy --user admin --passwordfile /home/user/mtomtest/build/password.txt --host localhost --port 4848 --contextroot MTOMTestService --target server --updload=true
     [exec] Command deploy executed successfully.
Step 6

Verify web service application is deployed:

In your browser go to URL location of the published WSDL for this server:


o http://host:port/MTOMTestService/jaxws/MTOMTest?WSDL

where host and port are the settings of your configured GlassFish web server host and port settings, MTOMTestService is the context root of your web service application, /jaxws/MTOMTest is the URL alias specified in the web.xml deployment descriptor for deployed endpoint and ?WSDL is how the published WSDL is accessed.

A WSDL should be displayed if the service is up and running.

Developing WebServices Client Side Code

Step 1

Run wsimport to generate the client side artifacts to communicate with the webservices endpoint developed in previous section pointing to the wsdl of the deployed endpoint on a GlassFish appserver environment.

a) Create the customization file for the client side generation.

customfile-client.xml


<!--
  Copyright 2006 Sun Microsystems, Inc. All rights reserved.
  SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
-->

<jaxws:bindings wsdlLocation="wsdl/MTOMTestService.wsdl"  version="2.0" 
    xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb">    
   
    <jaxws:bindings node="wsdl:definitions">
        <jaxws:package name="mtomtest.client"/>
    </jaxws:bindings>
 
    <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='http://MTOMTestService.org/types']" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
        <jxb:schemaBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
            <jxb:package name="mtomtest.client"/> 
        </jxb:schemaBindings>
    </jaxws:bindings>
</jaxws:bindings>            

b) Run wsimport to generate the client side artifacts to communicate with the endpoint developed in the previous section pointing to the wsdl of the deployed endpoint on a GlassFish appserver environment using the above customization file.


Ensure you are in the directory: mtomtest/src/mtomtest

Execute the command:ant import-wsdl-client

The output follows:

Buildfile: build.xml

import-wsdl-client:

do-wsdl2java:
     [echo] Invoking WsImport task (WSDL-to-Java mapping)
 [wsimport] command line: wsimport /files/jdk/jdk1.5.0_06/jre/bin/java -classpath /sun/appserver9/lib/javaee.jar:/sun/appserver9/lib/appserv-ws.jar:/home/user/mtomtest/classes com.sun.tools.ws.WsImport -d /home/user/mtomtest/classes -keep -s /home/user/mtomtest/generated -verbose wsdl/MTOMTestService.wsdl -wsdllocation http://localhost:8001/MTOMTestService/jaxws/MTOMTest?WSDL -b /home/user/mtomtest/src/mtomtest/customfile-client.xml
 [wsimport] mtomtest/client/DataType.java
 [wsimport] mtomtest/client/DataType2.java
 [wsimport] mtomtest/client/DataType3.java
 [wsimport] mtomtest/client/MTOMPortType.java
 [wsimport] mtomtest/client/MTOMTestService.java
 [wsimport] mtomtest/client/ObjectFactory.java
 [wsimport] mtomtest/client/package-info.java
 [wsimport] mtomtest/client/DataType.java
 [wsimport] mtomtest/client/DataType2.java
 [wsimport] mtomtest/client/DataType3.java
 [wsimport] mtomtest/client/MTOMPortType.java
 [wsimport] mtomtest/client/MTOMTestService.java
 [wsimport] mtomtest/client/ObjectFactory.java
 [wsimport] mtomtest/client/package-info.java
Step 2

Create the client code to communicate with the deployed endpoint.

Notice the following lines of code from the setup method:


       SOAPBinding binding = (SOAPBinding)((BindingProvider)port).getBinding();
       binding.setMTOMEnabled(true);
This is one way to enable MTOM on the client side.

a) Client.java


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package mtomtest.client;

import mtomtest.common.AttachmentHelper;

import java.io.\*;
import java.net.\*;
import java.util.\*;
import java.awt.Image;
import javax.xml.soap.\*;

import javax.activation.DataHandler;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import javax.xml.ws.Holder;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.soap.SOAPBinding;
import javax.xml.ws.WebServiceRef;

import javax.xml.namespace.QName;


public class Client {
    private static MTOMPortType port = null;

    @WebServiceRef
    private static MTOMTestService service = null;

    final String NAMESPACEURI = "http://MTOMTestService.org/wsdl";
    final String PORT_NAME    = "MTOMTestPort";
    final QName PORT_QNAME = new QName(NAMESPACEURI, PORT_NAME);

    final String PROTOCOL="http";
    private static String host="localhost";
    private static int portnum=8001;
    final String ctxroot = "/MTOMTestService";

    final String SDOC1="text.xml";
    final String SDOC2="application.xml";
    final String SDOC3="attach.html";
    final String SDOC4="attach.jpg";
    final String SDOC11="text2.xml";
    final String SDOC12="application2.xml";
    final String SDOC13="attach2.html";
    final String SDOC14="attach2.jpg";


    private URL docURL1 = null;
    private URL docURL2 = null;
    private URL docURL3 = null;
    private URL docURL4 = null;
    private URL docURL11 = null;
    private URL docURL12 = null;
    private URL docURL13 = null;
    private URL docURL14 = null;


    public static void main(String[] args ) {
    Client client = new Client();
     try {
        int i=0;
        while (i < args.length) {
          System.out.println("args["+i+"]="+args[i]);
          if (args[i].equals("-host")){
             host=args[++i];
             i++;
             continue;
          }
          if (args[i].equals("-portnum")){
             portnum=Integer.parseInt(args[++i]);
             i++;
             continue;
          }
        }
     } catch (Exception e) {
       e.printStackTrace();
     }
     System.out.println("------------------------------------------");
     System.out.println("Executing Tests");
     System.out.println("------------------------------------------");
     client.doTests();
    }


    public void doTests() {
       doMTOMInTest();
       doMTOMInOutTest();
       doMTOMOutTest();
    }
    public boolean setup() {
       boolean result=true;
       System.out.println("Protocol="+PROTOCOL);
       System.out.println("Host="+host);
       System.out.println("portnum="+portnum);
       try {
          docURL1 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC1);
          docURL2 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC2);
          docURL3 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC3);
          docURL4 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC4);
          docURL11 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC11);
          docURL12 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC12);
          docURL13 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC13);
          docURL14 = new URL(PROTOCOL, host, portnum, ctxroot + "/" + SDOC14);
       } catch (Exception e) {
          e.printStackTrace();
          result=false;
       }
       port = service.getMTOMPort();
       System.out.println("port="+port);
       SOAPBinding binding = (SOAPBinding)((BindingProvider)port).getBinding();
       binding.setMTOMEnabled(true);

       return result;
    }
    public void doMTOMInTest() {
      System.out.println("doMTOMInTest");
      boolean pass = true;
      if (setup()){
         try {
           DataType data = new DataType();
           data.setDocName1(SDOC1);
           data.setDocName2(SDOC2);
           data.setDocName3(SDOC3);
           data.setDocName4(SDOC4);

           data.setDocUrl1(docURL1.toString());
           data.setDocUrl2(docURL2.toString());
           data.setDocUrl3(docURL3.toString());
           data.setDocUrl4(docURL4.toString());

           StreamSource doc1 = AttachmentHelper.getSourceDoc(docURL1);
           StreamSource doc2 = AttachmentHelper.getSourceDoc(docURL2);
           DataHandler doc3 = AttachmentHelper.getDataHandlerDoc(docURL3);
           Image doc4 = AttachmentHelper.getImageDoc(docURL4);

           data.setDoc1(doc1);
           data.setDoc2(doc2);
           data.setDoc3(doc3);
           data.setDoc4(doc4);

           System.out.println("Send 4 documents using MTOM via webservice method mtomIn()");
           System.out.println("Documents to send: ["+SDOC1+","+SDOC2+","+SDOC3+","+SDOC4+"]");
           String result = port.mtomIn(data);
           if (!result.equals("")){
               System.err.println("An error occurred with one or more of the attachments"); 
               System.err.println("result="+result);
               pass=false;
           }
         } catch (Exception e) {
               e.printStackTrace();
               pass=false;
         }
      } else {
         pass=false;
      }
      if (pass)
         System.out.println("doMTOMInTest PASSED");
      else
         System.err.println("doMTOMInTest FAILED");
    }

    public void doMTOMInOutTest() {
     System.out.println("doMTOMInOutTest");
     boolean pass = true;
     if (setup()) {
        try {
           Holder hDocName1 = new Holder(SDOC1);
           Holder hDocName2 = new Holder(SDOC2);
           Holder hDocName3 = new Holder(SDOC3);
           Holder hDocName4 = new Holder(SDOC4);

           Holder hDocUrl1 = new Holder(docURL1.toString());
           Holder hDocUrl2 = new Holder(docURL2.toString());
           Holder hDocUrl3 = new Holder(docURL3.toString());
           Holder hDocUrl4 = new Holder(docURL4.toString());
           Holder hDocUrl11 = new Holder(docURL11.toString());
           Holder hDocUrl12 = new Holder(docURL12.toString());
           Holder hDocUrl13 = new Holder(docURL13.toString());
           Holder hDocUrl14 = new Holder(docURL14.toString());

           StreamSource doc1 = AttachmentHelper.getSourceDoc(docURL1);
           StreamSource doc2 = AttachmentHelper.getSourceDoc(docURL2);
           DataHandler doc3 = AttachmentHelper.getDataHandlerDoc(docURL3);
           Image doc4 = AttachmentHelper.getImageDoc(docURL4);


           Holder hDoc1 = new Holder(doc1);
           Holder hDoc2 = new Holder(doc2);
           Holder hDoc3 = new Holder(doc3);
           Holder hDoc4 = new Holder(doc4);
           Holder hResult = new Holder(new String());
           System.out.println("Send and receieve 4 documents using MTOM via webservice method mtomInOut()");
           System.out.println("Documents to send: ["+SDOC1+","+SDOC2+","+SDOC3+","+SDOC4+"]");
           System.out.println("Documents to receive: ["+SDOC11+","+SDOC12+","+SDOC13+","+SDOC14+"]");
           port.mtomInOut(hDocName1,hDocName2,hDocName3,hDocName4,
                          hDocUrl1,hDocUrl2,hDocUrl3,hDocUrl4,
                          hDocUrl11,hDocUrl12,hDocUrl13,hDocUrl14,
                          hDoc1,hDoc2,hDoc3,hDoc4,hResult);
           if (!(hResult.value).equals("")){
               System.err.println("Server-side errors occurred:\\n"+ hResult.value);
               pass=false;
           }
           System.out.println("Verify the contents of the received documents");

           doc1 = AttachmentHelper.getSourceDoc(docURL11);
           doc2 = AttachmentHelper.getSourceDoc(docURL12);
           doc3 = AttachmentHelper.getDataHandlerDoc(docURL13);
           doc4 = AttachmentHelper.getImageDoc(docURL14);
           
           // Now test the documents that were sent back by Server
           String tmpRes = AttachmentHelper.ValidateAttachmentData(doc1,hDoc1.value, SDOC11);
           if (tmpRes != null){
               System.err.println("Client-side error: "+tmpRes);
               pass = false;
           }
           tmpRes = AttachmentHelper.ValidateAttachmentData(doc2,hDoc2.value,SDOC12);
           if (tmpRes != null){
               System.err.println("Client-side error: "+tmpRes);
               pass = false;
           }
           tmpRes = AttachmentHelper.ValidateAttachmentData(doc3,hDoc3.value,SDOC13);
           if (tmpRes != null){
              System.err.println("Client-side error: "+tmpRes);
              pass = false;
           }
           tmpRes = AttachmentHelper.ValidateAttachmentData(doc4,hDoc4.value,SDOC14);
           if (tmpRes != null){
               System.err.println("Client-side error: "+tmpRes);
               pass = false;
           }
           if(pass) {
              System.out.println("All received documents are as expected (ok)");
           }
         } catch (Exception e) {
            e.printStackTrace();
            pass=false;
         }
      } else {
         pass=false;
      }
      if (pass)
         System.out.println("doMTOMInOutTest PASSED");
      else
         System.err.println("doMTOMInOutTest FAILED");
    }

    public void doMTOMOutTest() {
     System.out.println("doMTOMOutTest");
     boolean pass = true;
     if (setup()) {
        try {
           StreamSource doc1 = AttachmentHelper.getSourceDoc(docURL1);
           StreamSource doc2 = AttachmentHelper.getSourceDoc(docURL2);
           DataHandler doc3 = AttachmentHelper.getDataHandlerDoc(docURL3);
           Image doc4 = AttachmentHelper.getImageDoc(docURL4);

           String urls = docURL1.toString()+","+docURL2.toString()+
                        ","+docURL3.toString()+","+docURL4.toString();
           System.out.println("urls="+urls);
           System.out.println("Receive 4 documents using MTOM via webservice method mtomOut()");
           System.out.println("Documents to receive: ["+SDOC1+","+SDOC2+","+SDOC3+","+SDOC4+"]");
           DataType data = port.mtomOut(urls);
           System.out.println("Verify the contents of the received documents");
           String tmpRes = AttachmentHelper.ValidateAttachmentData(doc1,data.getDoc1(), SDOC1);
           if (tmpRes != null){
             System.err.println("Client-side error: "+tmpRes);
             pass = false;
           }
           tmpRes = AttachmentHelper.ValidateAttachmentData(doc2,data.getDoc2(),SDOC2);
           if (tmpRes != null){
             System.err.println("Client-side error: "+tmpRes);
             pass = false;
           }
           tmpRes = AttachmentHelper.ValidateAttachmentData(doc3,data.getDoc3(),SDOC3);
           if (tmpRes != null){
             System.err.println("Client-side error: "+tmpRes);
             pass = false;
           }
           tmpRes = AttachmentHelper.ValidateAttachmentData(doc4,data.getDoc4(),SDOC4);
           if (tmpRes != null){
             System.err.println("Client-side error: "+tmpRes);
             pass = false;
           }
           if(pass) {
               System.out.println("All received documents are as expected (ok)");
           }
        } catch (Exception e) {
               e.printStackTrace();
               pass=false;
        }

      } else {
         pass=false;
      }
      if (pass)
         System.out.println("doMTOMOutTest PASSED");
      else
         System.err.println("doMTOMOutTest FAILED");
    }

}

Step 3

Build and compile the client code.


Ensure you are in the directory: mtomtest/src/mtomtest

Execute the command:ant compile-client

The output follows:

Buildfile: build.xml

compile-client:
     [echo] compile-client
    [javac] Compiling 9 source files to /home/user/mtomtest/classes
Step 4

Run the client code which will communicate with the deployed webservices endpoint


Ensure you are in the directory: mtomtest/src/mtomtest

Execute the command:ant runclient

The output follows:

Buildfile: build.xml

checkPlatform:

configUnix:

configWindows:

filter.password.file:
     [copy] Copying 1 file to /home/user/mtomtest/build

configPlatform:

runclient:
     [echo] runclient mtomtest.client.Client
     [exec] args[0]=-host
     [exec] args[2]=-portnum
     [exec] ------------------------------------------
     [exec] Executing Tests
     [exec] ------------------------------------------
     [exec] doMTOMInTest
     [exec] Protocol=http
     [exec] Host=localhost
     [exec] portnum=8001
     [exec] port=com.sun.xml.ws.client.EndpointIFInvocationHandler@171194d
     [exec] url=http://localhost:8001/MTOMTestService/text.xml
     [exec] url=http://localhost:8001/MTOMTestService/application.xml
     [exec] url=http://localhost:8001/MTOMTestService/attach.html
     [exec] url=http://localhost:8001/MTOMTestService/attach.jpg
     [exec] Send 4 documents using MTOM via webservice method mtomIn()
     [exec] Documents to send: [text.xml,application.xml,attach.html,attach.jpg]
     [exec] MTOMEnabled=true
     [exec] doMTOMInTest PASSED
     [exec] doMTOMInOutTest
     [exec] Protocol=http
     [exec] Host=localhost
     [exec] portnum=8001
     [exec] port=com.sun.xml.ws.client.EndpointIFInvocationHandler@11e1bbf
     [exec] url=http://localhost:8001/MTOMTestService/text.xml
     [exec] url=http://localhost:8001/MTOMTestService/application.xml
     [exec] url=http://localhost:8001/MTOMTestService/attach.html
     [exec] url=http://localhost:8001/MTOMTestService/attach.jpg
     [exec] Send and receieve 4 documents using MTOM via webservice method mtomInOut()
     [exec] Documents to send: [text.xml,application.xml,attach.html,attach.jpg]
     [exec] Documents to receive: [text2.xml,application2.xml,attach2.html,attach2.jpg]
     [exec] Verify the contents of the received documents
     [exec] url=http://localhost:8001/MTOMTestService/text2.xml
     [exec] url=http://localhost:8001/MTOMTestService/application2.xml
     [exec] url=http://localhost:8001/MTOMTestService/attach2.html
     [exec] url=http://localhost:8001/MTOMTestService/attach2.jpg
     [exec] All received documents are as expected (ok)
     [exec] doMTOMInOutTest PASSED
     [exec] doMTOMOutTest
     [exec] Protocol=http
     [exec] Host=localhost
     [exec] portnum=8001
     [exec] port=com.sun.xml.ws.client.EndpointIFInvocationHandler@c7057c
     [exec] url=http://localhost:8001/MTOMTestService/text.xml
     [exec] url=http://localhost:8001/MTOMTestService/application.xml
     [exec] url=http://localhost:8001/MTOMTestService/attach.html
     [exec] url=http://localhost:8001/MTOMTestService/attach.jpg
     [exec] urls=http://localhost:8001/MTOMTestService/text.xml,http://localhost:8001/MTOMTestService/application.xml,http://localhost:8001/MTOMTestService/attach.html,http://localhost:8001/MTOMTestService/attach.jpg
     [exec] Receive 4 documents using MTOM via webservice method mtomOut()
     [exec] Documents to receive: [text.xml,application.xml,attach.html,attach.jpg]
     [exec] Verify the contents of the received documents
     [exec] All received documents are as expected (ok)
     [exec] doMTOMOutTest PASSED

BUILD SUCCESSFUL
Total time: 24 seconds

Sample code

A sample package which provides the complete example of the techniques covered by this techtip is downloadable from here

The sample package includes the source code, required descriptor files, and the build scripts inorder to build the example.


Steps to install and run the sample:

Step  1. Download GlassFish from the GlassFish Project page.

Step  2. Set the following environment variables:

          ANT_HOME  - path to location of Ant installation. This example uses Ant 1.6.5.
          JAVA_HOME - path to location of JDK5.0 installation.

         Also, add the Ant location to your PATH environment variable.

Step  3. Download the sample package and extract its contents.

     To get started using this techtip all you have to edit is the
     following file:

     o mtomtest/build/common.properties

     The main properties to set are the ones listed below based on your
     glassfish installation properties. You should check the others to ensure
     they are also correct


     <!-- Main Properties to Set -->

     <!-- Only these need be set -->
     <property name="jdk.home" value="/jdk1.5.0"/>
     <property name="appserver.home" value="/sun/appserver9"/>
     <property name="tests.home" value="/home/user/mtomtest"/>
     <property name="webserver.host" value="localhost"/>
     <property name="webserver.port" value="8001"/>

Step  4. Start the GlassFish Application Server 

Step  5. cd mtomtest/src/mtomtest

Step  6. Type the following to build, deploy and run the sample:

         ant

Monday May 15, 2006

Handler example using JAXWS 2.0

This techtip will focus on how to use JAX-WS 2.0 LogicalMessage Handlers and SOAP Handlers to read a message sent from a client to a webservice endpoint and back again. The example code below was developed and tested using a GlassFish implementation.

To understand the configuration and use of handlers in JAX-WS 2.0 you will need to be familiar with the following specifications


JSR 224: JavaTM API for XML-Based Web Services (JAX-WS) 2.0 specification
JSR 109: Implementing Enterprise Web Services

This handler example will demonstrate how to configure 3 kinds of handlers (Service based, Port based, and Protocol based) for both the client and server. These handlers when run, will simply determine which direction the message is traveling and will display the name of the handler that's doing the processing and the contents of the message. This example makes use of customization files to configure the server side handlers and programatic handlers to configure the client side handlers. Although this is a very simplistic example it does show a way of using handlers to intercept a Logical/SOAP message. Certainly the user could expand and enhance this example to do far greater things.

Developing the WebService Server Side Endpoint

Step 1

Create your wsdl description for your webservices endpoint which will send and receive messages.

a) HandlerTestService.wsdl

The following wsdl was used to develop this example. Notice that there is one operation doHandlerTest and one port HandlerPort that have been specified. During the running of this example, there will be one test that will run using the HandlerPort and doHandlerTest operation.


<?xml version="1.0" encoding="UTF-8"?>
<!--
  Copyright 2006 Sun Microsystems, Inc. All rights reserved.
  SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
-->

<definitions 
    name="HandlerTestService"
    targetNamespace="http://HandlerTestService.org/wsdl"
    xmlns:types="http://HandlerTestService.org/types"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://HandlerTestService.org/wsdl"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

  <types>
     <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://HandlerTestService.org/types" targetNamespace="http://HandlerTestService.org/types">
       <complexType name="MyActionType">
            <sequence>
                <element name="inputString" type="xsd:string"/>
            </sequence>
       </complexType>
       <complexType name="MyResultType">
            <sequence>
                <element name="outputString" type="xsd:string"/>
            </sequence>
       </complexType>
    </schema>
  </types>

  <message name="Hello" >
    <part name="action" type="types:MyActionType" />
  </message>
  <message name="HelloResponse">
    <part name="result" type="types:MyResultType" />
  </message>


  <portType name="HandlerPortType">
    <operation name="doHandlerTest">
      <input message="tns:Hello" />
      <output message="tns:HelloResponse" />
    </operation>
  </portType>

  <binding name="HandlerBinding" type="tns:HandlerPortType">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc" />
    <operation name="doHandlerTest">
      <soap:operation soapAction="" />
      <input>
        <soap:body use="literal" namespace="http://HandlerTestService.org/wsdl"/>
      </input>
      <output>
        <soap:body use="literal" namespace="http://HandlerTestService.org/wsdl"/>
      </output>
    </operation>
  </binding>

  <service name="HandlerTestService">
    <port name="HandlerPort" binding="tns:HandlerBinding">
      <soap:address location="http://localhost:8001/HandlerTestService/jaxws/HandlerTest"/>
    </port>
  </service>
</definitions>

Step 2

First, create a customization file for the server side generation.

a) customfile-server.xml


<!--
  Copyright 2006 Sun Microsystems, Inc. All rights reserved.
  SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
--> 

<jaxws:bindings wsdlLocation="wsdl/HandlerTestService.wsdl"  version="2.0" 
    xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb">    

    <jaxws:bindings node="wsdl:definitions">
        <jaxws:package name="handlertest.server"/> 
    </jaxws:bindings>
    
    <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='http://HandlerTestService.org/types']" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
        <jxb:schemaBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
            <jxb:package name="handlertest.server"/> 
        </jxb:schemaBindings>
    </jaxws:bindings>

    <jaxws:bindings>
        <handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
           <!-- ====================== -->
           <!-- service based handlers -->
           <!-- ====================== -->
           <handler-chain>
              <handler>
                  <handler-name>ServerLogicalHandler1</handler-name>
                  <handler-class>handlertest.server.ServerLogicalHandler1</handler-class>
              </handler>
              <handler>
                  <handler-name>ServerSOAPHandler1</handler-name>
                  <handler-class>handlertest.server.ServerSOAPHandler1</handler-class>
              </handler>
           </handler-chain>
           <!-- ====================== -->
           <!-- port based handlers    -->
           <!-- ====================== -->
           <handler-chain>
              <port-name-pattern xmlns:ns1="http://HandlerTestService.org/wsdl">ns1:HandlerPort</port-name-pattern>
              <handler>
                  <handler-name>ServerLogicalHandler2</handler-name>
                  <handler-class>handlertest.server.ServerLogicalHandler2</handler-class>
              </handler>
              <handler>
                  <handler-name>ServerSOAPHandler2</handler-name>
                  <handler-class>handlertest.server.ServerSOAPHandler2</handler-class>
              </handler>
           </handler-chain>
           <!-- ====================== -->
           <!-- protocol based handlers    -->
           <!-- ====================== -->
           <handler-chain>
              <protocol-bindings>##SOAP11_HTTP</protocol-bindings>
              <handler>
                  <handler-name>ServerLogicalHandler3</handler-name>
                  <handler-class>handlertest.server.ServerLogicalHandler3</handler-class>
              </handler>
              <handler>
                  <handler-name>ServerSOAPHandler3</handler-name>
                  <handler-class>handlertest.server.ServerSOAPHandler3</handler-class>
              </handler>
           </handler-chain>
        </handler-chains>
    </jaxws:bindings>
</jaxws:bindings>

b) Run wsimport to generate the server side artifacts using the above customization file.


Execute the command: ant import-wsdl-server

The output follows:

Buildfile: build.xml

import-wsdl-server:

do-wsdl2java:
     [echo] Invoking WsImport task (WSDL-to-Java mapping)
 [wsimport] command line: wsimport /files/jdk/jdk1.5.0_06/jre/bin/java -classpath /files/sun/appserver9.0.pe.promoted/lib/javaee.jar:/files/sun/appserver9.0.pe.promoted/lib/appserv-ws.jar:/home/user/blog/handlertest/classes com.sun.tools.ws.WsImport -d /home/user/blog/handlertest/classes -keep -s /home/user/blog/handlertest/generated -verbose wsdl/HandlerTestService.wsdl -wsdllocation WEB-INF/wsdl/HandlerTestService.wsdl -b /home/user/blog/handlertest/src/handlertest/customfile-server.xml
 [wsimport] handlertest/server/HandlerPortType.java
 [wsimport] handlertest/server/HandlerTestService.java
 [wsimport] handlertest/server/MyActionType.java
 [wsimport] handlertest/server/MyResultType.java
 [wsimport] handlertest/server/ObjectFactory.java
 [wsimport] handlertest/server/package-info.java
 [wsimport] handlertest/server/HandlerPortType.java
 [wsimport] handlertest/server/HandlerTestService.java
 [wsimport] handlertest/server/MyActionType.java
 [wsimport] handlertest/server/MyResultType.java
 [wsimport] handlertest/server/ObjectFactory.java
 [wsimport] handlertest/server/package-info.java

Step 3

Create and implement the code for the webservices server side endpoint along with the various server side handlers.

a) HandlerTestImpl.java


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package handlertest.server;

import javax.jws.WebService;

@WebService(
    portName="HandlerPort",
    targetNamespace="http://HandlerTestService.org/wsdl",
    serviceName="HandlerTestService",
    wsdlLocation="WEB-INF/wsdl/HandlerTestService.wsdl",
    endpointInterface="handlertest.server.HandlerPortType")

public class HandlerTestImpl implements HandlerPortType {
    public MyResultType doHandlerTest(MyActionType action){
        System.out.println("in endpoint");
        System.out.println("MSG="+action.getInputString());
        MyResultType mrt = new MyResultType();
        mrt.setOutputString("endpoint");
        return mrt;
    }
}

b) ServerLogicalHandlerBase.java

The following base class implements all the necessary functionality of a Logical Handler. The actual server side Logical Handlers will extend this class.


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package handlertest.server;

import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.LogicalHandler;
import javax.xml.ws.handler.LogicalMessageContext;
import javax.xml.ws.LogicalMessage;

import javax.xml.transform.OutputKeys;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;

import javax.annotation.PreDestroy;
import javax.annotation.PostConstruct;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;

public class ServerLogicalHandlerBase implements LogicalHandler
{

    private String handlerName=null;
   
    public void setHandlerName(String h) {
        handlerName=h;
    }
    public String getHandlerName() {
        return handlerName;
    }

    @PostConstruct
    public void myInit() {
        System.out.println("in "+handlerName+":myInit");
        System.out.println("exiting "+handlerName+":myInit");
    }

    @PreDestroy
    public void myDestroy() {
        System.out.println("in "+handlerName+":myDestroy");
        System.out.println("exiting "+handlerName+":myDestroy");
    }

    public boolean handleMessage(LogicalMessageContext context)
    {
        System.out.println("in "+handlerName+":handleMessage");

        boolean direction= ((Boolean)context.get(LogicalMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();
        if (direction) {
            System.out.println("direction = outbound");
        } else {
            System.out.println("direction = inbound");
        }

        dumpMsg(context);

        System.out.println("exiting "+handlerName+":handleMessage");
        return true;
    }

    public void close(MessageContext context)
    {
        System.out.println("in "+handlerName+":close");
        System.out.println("exiting "+handlerName+":close");
    }

    public boolean handleFault(LogicalMessageContext context)
    {
        System.out.println("in "+handlerName+":handleFault");
        System.out.println("exiting "+handlerName+":handleFault");
        return true;
    }

    public void dumpMsg(MessageContext context) {
        System.out.println("in "+handlerName+":dumpMsg");

        try {
            LogicalMessage lm = ((LogicalMessageContext)context).getMessage();
            if (lm != null) {
                Source source = lm.getPayload();
                if (source != null) {
                    System.out.println("MSG="+getSourceAsString(source));
                } else {
                    System.out.println("No message payload was present");
                }
            } else {
               System.out.println("No message was present");
            }
        } catch (Exception e) {
              e.printStackTrace();
        }

        System.out.println("exiting "+handlerName+":dumpMsg");


       return;
    }

    public String getSourceAsString(Source s) throws Exception {
        System.out.println("in "+handlerName+":getSourceAsString");

        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        OutputStream out = new ByteArrayOutputStream();
        StreamResult streamResult = new StreamResult();
        streamResult.setOutputStream(out);
        transformer.transform(s, streamResult);

        System.out.println("exiting "+handlerName+":getSourceAsString");
        return streamResult.getOutputStream().toString();
    }
}

c) ServerSOAPHandlerBase.java

The following base class implements all the necessary functionality of a SOAP Handler. The actual server side SOAP Handlers will extend this class.


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package handlertest.server;

import javax.xml.transform.Source;
import java.util.Set;
import java.util.TreeSet;
import javax.annotation.PreDestroy;
import javax.annotation.PostConstruct;

import javax.xml.namespace.QName;

import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.soap.SOAPMessage;

import java.io.ByteArrayOutputStream;

public class ServerSOAPHandlerBase implements SOAPHandler
{
    private String handlerName=null;

    public void setHandlerName(String h) {
        handlerName=h;
    }
    public String getHandlerName() {
        return handlerName;
    }

    @PostConstruct
    public void myInit() {
        System.out.println("in "+handlerName+":myInit");
        System.out.println("exiting "+handlerName+":myInit");
    }

    @PreDestroy
    public void myDestroy() {
        System.out.println("in "+handlerName+":myDestroy");
        System.out.println("exiting "+handlerName+":myDestroy");
    }

    public Set getHeaders() {
        return new TreeSet();
    }

    public boolean handleMessage(SOAPMessageContext context)
    {
        System.out.println("in "+handlerName+":handleMessage");

        boolean direction= ((Boolean)context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();
        if (direction) {
            System.out.println("direction = outbound");
        } else {
            System.out.println("direction = inbound");
        } 

        dumpMsg(context);
        
        System.out.println("exiting "+handlerName+":handleMessage");
        return true;
    }

    public void close(MessageContext context)
    {
        System.out.println("in "+handlerName+":close");
        System.out.println("exiting "+handlerName+":close");
    }

    public boolean handleFault(SOAPMessageContext context)
    {
        System.out.println("in "+handlerName+":handleFault");
        System.out.println("exiting "+handlerName+":handleFault");
        return true;
    }


    public void dumpMsg(MessageContext context) {
       System.out.println("in "+handlerName+":dumpMsg");
       try {
          System.out.println("in "+handlerName+":dumpMsg");
          SOAPMessage soapmsg = ((SOAPMessageContext)context).getMessage();
          System.out.println("MSG="+getMsgAsString(soapmsg));

       } catch (Exception e) {
           e.printStackTrace();
       }
       System.out.println("exiting "+handlerName+":dumpMsg");
       return;
    }


    public String getMsgAsString(SOAPMessage message) {
        System.out.println("in "+handlerName+":getMsgAsString");
        String msg  = null;
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            message.writeTo(baos);
            msg = baos.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("exiting "+handlerName+":getMsgAsString");
        return msg;
    }
}

d) ServerLogicalHandler1.java

The following handler extends the Logical Handler base class. The remaining Logical Handlers are identical to this hander except for the name. For brevity, I won't list the code here but you will be able to download the entire example at the end of this blog.


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package handlertest.server;

public class ServerLogicalHandler1 extends ServerLogicalHandlerBase
{
    private final String HANDLERNAME="ServerLogicalHandler1";

    public ServerLogicalHandler1(){
       super();
       super.setHandlerName(HANDLERNAME);
    }
}
e) ServerSOAPHandler1.java

The following handler extends the Logical Handler base class. The remaining Logical Handlers are identical to this hander except for the name. For brevity, I won't list the code here but you will be able to download the entire example at the end of this blog.


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package handlertest.server;

public class ServerSOAPHandler1 extends ServerSOAPHandlerBase
{
    private final String HANDLERNAME="ServerSOAPHandler1";

    public ServerSOAPHandler1(){
       super();
       super.setHandlerName(HANDLERNAME);
    }
}
Step 4

Build and compile the webservices server side endpoint code and package it in a war file.


Execute the command:ant compile-server create-war

The output follows:

compile-server:
     [echo] compile-server
    [javac] Compiling 9 source files to /home/user/blog/handlertest/classes

compile-server-w2j:
     [echo] compile-server-w2j

create-war:
     [echo] create-war
     [echo] Creating war file /home/user/blog/handlertest/dist/handlertest/HandlerTestService.war
      [war] Building war: /home/user/blog/handlertest/dist/handlertest/HandlerTestService.war
     [echo] Created war file /home/user/blog/handlertest/dist/handlertest/HandlerTestService.war

build-server-w2j:

build-server:
Step 5

Deploy the webservices endpoint packaged in the war to a GlassFish appserver environment.


Execute the command:ant deploy

The output follows:

Buildfile: build.xml

checkPlatform:

configUnix:

configWindows:

filter.password.file:
     [copy] Copying 1 file to /home/user/blog/handlertest/build

configPlatform:

deploy:
     [echo] deploy
     [echo] Deploying /home/user/blog/handlertest/dist/handlertest/HandlerTestService.war.
     [echo] asadmin deploy --user admin --passwordfile /home/user/blog/handlertest/build/password.txt --host localhost --port 4848 --contextroot HandlerTestService --target server --updload=true
     [exec] Command deploy executed successfully.
Step 6 Verify web service application is deployed:

In your browser go to URL location of the published WSDL for this server:


o http://host:port/HandlerTestService/jaxws/HandlerTest?WSDL

where host and port are the settings of your configured GlassFish web server host and port settings, HandlerTestService is the context root of your web service application, /jaxws/HandlerTest is the URL alias specified in the web.xml deployment descriptor for deployed endpoint and ?WSDL is how the published WSDL is accessed.

A WSDL should be displayed if the service is up and running.

Developing WebServices Client Side code

Step 1

Run wsimport to generate the client side artifacts to communicate with the webservices endpoint developed in previous section pointing to the wsdl of the deployed endpoint on a GlassFish appserver environment.

a) First create the customization file for the client side generation.

customfile-client.xml


<!--
  Copyright 2006 Sun Microsystems, Inc. All rights reserved.
  SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
-->

<jaxws:bindings wsdlLocation="wsdl/HandlerTestService.wsdl"  version="2.0" 
    xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb">    
   
    <jaxws:bindings node="wsdl:definitions">
        <jaxws:package name="handlertest.client"/>
    </jaxws:bindings>
 
    <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='http://HandlerTestService.org/types']" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
        <jxb:schemaBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
            <jxb:package name="handlertest.client"/> 
        </jxb:schemaBindings>
    </jaxws:bindings>
</jaxws:bindings>

b) Run wsimport to generate the client side artifacts to communicate with the endpoint developed in the previous section pointing to the wsdl of the deployed endpoint on a GlassFish appserver environment using the above customization file.


Execute the command:ant import-wsdl-client

The output follows:

Buildfile: build.xml

import-wsdl-client:

do-wsdl2java:
     [echo] Invoking WsImport task (WSDL-to-Java mapping)
 [wsimport] command line: wsimport /files/jdk/jdk1.5.0_06/jre/bin/java -classpath /files/sun/appserver9.0.pe.promoted/lib/javaee.jar:/files/sun/appserver9.0.pe.promoted/lib/appserv-ws.jar:/home/user/blog/handlertest/classes com.sun.tools.ws.WsImport -d /home/user/blog/handlertest/classes -keep -s /home/user/blog/handlertest/generated -verbose wsdl/HandlerTestService.wsdl -wsdllocation http://localhost:8001/HandlerTestService/jaxws/HandlerTest?WSDL -b /home/user/blog/handlertest/src/handlertest/customfile-client.xml
 [wsimport] handlertest/client/HandlerPortType.java
 [wsimport] handlertest/client/HandlerTestService.java
 [wsimport] handlertest/client/MyActionType.java
 [wsimport] handlertest/client/MyResultType.java
 [wsimport] handlertest/client/ObjectFactory.java
 [wsimport] handlertest/client/package-info.java
 [wsimport] handlertest/client/HandlerPortType.java
 [wsimport] handlertest/client/HandlerTestService.java
 [wsimport] handlertest/client/MyActionType.java
 [wsimport] handlertest/client/MyResultType.java
 [wsimport] handlertest/client/ObjectFactory.java
 [wsimport] handlertest/client/package-info.java
Step 3

Create the client code to communicate with the deployed endpoint and the various client side handlers.

a) Client.java


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package handlertest.client;

import java.io.\*;
import java.net.\*;
import java.util.\*;
import javax.xml.soap.\*;

import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.WebServiceRef;

import javax.xml.namespace.QName;


public class Client {
    private static HandlerPortType port = null;

    @WebServiceRef
    private static HandlerTestService service = null;

    public static void main(String[] args ) {
	Client client = new Client();

	System.out.println("------------------------------------------");
	System.out.println("Executing Tests");
	System.out.println("------------------------------------------");
	client.doHandlersTest();
    }

    public void doHandlersTest() {
	 System.out.println("doHandlersTest");
	 boolean pass = true;

      final String THEBINDINGPROTOCOL = javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING;
      final String NAMESPACEURI = "http://HandlerTestService.org/wsdl";
      final String PORT_NAME    = "HandlerPort";
      final QName PORT_QNAME = new QName(NAMESPACEURI, PORT_NAME);


	 System.out.println("Configuring client side handlers");
      service.setHandlerResolver(new HandlerResolver() {
        public List<Handler> getHandlerChain(PortInfo info) {
           List<Handler> handlerList = new ArrayList<Handler>();
           System.out.println("--------------------------------------------------");
           System.out.println("Registering the following service based handlers:"); 
           System.out.println("ClientSOAPHandler1, ClientLogicalHandler1");
           System.out.println("--------------------------------------------------");
           System.out.println("Construct HandleInfo for ClientSOAPHandler1 and add to HandlerChain");
           Handler handler = new handlertest.client.ClientSOAPHandler1();
           handlerList.add(handler);
           System.out.println("Construct HandleInfo for ClientLogicalHandler1 and add to HandlerChain");
           handler = new handlertest.client.ClientLogicalHandler1();
           handlerList.add(handler);
           if (info.getBindingID().equals(THEBINDINGPROTOCOL)) {
               System.out.println("--------------------------------------------------");
               System.out.println("Registering the following protocol based handlers:"); 
               System.out.println("ClientSOAPHandler2, ClientLogicalHandler2");
               System.out.println("--------------------------------------------------");
               System.out.println("Construct HandleInfo for ClientSOAPHandler2 and add to HandlerChain");
               handler = new handlertest.client.ClientSOAPHandler2();
               handlerList.add(handler);
               System.out.println("Construct HandleInfo for ClientLogicalHandler2 and add to HandlerChain");
               handler = new handlertest.client.ClientLogicalHandler2();
               handlerList.add(handler);
           }
           if (info.getPortName().equals(PORT_QNAME)) {
               System.out.println("--------------------------------------------------");
               System.out.println("Registering the following port based handler:"); 
               System.out.println("ClientSOAPHandler3");
               System.out.println("--------------------------------------------------");
               System.out.println("Construct HandleInfo for ClientSOAPHandler3 and add to HandlerChain");
               handler = new handlertest.client.ClientSOAPHandler3();
               handlerList.add(handler);
           }
           System.out.println("HandlerChainList="+handlerList);
           System.out.println("HandlerChain size = " + handlerList.size());
           return handlerList;
        }
 
     });
	
     port = service.getHandlerPort();
	System.out.println("port="+port);

     String expected="endpoint";

	try {
         MyActionType request = new MyActionType();
         request.setInputString("client");
	    MyResultType response = port.doHandlerTest(request);
         String actual = response.getOutputString();
         System.out.println("result="+actual);
         if (!actual.equals(expected)){
	       pass = false;
         }
	} catch(Exception e) {
	    System.err.println("Caught exception: " + e.getMessage());
            e.printStackTrace(System.err);
	    pass = false;
 	}
	if (pass)
	    System.out.println("doHandlersTest PASSED");
	else
	    System.err.println("doHandlersTest FAILED");
    }
}

b) ClientLogicalHandlerBase.java

The following base class implements all the necessary functionality of a Logical Handler. The actual client side Logical Handlers will extend this class.


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package handlertest.client;

import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.LogicalHandler;
import javax.xml.ws.handler.LogicalMessageContext;
import javax.xml.ws.LogicalMessage;

import javax.xml.transform.OutputKeys;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;

import javax.annotation.PreDestroy;
import javax.annotation.PostConstruct;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;

public class ClientLogicalHandlerBase implements LogicalHandler<LogicalMessageContext>
{

    private String handlerName=null;
   
    public void setHandlerName(String h) {
        this.handlerName=h;
    }
    public String getHandlerName() {
        return this.handlerName;
    }

    @PostConstruct
    public void myInit() {
        System.out.println("------------------------------------");
        System.out.println("in "+handlerName+":myInit");
        System.out.println("exiting "+handlerName+":myInit");
        System.out.println("------------------------------------");
    }

    @PreDestroy
    public void myDestroy() {
        System.out.println("------------------------------------");
        System.out.println("in "+handlerName+":myDestroy");
        System.out.println("exiting "+handlerName+":myDestroy");
        System.out.println("------------------------------------");
    }

    public boolean handleMessage(LogicalMessageContext context) {
        System.out.println("------------------------------------");
        System.out.println("in "+handlerName+":handleMessage");

        boolean direction= ((Boolean)context.get(LogicalMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();
        if (direction) {
            System.out.println("direction = outbound");
        } else {
            System.out.println("direction = inbound");
        }

        dumpMsg(context);

        System.out.println("exiting "+handlerName+":handleMessage");
        System.out.println("------------------------------------");
        return true;
    }

    public void close(MessageContext context) {
        System.out.println("------------------------------------");
        System.out.println("in "+handlerName+":close");
        System.out.println("exiting "+handlerName+":close");
        System.out.println("------------------------------------");
    }

    public boolean handleFault(LogicalMessageContext context) {
        System.out.println("------------------------------------");
        System.out.println("in "+handlerName+":handleFault");
        System.out.println("exiting "+handlerName+":handleFault");
        System.out.println("------------------------------------");
        return true;
    }

    public void dumpMsg(MessageContext context) {
        try {
            LogicalMessage lm = ((LogicalMessageContext)context).getMessage();
            if (lm != null) {
                Source source = lm.getPayload();
                if (source != null) {
                    System.out.println("MSG="+getSourceAsString(source));
                } else {
                    System.out.println("No message payload was present");
                }
            } else {
               System.out.println("No message was present");
            }
        } catch (Exception e) {
              e.printStackTrace();
        }
        return;
    }

    public String getSourceAsString(Source s) throws Exception {
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        OutputStream out = new ByteArrayOutputStream();
        StreamResult streamResult = new StreamResult();
        streamResult.setOutputStream(out);
        transformer.transform(s, streamResult);

        return streamResult.getOutputStream().toString();
    }
}

c) ClientSOAPHandlerBase.java

The following base class implements all the necessary functionality of a SOAP Handler. The actual client side SOAP Handlers will extend this class.


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package handlertest.client;

import javax.xml.transform.Source;
import java.util.Set;
import java.util.TreeSet;
import javax.annotation.PreDestroy;
import javax.annotation.PostConstruct;

import javax.xml.namespace.QName;

import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.soap.SOAPMessage;

import java.io.ByteArrayOutputStream;

public class ClientSOAPHandlerBase implements SOAPHandler<SOAPMessageContext>
{

    private String handlerName=null;

    public void setHandlerName(String h) {
        this.handlerName=h;
    }
    public String getHandlerName() {
        return this.handlerName;
    }

    @PostConstruct
    public void myInit() {
        System.out.println("------------------------------------");
        System.out.println("in "+handlerName+":myInit");
        System.out.println("exiting "+handlerName+":myInit");
        System.out.println("------------------------------------");
    }

    @PreDestroy
    public void myDestroy() {
        System.out.println("------------------------------------");
        System.out.println("in "+handlerName+":myDestroy");
        System.out.println("exiting "+handlerName+":myDestroy");
        System.out.println("------------------------------------");
    }

    public Set<QName> getHeaders() {
        return new TreeSet<QName>();
    }

    public boolean handleMessage(SOAPMessageContext context) {
        System.out.println("------------------------------------");
        System.out.println("in "+handlerName+":handleMessage");

        boolean direction= ((Boolean)context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue();
        if (direction) {
            System.out.println("direction = outbound");
        } else {
            System.out.println("direction = inbound");
        } 

        dumpMsg(context);
        
        System.out.println("exiting "+handlerName+":handleMessage");
        System.out.println("------------------------------------");
        return true;
    }

    public void close(MessageContext context) {
        System.out.println("------------------------------------");
        System.out.println("in "+handlerName+":close");
        System.out.println("exiting "+handlerName+":close");
        System.out.println("------------------------------------");
    }

    public boolean handleFault(SOAPMessageContext context) {
        System.out.println("------------------------------------");
        System.out.println("in "+handlerName+":handleFault");
        System.out.println("exiting "+handlerName+":handleFault");
        System.out.println("------------------------------------");
        return true;
    }


    public void dumpMsg(MessageContext context) {
       try {
          SOAPMessage soapmsg = ((SOAPMessageContext)context).getMessage();
          System.out.println("MSG="+getMsgAsString(soapmsg));

       } catch (Exception e) {
           e.printStackTrace();
       }
       return;
    }


    public String getMsgAsString(SOAPMessage message) {
        String msg  = null;
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            message.writeTo(baos);
            msg = baos.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return msg;
    }
}

d) ClientLogicalHandler1.java

The following handler extends the Logical Handler base class. The remaining Logical Handlers are identical to this hander except for the name. For brevity, I won't list the code here but you will be able to download the entire example at the end of this blog.


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package handlertest.client;

public class ClientLogicalHandler1 extends ClientLogicalHandlerBase
{
    private final String HANDLERNAME="ClientLogicalHandler1";

    public ClientLogicalHandler1(){
       super();
       super.setHandlerName(HANDLERNAME);
    }
}

e) ClientSOAPHandler1.java

The following handler extends the SOAP Handler base class. The remaining Logical Handlers are identical to this hander except for the name. For brevity, I won't list the code here but you will be able to download the entire example at the end of this blog.


/\*
 \* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 \* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 \*/

package handlertest.client;

public class ClientSOAPHandler1 extends ClientSOAPHandlerBase
{
    private final String HANDLERNAME="ClientSOAPHandler1";

    public ClientSOAPHandler1(){
       super();
       super.setHandlerName(HANDLERNAME);
    }
}
Step 3

Build and compile the client code.


Execute the command:ant compile-client

The output follows:

Buildfile: build.xml

compile-client:
     [echo] compile-client
    [javac] Compiling 9 source files to /home/user/blog/handlertest/classes
Step 4

Run the client code which will communicate with the deployed webservices endpoint


Execute the command:ant runclient

The output follows:

Buildfile: build.xml

checkPlatform:

configUnix:

configWindows:

filter.password.file:
     [copy] Copying 1 file to /home/user/blog/handlertest/build

configPlatform:

runclient:
     [echo] runclient handlertest.client.Client
     [exec] ------------------------------------------
     [exec] Executing Tests
     [exec] ------------------------------------------
     [exec] doHandlersTest
     [exec] Configuring client side handlers
     [exec] --------------------------------------------------
     [exec] Registering the following service based handlers:
     [exec] ClientSOAPHandler1, ClientLogicalHandler1
     [exec] --------------------------------------------------
     [exec] Construct HandleInfo for ClientSOAPHandler1 and add to HandlerChain
     [exec] Construct HandleInfo for ClientLogicalHandler1 and add to HandlerChain
     [exec] --------------------------------------------------
     [exec] Registering the following protocol based handlers:
     [exec] ClientSOAPHandler2, ClientLogicalHandler2
     [exec] --------------------------------------------------
     [exec] Construct HandleInfo for ClientSOAPHandler2 and add to HandlerChain
     [exec] Construct HandleInfo for ClientLogicalHandler2 and add to HandlerChain
     [exec] --------------------------------------------------
     [exec] Registering the following port based handler:
     [exec] ClientSOAPHandler3
     [exec] --------------------------------------------------
     [exec] Construct HandleInfo for ClientSOAPHandler3 and add to HandlerChain
     [exec] HandlerChainList=[handlertest.client.ClientSOAPHandler1@3fa6cd, handlertest.client.ClientLogicalHandler1@dfe303, handlertest.client.ClientSOAPHandler2@b0ede5, handlertest.client.ClientLogicalHandler2@1d27069, handlertest.client.ClientSOAPHandler3@d22462]
     [exec] HandlerChain size = 5
     [exec] port=com.sun.xml.ws.client.EndpointIFInvocationHandler@17b1d64
     [exec] ------------------------------------
     [exec] in ClientLogicalHandler1:handleMessage
     [exec] direction = outbound
     [exec] MSG=<ans:doHandlerTest xmlns:ans="http://HandlerTestService.org/wsdl"><action><inputString>client</inputString></action></ans:doHandlerTest>
     [exec] exiting ClientLogicalHandler1:handleMessage
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientLogicalHandler2:handleMessage
     [exec] direction = outbound
     [exec] MSG=<ans:doHandlerTest xmlns:ans="http://HandlerTestService.org/wsdl"><action><inputString>client</inputString></action></ans:doHandlerTest>
     [exec] exiting ClientLogicalHandler2:handleMessage
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientSOAPHandler1:handleMessage
     [exec] direction = outbound
     [exec] MSG=<?xml version="1.0" ?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soapenv:Body><ans:doHandlerTest xmlns:ans="http://HandlerTestService.org/wsdl"><action><inputString>client</inputString></action></ans:doHandlerTest></soapenv:Body></soapenv:Envelope>
     [exec] exiting ClientSOAPHandler1:handleMessage
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientSOAPHandler2:handleMessage
     [exec] direction = outbound
     [exec] MSG=<?xml version="1.0" ?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soapenv:Body><ans:doHandlerTest xmlns:ans="http://HandlerTestService.org/wsdl"><action><inputString>client</inputString></action></ans:doHandlerTest></soapenv:Body></soapenv:Envelope>
     [exec] exiting ClientSOAPHandler2:handleMessage
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientSOAPHandler3:handleMessage
     [exec] direction = outbound
     [exec] MSG=<?xml version="1.0" ?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soapenv:Body><ans:doHandlerTest xmlns:ans="http://HandlerTestService.org/wsdl"><action><inputString>client</inputString></action></ans:doHandlerTest></soapenv:Body></soapenv:Envelope>
     [exec] exiting ClientSOAPHandler3:handleMessage
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientSOAPHandler3:handleMessage
     [exec] direction = inbound
     [exec] MSG=<?xml version="1.0" ?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soapenv:Body><ans:doHandlerTestResponse xmlns:ans="http://HandlerTestService.org/wsdl"><result><outputString>endpoint</outputString></result></ans:doHandlerTestResponse></soapenv:Body></soapenv:Envelope>
     [exec] exiting ClientSOAPHandler3:handleMessage
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientSOAPHandler2:handleMessage
     [exec] direction = inbound
     [exec] MSG=<?xml version="1.0" ?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soapenv:Body><ans:doHandlerTestResponse xmlns:ans="http://HandlerTestService.org/wsdl"><result><outputString>endpoint</outputString></result></ans:doHandlerTestResponse></soapenv:Body></soapenv:Envelope>
     [exec] exiting ClientSOAPHandler2:handleMessage
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientSOAPHandler1:handleMessage
     [exec] direction = inbound
     [exec] MSG=<?xml version="1.0" ?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soapenv:Body><ans:doHandlerTestResponse xmlns:ans="http://HandlerTestService.org/wsdl"><result><outputString>endpoint</outputString></result></ans:doHandlerTestResponse></soapenv:Body></soapenv:Envelope>
     [exec] exiting ClientSOAPHandler1:handleMessage
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientLogicalHandler2:handleMessage
     [exec] direction = inbound
     [exec] MSG=<ans:doHandlerTestResponse xmlns:ans="http://HandlerTestService.org/wsdl"><result><outputString>endpoint</outputString></result></ans:doHandlerTestResponse>
     [exec] exiting ClientLogicalHandler2:handleMessage
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientLogicalHandler1:handleMessage
     [exec] direction = inbound
     [exec] MSG=<ans:doHandlerTestResponse xmlns:ans="http://HandlerTestService.org/wsdl"><result><outputString>endpoint</outputString></result></ans:doHandlerTestResponse>
     [exec] exiting ClientLogicalHandler1:handleMessage
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientSOAPHandler3:close
     [exec] exiting ClientSOAPHandler3:close
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientSOAPHandler2:close
     [exec] exiting ClientSOAPHandler2:close
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientSOAPHandler1:close
     [exec] exiting ClientSOAPHandler1:close
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientLogicalHandler2:close
     [exec] exiting ClientLogicalHandler2:close
     [exec] ------------------------------------
     [exec] ------------------------------------
     [exec] in ClientLogicalHandler1:close
     [exec] exiting ClientLogicalHandler1:close
     [exec] ------------------------------------
     [exec] result=endpoint
     [exec] doHandlersTest PASSED

Note: If you examine the output of the appservers server.log file, you will see similar output as that displayed by the client

Sample code

A sample package which provides the complete example of the techniques covered by this techtip is downloadable from here

The sample package includes the source code, required descriptor files, and the build scripts inorder to build the example.


Steps to install and run the sample:

Step  1. Download GlassFish from the GlassFish Project page.

Step  2. Set the following environment variables:

          ANT_HOME  - path to location of Ant installation. This example uses Ant 1.6.5.
          JAVA_HOME - path to location of JDK5.0 installation.

         Also, add the Ant location to your PATH environment variable.

Step  3. Download the sample package and extract its contents.

	To get started using this techtip all you have to edit is the
	following file:
	
	o handlertest/build/common.properties
	
	The main properties to set are the ones listed below based on your
	glassfish installation properties. You should check the others to ensure
	they are also correct
	
	
	<!-- Main Properties to Set -->

	<!-- Only these need be set -->
	<property name="jdk.home" value="/files/java/jdk1.5.0"/>
	<property name="appserver.home" value="/sun/appserver9"/>
	<property name="tests.home" value="/home/user/handlertest"/>
	<property name="webserver.host" value="localhost"/>
	<property name="webserver.port" value="8001"/>

Step  4. Start the GlassFish Application Server 

Step  5. cd handlertest/src/handlertest

Step  6. Type the following to build, deploy and run the sample:

         ant
About

sdimilla

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today