Chapter 14. WSIT Example Using a Web Container Without NetBeans IDE
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 Jakarta XML Web Services
Specification relies heavily on the use of annotations
as specified in A Metadata Facility for the Java Programming
Language (JSR-175) and Jakarta Web Services Metadata,
as well as additional annotations defined by the Jakarta XML
Web Services 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 Jakarta
XML Web Services.
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 jakarta.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 jakarta.jws.WebService;
import jakarta.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 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 Jakarta
XML Web Services.
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.
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 jakarta.jws.WebService;
import jakarta.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
Jakarta XML 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 wsgen
tool
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:
[jakarta.xml.bind.annotation.XmlRootElement,
jakarta.xml.bind.annotation.XmlAccessorType,
jakarta.xml.bind.annotation.XmlType,
jakarta.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.
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