You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by st...@apache.org on 2004/02/22 00:14:18 UTC

cvs commit: ws-axis/contrib/axisdocs/src/documentation/content/xdocs/java index.ihtml client-side-axis.ihtml

stevel      2004/02/21 15:14:18

  Modified:    contrib/axisdocs/src/documentation/content/xdocs/java
                        index.ihtml client-side-axis.ihtml
  Log:
  More on client side axis; everything you need to know about TCP and firewalls.
  
  Revision  Changes    Path
  1.3       +2 -0      ws-axis/contrib/axisdocs/src/documentation/content/xdocs/java/index.ihtml
  
  Index: index.ihtml
  ===================================================================
  RCS file: /home/cvs/ws-axis/contrib/axisdocs/src/documentation/content/xdocs/java/index.ihtml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- index.ihtml	16 Oct 2003 21:44:08 -0000	1.2
  +++ index.ihtml	21 Feb 2004 23:14:18 -0000	1.3
  @@ -32,6 +32,8 @@
   
       <LI><A href="user-guide.html">User's Guide</A></LI>
   
  +    <LI><A href="client-side-axis.html">Client-side Axis</A></LI>
  +
       <LI><A href="security.html">Securing an Axis-based Web
       Service</A></LI>
   
  
  
  
  1.2       +525 -46   ws-axis/contrib/axisdocs/src/documentation/content/xdocs/java/client-side-axis.ihtml
  
  Index: client-side-axis.ihtml
  ===================================================================
  RCS file: /home/cvs/ws-axis/contrib/axisdocs/src/documentation/content/xdocs/java/client-side-axis.ihtml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- client-side-axis.ihtml	18 Dec 2003 23:40:33 -0000	1.1
  +++ client-side-axis.ihtml	21 Feb 2004 23:14:18 -0000	1.2
  @@ -6,7 +6,7 @@
   	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.0  (Win32)">
   	<META NAME="CREATED" CONTENT="20031218;22214696">
   	<META NAME="CHANGEDBY" CONTENT="Steve Loughran">
  -	<META NAME="CHANGED" CONTENT="20031218;23391077">
  +	<META NAME="CHANGED" CONTENT="20040221;23120647">
   	<STYLE>
   	<!--
   		TD P { margin-left: 0.42in; color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif }
  @@ -15,6 +15,8 @@
   		H2 { color: #000000; text-decoration: underline }
   		H3 { color: #000000 }
   		BLOCKQUOTE { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif }
  +		H4 { color: #000000 }
  +		TH P { margin-left: 0.42in; color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif }
   	-->
   	</STYLE>
   </HEAD>
  @@ -24,6 +26,94 @@
   <P>This document looks at the issues related to developing the client
   side of a Web Service using Axis. 
   </P>
  +<P>Axis supports SOAP, which is built on top of HTTP, a protocol
  +built on TCP/IP. To understand what is going on, it is important to
  +understand the levels underneath.</P>
  +<H2>Core TCP/IP Concepts</H2>
  +<P>We are not going to explain TCP/IP in any detail, as it is far too
  +complex. Some of the concepts and features of the technology are
  +worth covering.</P>
  +<P>TCP/IP builds a reliable channel between two computers, <I>hosts</I>.
  +Every computer running TCP can receive messages coming in on any
  +<I>port</I><SPAN STYLE="font-style: normal">, from 1-65535. That is,
  +if a program on that machine has created a <I>socket</I> and is
  +listening on that port. If not, you will see the message </SPAN><I>connection
  +refused. </I>
  +</P>
  +<P STYLE="font-style: normal">Before a client connects to a host, it
  +has to find its address. IPv4, the most widely supported version of
  +TCP/IP uses 32 bit addresses, such as 127.0.0.1 (that's a special
  +address, it means the local system). To connect to a host you need
  +either the address, or a name of machine &quot;www.w3.org&quot; that
  +can get mapped to an address. That mapping is provided by DNS, a
  +hierarchical network that is so ubiquitous across the infrastructure
  +that we usually take it for granted. Essentially, DNS servers take a
  +hostname and return an IP address or an error message. How DNS
  +servers work out the address is beyond the scope of this document;
  +just assume that a local DNS server asks other ones if it thinks it
  +needs to. 
  +</P>
  +<P STYLE="font-style: normal">Not all systems have DNS support. A
  +system can be configured to have its own host table; on Unix systems
  +this lives in /etc/hosts, on windows in
  +c:\windows\system32\drivers\etc\hosts. You can edit this file and
  +bypass DNS completely, creating a maintenance nightmare in the
  +process. If your users use static host tables rather than DNS, you
  +can never change the network address of a host without serious grief.
  +</P>
  +<P STYLE="font-style: normal">Machines either have static addresses
  +-the network managers assign them an address and they retain it over
  +time, or dynamic addresses. The latter is common for client systems,
  +especially laptops, desktop PCs and dial-up computers. Broadband
  +computers often have static addresses, though it depends on the ISP.</P>
  +<P STYLE="font-style: normal">After looking up the address, the
  +client program creates a socket and tries to connect to the server.
  +At this point the TCP protocol kicks in, the client initiating a
  +conversation by sending a <I>datagram</I> to the destination. This
  +commences the setup of the link, which takes a few packets (three).
  +Once the connection is up and running, the server will be told of the
  +caller (they can get its IP address), and they have a socket which is
  +bound to the client for the duration of the connection. The client
  +and server can send arbitrary binary data between each other, with
  +the guarantees that (a) if the data arrives, it arrives in the order
  +it was written to the socket, and (b) if it doesn't arrive, you will
  +get an error message. 
  +</P>
  +<P STYLE="font-style: normal">Some special things to know:</P>
  +<OL>
  +	<LI><P STYLE="font-style: normal">TCP does not (by default) send
  +	messages over an open connection to probe for a functioning link.
  +	You can turn this on by asking for <I>keepalive</I> packets on a
  +	connection, but it is wasteful of bandwidth.</P>
  +	<LI><P STYLE="font-style: normal">TCP connections run with Nagle's
  +	algorithm enabled by default. This is a cooperative way of limiting
  +	bandwidth consumption, by having the sender only send at a rate the
  +	recipient can handle. The algorithm adapts, but it does ramp up
  +	slowly. Set TCP_NODELAY on a socket if you do not want it.</P>
  +</OL>
  +<P STYLE="font-style: normal">When communicating over a network,
  +<I>latency </I>and <I>bandwidth</I> are the big constraints. Latency
  +is how long it takes to communicate -all those bits of hardware like
  +routers and firewalls add to latency, as does the network wiring.
  +Bandwidth is the measure of how much stuff you can send per second. A
  +link with low latency (good) may still have low bandwidth (bad),
  +while a high bandwidth connection might have a high latency, as the
  +remote server is distant.</P>
  +<P STYLE="font-style: normal"><SPAN STYLE="font-style: normal">Firewalls
  +are a critical feature of modern networks. A firewall blocks off
  +ports to incoming calls. A </SPAN><I>stateful firewall</I><SPAN STYLE="font-style: normal">
  +examines every packet and only allows packets of the current TCP
  +conversation in, and is even better. Firewalls are essential for
  +security reasons, so that you can expose more services behind a
  +network than to the outside world. As well as restricting incoming
  +calls, they often restrict outbound connections. For example,
  +outbound connections to port 80 (HTTP) may be blocked to encourage
  +use of an HTTP proxy server (see below), outbound connections to port
  +143 (IMAP) blocked to stop people connecting to external mail
  +servers. You need to assume that there will be firewalls in the
  +network, between SOAP client and server, and so callbacks from server
  +to client are not going to be possible. </SPAN>
  +</P>
   <H2>Core HTTP Concepts 
   </H2>
   <P>HTTP is at its heart, a very simple protocol. The client opens a
  @@ -47,15 +137,22 @@
   caching proxy server may cache request/response pairs, so popular
   requests do not consume bandwidth. This is very useful, but only
   works on requests that can be cached -historically only GET requests.
  +<I>Transparent Proxies</I> are a special form of proxy -one that by
  +virtue of the underlying network configuration route HTTP requests
  +(especially those on port 80) through a proxy server -without any
  +application configuration. Usually these are invisible until they go
  +wrong, at which point your favourite web service appears as if is
  +returning HTML destined for humans. This can lead to some interesting
  +support calls. 
   </P>
   <P>SOAP over HTTP works above this underlying protocol. A SOAP
   request is a POST with an XML body; the response is an HTTP status
   code and ideally an XML message. As with normal HTTP, the 200 status
   code means all is well. The error code 500 may mean an internal
   server error, or it can indicate that the SOAP stack and/or service
  -threw a SOAPFault. A SOAPFault is a standardised XML message that
  -contains information the recipients can parse. Although other HTTP
  -response codes may be sent back in some circumstances, the WS-I
  +threw a <I>SOAPFault</I>. A SOAPFault is a standardised XML message
  +that contains information the recipients can parse. Although other
  +HTTP response codes may be sent back in some circumstances, the WS-I
   organisation sets down the rules as to when and how these are
   allowed. 
   </P>
  @@ -64,19 +161,21 @@
   apply. Note that at some point in the future alternate transports may
   become more popular, in which case the HTTP techniques will cease to
   work. This is why so many people are writing SOAP-based replacements,
  -usually built using SOAP headers. 
  -</P>
  +usually built using SOAP headers. Axis has some prototypes of
  +alternate transports in its codebase, though none are (yet)
  +production ready.</P>
   <H2>JAX-RPC</H2>
   <P>The JAX-RPC specification is the base specification that
   client-side Axis is built upon. If you are writing a client, read it.
   </P>
  -<P>There are essentially two ways to use JAX-RPC. First, you can use
  -the javax.xml classes to build a SOAP call by hand, and invoke a
  -remote server. This is ugly but gives you an idea of what is going on
  -behind the scenes: an XML message is being built up that is then sent
  -to the remote server, whose response is parsed and deconstructed.
  -Client code written at this level should run against any JAX-RPC
  -implementation. 
  +<P>There are essentially two ways to use JAX-RPC to invoke a SOAP
  +<I>endpoint </I>-a URL at a server that processes SOAP messages.
  +First, you can use the javax.xml classes to build a SOAP call by
  +hand, and invoke a remote server. This is ugly but gives you an idea
  +of what is going on behind the scenes: an XML message is being built
  +up that is then sent to the remote server, whose response is parsed
  +and deconstructed. Client code written at this level should run
  +against any JAX-RPC implementation. 
   </P>
   <P>The other way is to have Axis hide the details of the call and
   generate a wrapper class for a web service. This is done by taking
  @@ -89,10 +188,10 @@
   talks about -which is often the URL of the (development) server that
   the WSDL was retrieved from. 
   </P>
  -<P>This automatic generation of <I>proxy classes</I><SPAN STYLE="font-style: normal">
  -is convenient, as it makes calling a remote Web Service look almost
  -like calling a local object. However, it has some disadvantages that
  -developers need to be aware of:</SPAN></P>
  +<P>This automatic generation of <I>proxy classes</I> is convenient,
  +as it makes calling a remote Web Service look almost like calling a
  +local object. However, it has some disadvantages that developers need
  +to be aware of:</P>
   <UL>
   	<LI><P STYLE="font-style: normal">These generated classes are only
   	compatible with Axis. This is allowed by the JAX-RPC specification,
  @@ -122,14 +221,19 @@
   	involve deploying the service.</P>
   </UL>
   <P STYLE="font-style: normal">Based on personal experience,
  -dynamically generating stub classes is very useful, as it simplifes
  +dynamically generating stub classes is very useful, as it simplifies
   client side code and helps the client source recognise when a service
   has changed is operations' signatures a way that is incompatible. If
   the parameters of an operation changes, the Java method's parameters
   change, and hence the application no longer builds. 
   </P>
  -<H2><BR><BR>
  -</H2>
  +<P STYLE="font-style: normal">However, it is absolutely critical to
  +always remember: <I>web services are not local objects.</I>&nbsp;The
  +proxy class may appear local, but the server can be a long way away,
  +over a narrow connection.</P>
  +<P><I>Never make a blocking call to a Web Service from the GUI
  +thread. </I>
  +</P>
   <H2>Testing</H2>
   <P>If you want to test an Axis service, Wsdl2Java can be told to
   create a stub JUnit test class, containing a test case for every
  @@ -147,41 +251,420 @@
   host that doesn't exist. Try going through a proxy server. Try using
   a slow connection -the TCP Monitor program can simulate this for you.
   </P>
  +<P>There are also third party applications that help you test Web
  +Services -by providing SOAP monitors and by giving you forms-based
  +construction of SOAP requests. These are convenient to have, though
  +you do have to pay for them.</P>
  +<P><A HREF="http://aft.sourceforge.net/">Anteater</A>, on
  +sourceforge, is an Ant-based way of testing SOAP calls. You provide
  +the payloads and then use xpath paths to verify the results. This may
  +seem somewhat low-level but, it is very powerful. 
  +</P>
   <H2>Configuring Client-side handlers</H2>
   <P><I>TODO</I></P>
  +<P STYLE="font-style: normal">Axis supports both client side JAX-RPC
  +and Axis handlers. These handlers get called before a message is
  +sent, and after it is received, just as for server-side handlers. 
  +</P>
   <H2>Redistribution</H2>
  -<P><I>TODO</I></P>
  -<H2>Implementing Dynamic Binding</H2>
  -<P><I>TODO</I></P>
  -<H2>Proxy Servers and other configuration tricks</H2>
  -<P><I>TODO. Cover IP address caching, timeout config</I></P>
  +<P STYLE="font-style: normal">To redistribute an application running
  +Axis, you need to redistribute</P>
  +<UL>
  +	<LI><P STYLE="font-style: normal">axis.jar</P>
  +	<LI><P STYLE="font-style: normal">commons-logging.jar</P>
  +	<LI><P STYLE="font-style: normal">A logging implementation
  +	compatible with commons-logging. As Java1.4's intrinsic logging
  +	facility is compatible, you do not need to include a logging JAR for
  +	Java1.4. Otherwise the log4j.jar is a good one to use</P>
  +	<LI><P STYLE="font-style: normal">A logging configuration file for
  +	your chosen logger. 
  +	</P>
  +	<LI><P STYLE="font-style: normal">An XML Parser. Java1.4 ships with
  +	crimson, although the axis team strongly recommend xerces over
  +	crimson. 
  +	</P>
  +	<LI><P STYLE="font-style: normal">commons-discovery.jar</P>
  +</UL>
  +<P STYLE="font-style: normal">The Axis JAR is not signed, and so can
  +not be used for auto-download from the Web Start facility in Java. 
  +</P>
  +<P><SPAN STYLE="font-style: normal">You do not currently need to
  +include wsdl4j.jar, as the wsdl is not processed at run time. Note
  +that this may change at some point in the future, as more knowledge
  +about the structure of the SOAP message is needed to support doc/lit
  +messages, which means limited runtime processing of WSDL files, or
  +other metadata generated from the WSDL files during compilation.</SPAN></P>
  +<H2>Dynamically Discovering and Binding to a Web Service</H2>
  +<P>When Axis generates client proxy classes code from WSDL, it binds
  +the code to the endpoint URL specified in the WSDL -this is usually a
  +URL generated from the URL of the inbound request. Using a
  +http://localhost URL to fetch a WSDL page will result in client code
  +also bound to a service served up on the localhost, which is not what
  +you want in a redistributable. Similarly, even if you use the
  +hostname when fetching the WSDL, you need the fully qualified domain
  +name, not any short name -http://s1.example.org/ and not http://s1/
  +-otherwise only callers in your own domain or subnet will be able to
  +find the server. Hand-written WSDL does not exhibit this problem; the
  +endpoint in the WSDL is the one the author typed in.</P>
  +<P>It is almost essential that you provide some way to update the URL
  +on the clients. The simplest is some command line override option, as
  +used in the Axis command line tools. More advanced is a dialog box
  +for entering URLs, and more advanced yet is some automated discovery
  +mechanism.</P>
  +<P>Axis does not provide any discovery mechanism in the JAR. There is
  +a sibling project, <A HREF="http://ws.apache.org/juddi/">jUDDI</A>,
  +that provides access to UDDI registries. There is also a multicast
  +discovery jar that works with Axis in the Axis CVS tree; this is a
  +proof-of-concept mechanism that uses XML messages but is not
  +compatible with any existing standard. It works OK over LAN networks,
  +but is not designed to be used over wider area. 
  +</P>
  +<P><I>TODO: how to set the URL in a service</I></P>
  +<P><BR><BR>
  +</P>
  +<H2>Call configuration</H2>
  +<P>The Call object can be configured before a call can be made. The
  +<TT>org.apache.axis.client.Call</TT> is Axis's implementation of the
  +<TT>javax.xml.rpc.Call</TT> interface. The JAX-RPC standard interface
  +defines a <TT>setProperty()</TT> method that lets the caller set
  +properties; there are both JAX-RPC standard properties and Axis's own
  +properties that you can set. 
  +</P>
  +<P>All properties have a string name, a name defined in a public
  +static final declaration in the class. 
  +</P>
  +<H4>Standard Properties</H4>
  +<TABLE WIDTH=100% BORDER=1 CELLPADDING=4 CELLSPACING=3>
  +	<COL WIDTH=85*>
  +	<COL WIDTH=85*>
  +	<COL WIDTH=85*>
  +	<THEAD>
  +		<TR VALIGN=TOP>
  +			<TH WIDTH=33%>
  +				<P>Property Name</P>
  +			</TH>
  +			<TH WIDTH=33%>
  +				<P>Description</P>
  +			</TH>
  +			<TH WIDTH=33%>
  +				<P>Type</P>
  +			</TH>
  +		</TR>
  +	</THEAD>
  +	<TBODY>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>USERNAME_PROPERTY</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>User name for authentication</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>String</FONT></P>
  +			</TD>
  +		</TR>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>PASSWORD_PROPERTY </FONT>
  +				</P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>Password for authentication</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>String</FONT></P>
  +			</TD>
  +		</TR>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>SESSION_PROPERTY </FONT>
  +				</P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>Participate in a session with the endpoint?</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>Boolean</FONT></P>
  +			</TD>
  +		</TR>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>OPERATION_STYLE_PROPERTY</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>Type of operation</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>String &quot;rpc&quot; or &quot;document&quot;</FONT></P>
  +			</TD>
  +		</TR>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>SOAPACTION_USE_PROPERTY</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>Should SOAPAction be used?</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>Boolean</FONT></P>
  +			</TD>
  +		</TR>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>SOAPACTION_URI_PROPERTY</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>If SOAPAction is used, this is that action</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>String</FONT></P>
  +			</TD>
  +		</TR>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>ENCODING_STYLE_PROPERTY</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>How to encode data; <BR>Default is SOAP 1.1:</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>String.
  +				&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;</FONT></P>
  +			</TD>
  +		</TR>
  +	</TBODY>
  +</TABLE>
  +<P><BR><BR>
  +</P>
  +<H4>Axis Properties</H4>
  +<TABLE WIDTH=100% BORDER=1 CELLPADDING=4 CELLSPACING=3>
  +	<COL WIDTH=99*>
  +	<COL WIDTH=72*>
  +	<COL WIDTH=85*>
  +	<THEAD>
  +		<TR VALIGN=TOP>
  +			<TH WIDTH=39%>
  +				<P>Property Name</P>
  +			</TH>
  +			<TH WIDTH=28%>
  +				<P>Description</P>
  +			</TH>
  +			<TH WIDTH=33%>
  +				<P>Type</P>
  +			</TH>
  +		</TR>
  +	</THEAD>
  +	<TBODY>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=39%>
  +				<P><FONT SIZE=2>SEND_TYPE_ATTR</FONT></P>
  +			</TD>
  +			<TD WIDTH=28%>
  +				<P><FONT SIZE=2>Should we send the XSI type attributes </FONT>
  +				</P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>Boolean</FONT></P>
  +			</TD>
  +		</TR>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=39%>
  +				<P><FONT SIZE=2>CONNECTION_TIMEOUT_PROPERTY</FONT></P>
  +			</TD>
  +			<TD WIDTH=28%>
  +				<P><FONT SIZE=2>Timeout used by transport sender in milliseconds</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>Integer</FONT></P>
  +			</TD>
  +		</TR>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=39%>
  +				<P><FONT SIZE=2>TRANSPORT_NAME</FONT></P>
  +			</TD>
  +			<TD WIDTH=28%>
  +				<P><FONT SIZE=2>Name of transport handler to use</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>String</FONT></P>
  +			</TD>
  +		</TR>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=39%>
  +				<P><FONT SIZE=2>ATTACHMENT_ENCAPSULATION_FORMAT</FONT></P>
  +			</TD>
  +			<TD WIDTH=28%>
  +				<P><FONT SIZE=2>Send attachments as MIME (the default), or DIME.</FONT></P>
  +			</TD>
  +			<TD WIDTH=33%>
  +				<P><FONT SIZE=2>String <BR>&quot;axis.attachment.style.mime&quot;
  +				or<BR>&quot;axis.attachment.style.dime&quot;</FONT></P>
  +			</TD>
  +		</TR>
  +	</TBODY>
  +</TABLE>
   <P><BR><BR>
   </P>
  +<P>You can still set these Axis-specific properties in a portable
  +client -other JAX-RPC implementations will not act on the options, of
  +course.</P>
  +<H2>Network configuration</H2>
  +<P>Axis runs in a JVM, and JVM parameters control the client's
  +behaviour. Here are JVM configuration options that are used.</P>
  +<TABLE WIDTH=100% BORDER=1 CELLPADDING=4 CELLSPACING=3>
  +	<COL WIDTH=97*>
  +	<COL WIDTH=108*>
  +	<COL WIDTH=51*>
  +	<THEAD>
  +		<TR VALIGN=TOP>
  +			<TH WIDTH=38%>
  +				<P>Name</P>
  +			</TH>
  +			<TH WIDTH=42%>
  +				<P>Meaning</P>
  +			</TH>
  +			<TH WIDTH=20%>
  +				<P>Example</P>
  +			</TH>
  +		</TR>
  +	</THEAD>
  +	<TBODY>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=38%>
  +				<P><FONT FACE="Courier, monospace"><FONT SIZE=2>http.proxyHost</FONT></FONT></P>
  +			</TD>
  +			<TD WIDTH=42%>
  +				<P>Hostname of proxy server</P>
  +			</TD>
  +			<TD WIDTH=20%>
  +				<P ALIGN=CENTER>web-proxy</P>
  +			</TD>
  +		</TR>
  +		<TR>
  +			<TD WIDTH=38% VALIGN=TOP>
  +				<P><FONT FACE="Courier, monospace"><FONT SIZE=2>http.proxyPort</FONT></FONT></P>
  +			</TD>
  +			<TD WIDTH=42% VALIGN=TOP>
  +				<P>Port on server of proxy</P>
  +			</TD>
  +			<TD WIDTH=20% VALIGN=BOTTOM SDVAL="8080" SDNUM="2057;">
  +				<P ALIGN=CENTER>8080</P>
  +			</TD>
  +		</TR>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=38%>
  +				<P><FONT FACE="Courier, monospace"><FONT SIZE=2>http.proxyUser</FONT></FONT></P>
  +			</TD>
  +			<TD WIDTH=42%>
  +				<P>Optional username for proxy authentication</P>
  +			</TD>
  +			<TD WIDTH=20%>
  +				<P ALIGN=CENTER>someone</P>
  +			</TD>
  +		</TR>
  +		<TR VALIGN=TOP>
  +			<TD WIDTH=38%>
  +				<P><FONT FACE="Courier, monospace"><FONT SIZE=2>http.proxyPassword</FONT></FONT></P>
  +			</TD>
  +			<TD WIDTH=42%>
  +				<P>Optional proxy server password</P>
  +			</TD>
  +			<TD WIDTH=20%>
  +				<P ALIGN=CENTER>secret</P>
  +			</TD>
  +		</TR>
  +		<TR>
  +			<TD WIDTH=38% VALIGN=TOP>
  +				<P><FONT FACE="Courier, monospace"><FONT SIZE=2>networkaddress.cache.ttl
  +				</FONT></FONT>
  +				</P>
  +			</TD>
  +			<TD WIDTH=42% VALIGN=TOP>
  +				<P>Seconds to cache resolved hostnames;<BR>-1 == forever, 0==no
  +				cache</P>
  +			</TD>
  +			<TD WIDTH=20% VALIGN=BOTTOM SDVAL="120" SDNUM="2057;">
  +				<P ALIGN=CENTER>120</P>
  +			</TD>
  +		</TR>
  +		<TR>
  +			<TD WIDTH=38% VALIGN=TOP>
  +				<P><FONT FACE="Courier, monospace"><FONT SIZE=2>networkaddress.cache.negative.ttl
  +				</FONT></FONT>
  +				</P>
  +			</TD>
  +			<TD WIDTH=42% VALIGN=TOP>
  +				<P>Seconds to cache unresolved hostnames;<BR>-1 == forever, 0==no
  +				cache</P>
  +			</TD>
  +			<TD WIDTH=20% VALIGN=BOTTOM SDVAL="30" SDNUM="2057;">
  +				<P ALIGN=CENTER>30</P>
  +			</TD>
  +		</TR>
  +	</TBODY>
  +</TABLE>
  +<P><BR><BR>
  +</P>
  +<P>Most of these options control proxy server settings; if they are
  +missing and a proxy server is needed for internet access -the client
  +will get connectivity errors of some form or another. If they are
  +present and wrong, the client will also get connectivity errors. Note
  +that even though users can configure the proxy settings for the JVM
  +when hosting Applets, these settings do not propagate to applications
  +-this is one of the many mysteries of Java networking. 
  +</P>
  +<P STYLE="margin-left: 0.79in"><I>Every Web Service client
  +application needs to provide some way to configure the proxy server
  +settings. It is also useful to display these somewhere for support
  +call diagnostics.</I></P>
  +<P>The final two properties are troublesome, all the more so because
  +they are so little known about. To find out about them, look at
  +&quot;Address Caching&quot; under <I>java.net.InetAddress. O</I>r
  +just switch your DNS server off for a few minutes and observe how
  +client applications not only fail to connect when the server is
  +missing -servers stay unreachable when the DNS server is turned back
  +on.</P>
  +<P STYLE="font-style: normal">What is happening is that the runtime
  +caches the IP addresses of hostnames it resolves using a DNS query.
  +By default, these are cached forever, so that a long running Java
  +application will break if the IP address of the remote server ever
  +changed during the life of the client. Similarly, the runtime caches
  +those hostnames that do not resolve to addresses. On Java1.3, these
  +failed lookups are cached indefinitely -if DNS is down or a laptop
  +off the net, the client will never be able to find them again. 
  +</P>
  +<P STYLE="font-style: normal">Clearly it is essential for any
  +non-trivial application to set the cache options to give a sensible
  +lifetime for cached hostnames. These values are (in Java1.4) Java
  +Security Properties; you set them using
  +java.security.Security.setProperty(). In Java1.3 and earlier there
  +was some alternate mechanism that mandated properties that could only
  +be done on the command line. We would tell you what the properties
  +are, except we have forgotten. 
  +</P>
   <H2>Troubleshooting Network Problems</H2>
   <P>The classic definition of a distributed system: 
   </P>
   <P STYLE="margin-left: 0.79in">&ldquo;<I>You know you have one when
   the crash of a computer you&rsquo;ve never heard of stops you from
  -getting any work done.&rdquo;  Leslie Lamport</I></P>
  -<P STYLE="margin-left: 0.79in; margin-bottom: 0in"><BR>
  -</P>
  -<P>This may seem humourous, but it is a depressingly accurate model
  -of the state of distributed systems. Everyone knows that web sites
  -are sometimes off-line, pages sometimes get served up incomplete or
  -with some error trace instead of the results.</P>
  +getting any work done.&rdquo; Leslie Lamport</I></P>
  +<P>This may seem funny, but it is a depressingly accurate model of
  +the state of distributed systems. Everyone knows that web sites are
  +sometimes off-line, pages sometimes get served up incomplete or with
  +some error trace instead of the results.</P>
   <P>Web Services are similar, except instead of a human reading a
   web-browser-displayed error page, the client software receives the
   error and has to handle it or report it.</P>
   <P>When the Axis client code receives an error, it throws an
   exception, specifically a subclass of java.rmi.RemoteException. This
   can be an AxisFault, or it can be something else. Either way, it
  -means trouble.  Usually the fault string of the exception provides
  +means trouble. Usually the fault string of the exception provides
   some error text which is meaningful to the experienced application
   developer -though less meaningful to either the end user or the
   support team.</P>
   <P>Here is a list of network-related error responses that can be
   received by a client application. As Axis' adminclient application is
  -a SOAP client, it can see these responses too. The Sitefinder 
  +a SOAP client, it can see these responses too. The Sitefinder
   comments are specific only if VeriSign SiteFinder or a successor is
   subverting the normal behaviour of DNS for their own goals, an action
   which complicates the normal failure modes of web services. 
  @@ -199,8 +682,9 @@
   		</TD>
   		<TD WIDTH=73%>
   			<P>The host exists, nothing is listening for connections on that
  -			port.<BR><I>Site Finder: the URL is using a port other than 80,
  -			and the .com or .net address is invalid</I></P>
  +			port. Alternatively, a firewall is blocking that port.<BR><I>Site
  +			Finder: the URL is using a port other than 80, and the .com or
  +			.net address is invalid</I></P>
   		</TD>
   	</TR>
   	<TR VALIGN=TOP>
  @@ -320,8 +804,6 @@
   	over the telephone being the ideal.</P>
   	<LI><P>Having support-accessible logging to provide an escalation
   	path should the problem turn out to be server side.</P>
  -	<LI><P>Always setting the content type to text/xml or a MIME type
  -	specific to the XML returned by the service. (xml+svg)</P>
   </UL>
   <P>Another useful technique is for the service to implement the
   &quot;Ping&quot; design pattern. The service needs to support a
  @@ -333,15 +815,12 @@
   detects failure early on, hopefully at a lower cost. 
   </P>
   <H3>What can the developer of a Web Service client application do?</H3>
  -<P>Developers of web service client applications are in the front
  -line here. Even if they use a WSDL-based code generation process that
  -hides underlying URLs, or discover services using UDDI, Rendezvous or
  -some other mechanism, their program will still encounter connectivity
  -problems. Networks are fundamentally unreliable; laptops move around
  -and go offline, services get switched off. 
  +<P>Networks are fundamentally unreliable; laptops move around and go
  +offline, services get switched off. 
   </P>
  -<P>They need to handle the connectivity problems and fail in a way
  -that allows the problem to be diagnosed and corrected.</P>
  +<P>Your application need to handle the connectivity problems and fail
  +in a way that allows the problem to be diagnosed and corrected. Axis
  +does not do this by itself, you need to help it.</P>
   <OL>
   	<LI><P>It is good to translate framework errors/exceptions into
   	error messages that are comprehensible by end users. XML parser