Links: Table of Contents | Single HTML | Single PDF

Chapter 14. WSIT Example Using a Web Container Without NetBeans IDE

Table of Contents

14.1. Environment Configuration Settings
14.1.1. Setting the Web Container Listener Port
14.1.2. Setting the Web Container Home Directory
14.2. WSIT Configuration and WS-Policy Assertions
14.3. Creating a Web Service without NetBeans
14.3.1. Creating a Web Service From Java
14.3.2. Creating a Web Service From WSDL
14.4. Building and Deploying the Web Service
14.4.1. Building and Deploying a Web Service Created From Java
14.4.2. Building and Deploying a Web Service Created From WSDL
14.4.3. Deploying the Web Service to a Web Container
14.4.4. Verifying Deployment
14.5. Creating a Web Service Client
14.5.1. Creating a Client from Java
14.5.2. Creating a Client from WSDL
14.6. Building and Deploying a Client
14.7. Running a Web Service Client
14.8. Undeploying a Web Service

14.1. Environment Configuration Settings

Before you can build and run the samples in this tutorial, you need to complete the following tasks:

14.1.1. Setting the Web Container Listener Port

The Java code and configuration files for the examples used in this tutorial assume that the web container is listening on IP port 8080. Port 8080 is the default listener port for both GlassFish (domain1) and Tomcat. If you have changed the port, you must update the port number in the following files before building and running the examples:

  • wsit-enabled-fromjava/etc/wsit-fromjava.server.AddNumbersImpl.xml

  • wsit-enabled-fromjava/etc/custom-schema.xml

  • wsit-enabled-fromjava/etc/custom-client.xml

  • wsit-enabled-fromjava/etc/build.properties

  • wsit-enabled-fromwsdl/etc/custom-client.xml

  • wsit-enabled-fromwsdl/etc/build.properties

14.1.2. Setting the Web Container Home Directory

Before you build and deploy the web service and its client, set one of the following environment variables:

  • If you are using GlassFish, set the AS_HOME environment variable to the top-level directory of GlassFish.

  • If you are using Tomcat, set the CATALINA_HOME environment variable to the top-level directory of Tomcat.

14.2. WSIT Configuration and WS-Policy Assertions

WSIT features are enabled and configured using a mechanism defined by the Web Services Policy Framework (WS-Policy) specification. A web service expresses its requirements and capabilities through policies embedded in the service's WSDL description. A web service consumer, or client, verifies that it can handle the expressed requirements and, optionally, uses server capabilities advertised in policies.

Each individual WSIT technology, such as Reliable Messaging, Addressing, or Secure Conversation, provides a set of policy assertions it can process. Those assertions provide the necessary configuration details to the WSIT runtime to enable proper operation of the WSIT features used by a given web service. The assertions may specify particular configuration settings or rely on default settings that are predetermined by the specific technology. For instance, in the snippet shown below, the wsrm:InactivityTimeout setting is optional and could be omitted. The following snippet shows WS-Policy assertions for WS-Addressing and WS-Reliable Messaging:

Example 14.1. Sample WS-Policy expression

<wsp:Policy wsu:Id="AddNumbers_policy">
    <wsp:ExactlyOne>
        <wsp:All>
            <wsaw:UsingAddressing/>
            <wsrm:RMAssertion>
                <wsrm:InactivityTimeout Milliseconds="600000"/>
            </wsrm:RMAssertion>
        </wsp:All>
    </wsp:ExactlyOne>
</wsp:Policy>

This snippet is valid in either a WSIT configuration file (wsit-package.service.xml) or in a Web Services Description Language (WSDL) file. Java-first web services use the WSIT configuration file, while WSDL-first web services rely exclusively on the policy elements in the WSDL file. This particular snippet is from the WSIT configuration file in the example, wsit-enabled-fromjava/etc/wsit-fromjava.server.AddNumbersImpl.xml.

14.3. Creating a Web Service without NetBeans

You can create a web service starting from Java code or starting from a WSDL file. The following sections describe each approach:

14.3.1. Creating a Web Service From Java

One way to create a web service application is to start by coding the endpoint in Java. If you are developing your Java web service from scratch or have an existing Java class you wish to expose as a web service, this is the most direct approach.

The Java API for XML Web Services (JAX-WS) 2.0 Specification, JSR-224, relies heavily on the use of annotations as specified in A Metadata Facility for the Java Programming Language (JSR-175) and Web Services Metadata for the Java Platform (JSR-181), as well as additional annotations defined by the JAX-WS 2.0 specification.

The web service is written as a normal Java class. Then the class and its exposed methods are annotated with the web service annotations @WebService and @WebMethod. The following code snippet shows an example:

Example 14.2. 

@WebService
public class AddNumbersImpl {
    @WebMethod(action="addNumbers")
    public int addNumbers(int number1, int number2)
            throws AddNumbersException {
        if (number1 < 0 || number2 < 0) {
            throw new AddNumbersException(
                    "Negative number can't be added!",
                    "Numbers: " + number1 + ", " + number2);
        }
        return number1 + number2;
    }
}

When developing a web service from scratch or based on an existing Java class, WSIT features are enabled using a configuration file. That file, wsit-package.service.xml, is written in WSDL format. An example configuration file can be found in the accompanying samples:

Example 14.3. 

wsit-enabled-fromjava/etc/wsit-fromjava.server.AddNumbersImpl.xml

The settings in the wsit-package.service.xml file are incorporated dynamically by the WSIT runtime into the WSDL it generates for the web service. So when a client requests the web service’s WSDL, the runtime embeds any publicly visible policy assertions contained in the wsit-package.service.xml file into the WSDL. For the example wsit-fromjava.server.AddNumbersImpl.xml in the sample discussed in this tutorial, the Addressing and Reliable Messaging assertions are part of the WSDL as seen by the client.

Note

The wsit-package.service.xml file must be in the WEB-INF sub-directory of the application’s WAR file when it is deployed to the web container. Otherwise, the WSIT run-time environment will not find it.

To create a web service from Java, create the following files:

  • These files define the web service and the WSIT configuration for the service, which are discussed in the sections below.

    • AddNumbersException.java

    • custom-schema.xml

    • sun-jaxws.xml

    • web.xml

  • These files are standard files required for JAX-WS. Examples of these files are provided in the wsit-enabled-fromjava sample directory.

    • AddNumbersException.java

    • custom-schema.xml

    • sun-jaxws.xml

    • web.xml

  • These files are standard in any Ant build environment. Examples of these files are provided in the wsit-enabled-fromjava sample directory.

    • build.xml

    • build.properties

14.3.1.1. Web Service Implementation Java File

The sample files define a web service that takes two integers, adds them, and returns the result. If one of the integers is negative, an exception is thrown.

The starting point for developing a web service that uses the WSIT technologies is a Java class file annotated with the javax.jws.WebService annotation. The @WebService annotation defines the class as a web service endpoint.

The following file (wsit-enabled-fromjava/src/fromjava/serverAddNumbersImpl.java) implements the web service interface.package fromjava.server;

Example 14.4. 

import javax.jws.WebService;
import javax.jws.WebMethod;

@WebService
public class AddNumbersImpl {
    @WebMethod(action="addNumbers")
    public int addNumbers(int number1, int number2)
            throws AddNumbersException {
        if (number1 < 0 || number2 < 0) {
            throw new AddNumbersException(
                    "Negative number cannot be added!",
                    "Numbers: " + number1 + ", " + number2);
        }
        return number1 + number2;
    }
}

Note

To ensure interoperability with Windows Communication Foundation (WCF) clients, you must specify the action element of @WebMethod in your endpoint implementation classes. WCF clients will incorrectly generate an empty string for the Action header if you do not specify the action element.

14.3.1.2. wsit-package.service.xml File

This file is the WSIT configuration file. It defines which WSIT technologies are enabled in the web service. The snippet shown below illustrates how to enable the WSIT reliable messaging technology in a wsit-package.service.xml file.

Example 14.5. 

<wsp:Policy wsu:Id="AddNumbers_policy">
    <wsp:ExactlyOne>
        <wsp:All>
            <wsaw:UsingAddressing/>
            <wsrm:RMAssertion>
                <wsrm:InactivityTimeout Milliseconds="600000"/>
                <wsrm:AcknowledgementInterval Milliseconds="200"/>
            </wsrm:RMAssertion>
        </wsp:All>
    </wsp:ExactlyOne>
</wsp:Policy>

For a complete example of a wsit-package.service.xml file, see the wsit-enabled-fromjava example. You can use the wsit-package.service.xml file provided in the example as a reference for creating your own wsit-package.service.xml file.

14.3.2. Creating a Web Service From WSDL

Typically, you start from WSDL to build your web service if you want to implement a web service that is already defined either by a standard or an existing instance of the service. In either case, the WSDL already exists. The JAX-WS wsimport tool processes the existing WSDL document, either from a local copy on disk or by retrieving it from a network address or URL. For an example of using a web browser to access a service’s WSDL, see Verifying Deployment.

When developing a web service starting from an existing WSDL, the process is actually simpler than starting from Java. This is because the policy assertions needed to enable various WSIT technologies are already embedded in the WSDL file. An example WSDL file is included in the fromwsdl sample provided with this tutorial at:

Example 14.6. 

tut-install/wsit-enabled-fromwsdl/etc/AddNumbers.wsdl

To create a web service from WSDL, create the following source files:

The following files are standard files required for JAX-WS. Examples of these files are provided in the fromwsdl sample directory.

  • custom-server.xml

  • sun-jaxws.xml

  • web.xml

The build.xml and build.properties files are standard in any Ant build environment. Examples of these files are provided in the respective samples directories.

The sample files provided in this tutorial define a web service that takes two integers, adds them, and returns the result. If one of the integers is negative, an exception is returned.

14.3.2.1. WSDL File

You can create a WSDL file by hand or retrieve it from an existing web service by simply pointing a web browser at the web service’s URL. The snippet shown below illustrates how to enable the WSIT Reliable Messaging technology in a WSDL file.

Example 14.7. 

<wsp:Policy wsu:Id="AddNumbers_policy">
    <wsp:ExactlyOne>
        <wsp:All>
            <wsrm:RMAssertion>
                <wsrm:InactivityTimeout Milliseconds="600000"/>
                <wsrm:AcknowledgementInterval Milliseconds="200"/>
            </wsrm:RMAssertion>
        </wsp:All>
    </wsp:ExactlyOne>
</wsp:Policy>

For a complete example of a WSDL file, see the AddNumbers.wsdl file in the fromwsdl example. Another benefit of the AddNumbers.wsdl file is that it shows how a WSIT-enabled WSDL is constructed. Therefore, you can use it as a reference when you create a WSDL file or modify an existing one.

14.3.2.2. Web Service Implementation File

The following file (AddNumbersImpl.java) shows how to implement a web service interface.package fromwsdl.server;

Example 14.8. 

import javax.jws.WebService;
import javax.jws.WebMethod;

@WebService (endpointInterface=
        "fromwsdl.server.AddNumbersPortType")
public class AddNumbersImpl{
    @WebMethod(action="addNumbers")
    public int addNumbers (int number1, int number2)
            throws AddNumbersFault_Exception {
        if (number1 < 0 || number2 < 0) {
            String message = "Negative number cannot be added!";
            String detail = "Numbers: " + number1 + ", " + number2;
            AddNumbersFault fault = new AddNumbersFault ();
            fault.setMessage (message);
            fault.setFaultInfo (detail);
            throw new AddNumbersFault_Exception(message, fault);
        }
        return number1 + number2;
    }

    public void oneWayInt(int number) {
        System.out.println("Service received: " + number);
    }
}

14.4. Building and Deploying the Web Service

Once configured, you can build and deploy a WSIT-enabled web service in the same manner as you would build and deploy a standard JAX-WS web service.

The following topics describe how to perform this task:

14.4.1. Building and Deploying a Web Service Created From Java

To build and deploy the web service, open a terminal window, go to the tut-install/wsit-enabled-fromjava/ directory and type the following:

This command calls the server target in build.xml, which builds and packages the application into a WAR file, wsit-enabled-fromjava.war, and places it in the wsit-enabled-fromjava/build/war directory. The ant server command also deploys the WAR file to the web container.

The ant command calls multiple tools to build and deploy the web service. The JAX-WS annotation processing tool (apt) processes the annotated source code and invokes the compiler itself, resulting in the class files for each of the Java source files. In the wsit-enabled-fromjava example, the Ant target build-server-java in build.xml handles this portion of the process. Next, the individual class files are bundled together along with the web service’s supporting configuration files into the application’s WAR file. It is this file that is deployed to the web container by the deploy target.

During execution of the server target, you will see a warning message. The message refers to “Annotation types without processors”. The warning is expected and does not indicate an abnormal situation. The text is included here for reference:

Example 14.9. 

build-server-java:
   [apt] warning: Annotation types without processors:
        [javax.xml.bind.annotation.XmlRootElement,
        javax.xml.bind.annotation.XmlAccessorType,
        javax.xml.bind.annotation.XmlType,
         javax.xml.bind.annotation.XmlElement]
   [apt] 1 warning

14.4.2. Building and Deploying a Web Service Created From WSDL

To build and deploy the web service, open a terminal window, go to the tut-install/wsit-enabled-fromwsdl/ directory, and type the following:

ant server

This command calls wsimport, which takes the WSDL description and generates a corresponding Java interface and other supporting classes. Then the Java compiler is called to compile both the user’s code and the generated code. Finally, the class files are bundled together into the WAR file. To see the details of how this is done, see the build-server-wsdl and create-war targets in the wsit-enabled-fromwsdl/build.xml file.

14.4.3. Deploying the Web Service to a Web Container

As a convenience, invoking the ant server command builds the web service’s WAR file and immediately deploys it to the web container. However, in some situations, such as after undeploying a web service, it may be useful to deploy the web service without rebuilding it.

For both scenarios, wsit-enabled-fromjava and fromwsdl, the resulting application is deployed in the same manner.

The following sections describe how to deploy on the different web containers:

14.4.3.1. Deploying to GlassFish

For development purposes, the easiest way to deploy is to use the autodeploy facility of the GlassFish application server. To do so, you simply copy your application’s WAR file to the /autodeploy directory for the domain to which you want to deploy. If you are using the default domain, domain1, which is set up by the GlassFish installation process, the appropriate directory path would be as-install/domains/domain1/autodeploy.

The build.xml file which accompanies this example has a deploy target for GlassFish. To invoke that target, run the following command in the top-level directory of the respective examples, either wsit-enabled-fromjava or wsit-enabled-fromwsdl, as follows.

ant deploy

14.4.3.2. Deploying to Apache Tomcat

Apache Tomcat also has an autoDeploy feature that is enabled by Tomcat’s out-of-the-box configuration settings. If you are not sure whether the autoDeploy is enabled, check tomcat-home/conf/server.xml for the value of autoDeploy, where tomcat-home is the directory where Tomcat is installed. Assuming autoDeploy is enabled, you simply copy your application’s WAR file to the tomcat-home/webapps directory.

The build.xml file which accompanies this example has a deploy target for Tomcat. To invoke that target, run the following command in the top-level directory of the respective examples, either wsit-enabled-fromjava or wsit-enabled-fromwsdl, as follows. You need to use the -Duse.tomcat=true switch to make sure that the application is deployed to Tomcat, and not to the default server, which is GlassFish.

ant -Duse.tomcat=true deploy

14.4.4. Verifying Deployment

A basic test to verify that the application has deployed properly is to use a web browser to retrieve the application’s WSDL from its hosting web container. The following URLs retrieve the WSDL from each of the two example services. If you are running your web browser and web container on different machines, you need to replace localhost with the name of the machine hosting your web service.

Note

Before testing, make sure your web container is running.

  • http://localhost:8080/wsit-enabled-fromjava/addnumbers?wsdl

  • http://localhost:8080/wsit-enabled-fromwsdl/addnumbers?wsdl

If the browser displays a page of XML tags, the web service has been deployed and is working. If not, check the web container log for any error messages related to the sample WAR you have just deployed. For GlassFish, the log can be found at as-install/domains/domain1/logs/server.log. For Apache Tomcat, the appropriate log file can be found at tomcat-home/logs/catalina.out.

14.5. Creating a Web Service Client

Unlike developing a web service provider, creating a web service client application always starts with an existing WSDL file. This process is similar to the process you use to build a service from an existing WSDL file. The WSDL file that the client consumes already contains the WS–* policy assertions (and, in some cases, any value-added WSIT policy assertions that augment Sun’s implementation, but can safely be ignored by other implementations). Most of the policy assertions are defined in the WS-* specifications. Sun’s implementation processes these standard policy assertions.

The policy assertions describe any requirements from the server as well as any optional features the client may use. The WSIT build tools and run-time environment detect the WSDL’s policy assertions and configure themselves appropriately, if possible. If an unsupported assertion is found, an error message describing the problem will be displayed.

Typically, you retrieve the WSDL directly from a web service provider using the wsimport tool. The wsimport tool then generates the corresponding Java source code for the interface described by the WSDL. The Java compiler, javac, is then called to compile the source into class files. The programming code uses the generated classes to access the web service.

The following sections describe how to create a web service client:

14.5.1. Creating a Client from Java

To create a client from Java, you must create the following files:

The build.xml and build.properties files are standard in any Ant build environment. Examples of these files are provided in the wsit-enabled-fromjava sample directory.

14.5.1.1. Client Java File (fromjava)

The client Java file defines the functionality of the web service client. The following code shows the AddNumbersClient.java file that is provided in the sample.

Example 14.10. 

package fromjava.client;

import com.sun.xml.ws.Closeable;
import java.rmi.RemoteException;

public class AddNumbersClient {
    public static void main (String[] args) {
        AddNumbersImpl port = null;
        try {
            port = new AddNumbersImplService().getAddNumbersImplPort();
            int number1 = 10;
            int number2 = 20;
            System.out.printf ("Invoking addNumbers(%d, %d)\n",
                    number1, number2);
            int result = port.addNumbers (number1, number2);
            System.out.printf (
                    "The result of adding %d and %d is %d.\n\n",
                     number1, number2, result);

            number1 = -10;
            System.out.printf ("Invoking addNumbers(%d, %d)\n",
                    number1, number2);
            result = port.addNumbers (number1, number2);
            System.out.printf (
                    "The result of adding %d and %d is %d.\n",
                     number1, number2, result);
        } catch (AddNumbersException_Exception ex) {
            System.out.printf (
                    "Caught AddNumbersException_Exception: %s\n",
                     ex.getFaultInfo ().getDetail ());
        } finally {
            ((Closeable)port).close();
        }
    }
}

This file specifies two positive integers that are to be added by the web service, passes the integers to the web service and gets the results from the web service by using the port.addNumbers method, and prints the results to the screen. It then specifies a negative number to be added, gets the results (which should be an exception), and prints the results (the exception) to the screen.

14.5.1.2. Client Configuration File (fromjava)

The client configuration file defines the URL of the web service WSDL file. It is used by the web container wsimport tool to access and consume the WSDL and to build the stubs that are used to communicate with the web service.

The custom-client.xml file provided in the wsit-enabled-fromjava sample is shown below. The wsdlLocation and the package name xml tags are unique to each client and are highlighted in bold text

Example 14.11. 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bindings
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    wsdlLocation="http://localhost:8080/wsit-enabled-fromjava/ 
        addnumbers?wsdl"
    xmlns="http://java.sun.com/xml/ns/jaxws">
    <bindings node="wsdl:definitions">
        <package name="fromjava.client"/>
    </bindings>
</bindings>

14.5.2. Creating a Client from WSDL

To create a client from WSDL, you must create the following files:

The build.xml and build.properties files are standard in any Ant build environment. Examples of these files are provided in the fromwsdl sample directory.

14.5.2.1. Client Java File (fromwsdl)

The client Java file defines the functionality of the web service client. The same client Java file is used with both samples, wsit-enabled-fromjava and wsit-enabled-fromwsdl. For more information on this file, see Client Java File (fromjava).

14.5.2.2. Client Configuration File (fromwsdl)

This is a sample custom-client.xml file. The wsdlLocation, package name, and jaxb:package name XML tags are unique to each client and are highlighted in bold text

Example 14.12. 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bindings
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    wsdlLocation="http://localhost:8080/wsit-enabled-fromwsdl/
            addnumbers?wsdl"
    xmlns="http://java.sun.com/xml/ns/jaxws">
    <bindings node="ns1:definitions"
            xmlns:ns1="http://schemas.xmlsoap.org/wsdl/">
            <package name="fromwsdl.client"/>
    </bindings>
    <bindings node="ns1:definitions/ns1:types/xsd:schema
            [@targetNamespace=’http://duke.org’]"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:ns1="http://schemas.xmlsoap.org/wsdl/">
        <jaxb:schemaBindings>
            <jaxb:package name="fromwsdl.client"/>
        </jaxb:schemaBindings>
    </bindings>
</bindings>

14.6. Building and Deploying a Client

To build and deploy a client for either of the examples provided in this tutorial, type one of the following Ant commands in the top-level directory of the respective example, (either wsit-enabled-fromjava or wsit-enabled-fromwsdl) depending on which web container you are using:

For GlassFish:

ant client

For Apache Tomcat:

ant -Duse.tomcat=true client

This command runs wsimport, which retrieves the web service’s WSDL, and then it runs javac to compile the source.

14.7. Running a Web Service Client

To run a client for either of the examples provided in this tutorial, type one of the following Ant commands in the top-level directory of the respective example, (either wsit-enabled-fromjava or wsit-enabled-fromwsdl) depending on which web container you are using:

For GlassFish:

ant run

For the Apache Tomcat:

ant -Duse.tomcat=true run

This command executes the run target, which simply runs Java with the name of the client’s class, for example, fromwsdl.client.AddNumbersClient.

14.8. Undeploying a Web Service

During the development process, it is often useful to undeploy a web service. Undeploying a web service means to disable and remove it from the web container. Once the web service is removed, clients are no longer able to use the web service. Further, the web service will not restart without explicit redeployment by the user.

To undeploy from GlassFish, type the following commands:

asadmin undeploy --user admin wsit-enabled-fromjava
asadmin undeploy --user admin wsit-enabled-fromwsdl

To undeploy from Apache Tomcat, type the following commands:

rm $CATALINA_HOME/webapps/wsit-enabled-fromjava.war
rm $CATALINA_HOME/webapps/wsit-enabled-fromwsdl.war