JAX-WS Tutorial

JAVA / GLASSFISH / WEB SERVICES

The objective of this tutorial is to install a glassfish/jdk/jax-ws bundle in a Windows XP environment, and get a "hello world" web service/client up and running using command line tools only, without taking any shortcuts, thereby creating an extensible basis for a real solution.

Using Command Line Tools versus Ant

Since this is a tutorial, we're going to do each step from the command prompt, just to see how everything works. However, I've added a section at the end, which automates each step using Ant, which makes sense for a real/practical project.

Create a Development Directory Structure

Create the following directories (or something similar):

C:\dev\downloads
C:\dev\projects\jax-ws\src\client
C:\dev\projects\jax-ws\src\endpoint

Download the Java EE SDK

Go to JAVA.SUN.COM/JAVAEE and find the "Download Java EE SDK" link.
Various bundles are available.
For this tutorial, download the "Glassfish Java EE + JDK" bundle, which at the time of writing is about 170 MB. This contains everything you need.
Save the java_ee_sdk-5_07-windows.exe file to C:\dev\downloads and run it.

Installation Steps

1. Welcome - [Next]
2. Software License Agreement - Yes - [Next]
3. Installation Directory - "C:\Sun\SDK" - [Next]
4. Admin Configuration - choose a password (e.g. "glassfish") - [Next]

        TAKE NOTE OF THE PORT NUMBERS: ADMIN 4848, HTTP 8080, HTTPS 8181

5. Intallation Options - accept default options - [Next]
6. Ready to install - [Install Now]
7. Registration Options - skip registration - [Next]
8. [Finish]

The install program should have modified the PATH environment variable of your system (by adding C:\Sun\SDK\bin); you may need to reboot your machine for this to take effect.

Check the Glassfish Server is Installed and Running

You can now start glassfish from the Start menu:
    Start » Programs » Sun Microsystems » Java EE 5 SDK » Start Default Server

In a browser, go to http://localhost:8080/ and you should get a Your GlassFish Enterprise Server is now running message.

Create the Service Endpoint

The endpoint "services" a call made from a client to the service. All our example endpoint is going to do is accept a String as an input parameter, tack the word "Hello" on to the front of the String, and return it to the client.

Create the following Hello class in the endpoint directory:

package endpoint;

import javax.jws.WebService;

@WebService
public class Hello {
    public String getHello(String name) {
        return "Hello " + name + "!";
    }
}

Now, we're going to compile this class, and deploy it to Glassfish.

In a Command Prompt window, perform these steps:

    cd c:\dev\projects\jax-ws

    c:\sun\sdk\jdk\bin\javac
        -cp c:\sun\sdk\lib\j2ee.jar
        -d c:\sun\sdk\domains\domain1\autodeploy
        src\endpoint\*


This cd's to the jax-ws directory, and compiles the endpoint.

However, note that the output of the compilation is sent to the autodeploy directory belonging to domain1 (the default domain that was created when you installed Glassfish).

To check that the compile/deploy succeeded, look in the C:\Sun\SDK\domains\domain1\autodeploy\endpoint directory, and you should see both a Hello.class and a Hello.class_deployed file. The _deployed file was created by Glassfish as a response to the deployment.

If there is no _deployed or _deployFailed file, check that auto-deploy feature is enabled in Glassfish. To do that: go to http://localhost:4848/ (the Glassfish Administration Console), login as user name (case sensitive) admin and password glassfish (or whatever password you set during the installation); click on the Application Server component; click on the Advanced tab; and check that both the Reload and Auto Deploy checkboxes are checked, and that the Auto Deploy Directory is correctly set to C:/Sun/SDK/domains/domain1/autodeploy — note the forward slashes, even though this is an XP environment.

Check the Hello Service WSDL

In a browser, go to http://localhost:8080/Hello/HelloService?wsdl and Glassfish should reply with a chunk of XML; this XML is actually the WSDL (Web Service Definition Language) that describes the Hello service.

In the next step, we're going to use this WSDL to automatically generate the "artifacts" required by a client to call the service.

Generate JAX-WS Portable Artifacts

In a Command Prompt window, perform these steps:

    cd c:\dev\projects\jax-ws

    mkdir build

    c:\sun\sdk\bin\wsimport -keep -d build
        http://localhost:8080/Hello/HelloService?wsdl


This cd's to the jax-ws directory, creates a new build directory to contain the artifacts, and then runs the wsimport tool. Note that it's a good idea to delete and recreate the build directory, before you run wsimport, each time.

You should get parsing WSDL... generating code... compiling code... messages.

We're now ready to create a client.

Create the Client

The client program does nothing more than call the service and print the response.

Create the following Client class in the client directory:

package client;

import javax.xml.ws.WebServiceRef;
import endpoint.HelloService;
import endpoint.Hello;

public class Client {

    @WebServiceRef(wsdlLocation=
            "http://localhost:8080/Hello/HelloService?WSDL")
    static HelloService service;
    
    public static void main(String[] args) {
        new Client().hello();
    }
    
    public void hello() {
        try {
            String name = System.getProperty("user.name");
            Hello port = service.getHelloPort();
            System.out.println(
                    "Hello result = " + port.getHello(name));
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

To compile this class, perform these steps:

    cd c:\dev\projects\jax-ws

    c:\sun\sdk\jdk\bin\javac
        -cp c:\sun\sdk\lib\j2ee.jar;build
        -d build
        src\client\*


We can now test the client and the service...

Calling the Service from the Command Line

To run the client program, perform these steps:

    cd c:\dev\projects\jax-ws\build

    appclient client.Client


This cd's to the build directory, and then runs the client using the appclient tool.

The appclient tool sets up a dauntingly complex runtime environment for the VM that's capable of making a JAX-WS call to the web service, before going ahead and actually calling the Client class. To Do: just how much of that environment is really necessary for this simple example would be something worth investigating.

You should see a message like:

    Hello result = Hello [user.name]!

That's it! It works!


Using Ant with JAX-WS

BUILDING THE SERVICE AND CLIENT USING ANT

Automated Compile/Deploy/Generate

It is cumbersome to manually perform each step shown above during the development of a real web service. To automate everything, we can use Ant.

Open a Command Prompt window. Type asant. You should get a build.xml does not exist message (if not, check that asant.bat exists within the C:\Sun\SDK\bin directory, and that C:\Sun\SDK\bin is in the PATH environment variable).

What is asant? It's just an Ant wrapper that sets up the Application Server environment before running Ant; hence the name A-S-Ant.

So, now we need to create a build.xml file, to configure Ant for this project. The contents of the required build.xml can seem somewhat mysterious at first, if you are unfamiliar with Ant; however, the steps just replicate the command line steps in the previous tutorial — it is mostly obvious what's going on once you examine the file in detail. Needless to say, understanding the build.xml file, at least at a high-level, is the key to understanding how to work with JAX-WS.

Create the following build.xml file in the jax-ws directory:

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

<project name="jax-ws" default="run-client" basedir=".">

  <property name="javaee.home" value="C:/Sun/SDK"/>
  <property name="javaee.domaindir" value="C:/Sun/SDK/domains/domain1"/>
  <property name="autodeploydir" value="${javaee.domaindir}/autodeploy"/>
  <property name="classesdir" value="./build"/>

  <target name="compile-deploy-service">
    <javac srcdir="./src"
      includes="endpoint/**" destdir="${autodeploydir}"
      classpath="${javaee.home}/lib/j2ee.jar"/>
    <waitfor maxwait="30" maxwaitunit="second">
      <or>
        <available file="${autodeploydir}/endpoint/Hello.class_deployed"/>
        <available file="${autodeploydir}/endpoint/Hello.class_deployFailed"/>
      </or>
    </waitfor>
  </target>

  <target name="get-artifacts" depends="compile-deploy-service">
    <delete dir="${classesdir}"/>
    <mkdir dir="${classesdir}"/>
    <exec executable="${javaee.home}/bin/wsimport.bat">
      <arg line="-keep -d ${classesdir} http://localhost:8080/Hello/HelloService?wsdl"/>
    </exec>
  </target>

  <target name="compile-client" depends="get-artifacts">
    <javac srcdir="./src/client" destdir="${classesdir}"
        classpath="${javaee.home}/lib/j2ee.jar;${classesdir}"/>
  </target>
    
  <target name="run-client" depends="compile-client">
    <exec executable="${javaee.home}/bin/appclient.bat" dir="${classesdir}">
      <arg value="client.Client"/>
    </exec>
  </target>

</project>


In a Command Prompt window, type:

    cd c:\dev\projects\jax-ws

    asant run-client


This, obviously, cd's to the directory that contains the new build.xml file you've created, and runs asant which hits the run-client target. Since that target depends on the preceeding targets, one by one, all the targets are hit: the service gets compiled and deployed; the ws artifacts are created; the client is compiled; and, finally, the client gets executed.



HOME

INFO

CONTACT

MORE

FOOLISHNESS

LINKS

SITE MAP

Copyright © 2009 Andrew Carson. All Rights Reserved.  CSS2-3 Validated.