Professional Documents
Culture Documents
30 Oct 2008
This article details the Java™ API for XML Web Services (JAX-WS) mapping of Web
Services Description Language (WSDL) faults to Java exceptions, Java exceptions to
WSDL faults, and some other exceptions defined by the JAX-WS specification.
Introduction
IBM® developerWorks has published articles about Java API for XML-based RPC
(JAX-RPC) faults and exceptions (see Resources). But now there's a new Web
services Java mapping specification: JAX-WS. JAX-WS mappings are somewhat
different from JAX-RPC mappings. This article describes these new mappings.
(Comparing the JAX-RPC and JAX-WS fault mappings is beyond the scope of this
article. Feel free to do your own comparison by checking out other developerWorks
JAX-RPC articles listed in Resources.)
WSDL-to-Java mapping.
First, let's look at the WSDL-to-Java mapping of faults to exceptions, starting with
the WSDL in Listing 1. Run your favorite JAX-WS WSDL-to-Java code generator on
this WSDL. It gives you the generated interface and fault classes shown in Listings
2, 3, and 4. (It would generate much more, but you're only concerned with
exceptions here.)
Listing 1. Faults.wsdl
<wsdl:definitions targetNamespace="urn:fault.sample"
xmlns:tns="urn:fault.sample"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<wsdl:types>
<xsd:schema targetNamespace="urn:fault.sample"
xmlns:tns="urn:fault.sample"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="op" type="tns:Op"/>
<xsd:complexType name="Op">
<xsd:sequence>
<xsd:element name="in" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="opResponse" type="tns:OpResponse"/>
<xsd:complexType name="OpResponse">
<xsd:sequence>
<xsd:element name="out" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="faultElement" type="tns:Fault"/>
<xsd:complexType name="Fault">
<xsd:sequence>
<xsd:element name="code" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="opRequest">
<wsdl:part name="parameters" element="tns:op"/>
</wsdl:message>
<wsdl:message name="opResponse">
<wsdl:part name="parameters" element="tns:opResponse"/>
</wsdl:message>
<wsdl:message name="faultMsg">
<wsdl:part name="parameters" element="tns:faultElement"/>
</wsdl:message>
<wsdl:portType name="PT">
<wsdl:operation name="op">
<wsdl:input message="tns:opRequest"/>
<wsdl:output message="tns:opResponse"/>
<wsdl:fault name="fault" message="tns:faultMsg"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Binding" type="tns:PT">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="op">
<soap:operation soapAction=""/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="fault">
<soap:fault use="literal" name="fault"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Service">
<wsdl:port name="Port" binding="tns:Binding">
<soap:address location="http://www.example.org/"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Notice in Listing 1 that I intentionally named each fault component differently so that
you can see the source for the names of the Java classes.
• The Java exception name is derived from the WSDL fault message's
name; in this case FaultMsg.
• All mapped JAX-WS exceptions contain a private faultInfo instance
variable. The type of this faultInfo is derived from the schema, which
the fault's wrapper element refers to; in this case it's Fault.
Note: Comments and annotations in the following listings have been removed from
the generated Java code for brevity.
package sample.fault;
public interface PT {
public String op(String in) throws FaultMsg;
}
package sample.fault;
public class FaultMsg extends Exception {
private Fault faultInfo;
public FaultMsg(String message, Fault faultInfo) {...}
public FaultMsg(String message, Fault faultInfo, Throwable
cause) {...}
public Fault getFaultInfo() {...}
}
package sample.fault;
public class Fault {
protected String code;
public String getCode() {...}
public void setCode(String value) {...}
}
Why does a JAX-WS mapping of faults create a fault class and a fault info class?
JAX-RPC didn't do that. The reason is that JAX-WS delegates the generation of
schema mappings to Java Architecture for XML Binding (JAXB). JAX-WS knows
how to do Web services stuff, but it doesn't know how to do schema stuff. JAXB
knows schema. A fault or exception is a Web services artifact. The data in a fault is
a schema artifact. So the JAX-WS generator generates the exception, and the JAXB
generator generates the Java bean containing the exception's data.
Java-to-WSDL mapping
JAX-WS seems to prefer that you build exceptions like the ones it generates, with
the exception itself separate from the Java bean data for the exception. If you follow
this pattern, you get the reverse of the mapping described in the previous section.
But separating the exception data from the exception is not typical of how a Java
programmer writes exceptions. So JAX-WS also provides a mapping for the more
natural exception. A simple example of this natural pattern is shown in Listings 5 and
6. Listing 7 shows the WSDL that a JAX-WS generator can create from it.
package sample2.fault;
public interface PT {
public String op(String in) throws Fault;
}
package sample2.fault;
public class Fault extends Exception {
public Fault(String code) {...}
public String getCode() {...}
public void setCode(String value) {...}
}
<definitions targetNamespace="http://fault.sample2/"
xmlns:tns="http://fault.sample2/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<types>
<xsd:schema>
<xsd:import
namespace="http://fault.sample2/"
schemaLocation="PTImplService_schema1.xsd"/>
</xsd:schema>
</types>
<message name="op">
<part element="tns:op" name="parameters"/>
</message>
<message name="opResponse">
<part element="tns:opResponse" name="parameters"/>
</message>
<message name="Fault">
<part element="tns:Fault" name="fault"/>
</message>
<portType name="PTImpl">
<operation name="op">
<input message="tns:op"/>
<output message="tns:opResponse"/>
<fault message="tns:Fault" name="Fault"/>
</operation>
</portType>
<binding name="PTImplPortBinding" type="tns:PTImpl">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="op">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="Fault">
<soap:fault name="Fault" use="literal"/>
</fault>
</operation>
</binding>
<service name="PTImplService">
<port binding="tns:PTImplPortBinding" name="PTImplPort">
<soap:address
location="https://localhost:9444/SampleFault/PTImplService"/>
</port>
</service>
</definitions>
<xs:schema targetNamespace="http://fault.sample2/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://fault.sample2/">
<xs:element name="Fault" type="tns:Fault"/>
<xs:element name="op" type="tns:op"/>
<xs:element name="opResponse" type="tns:opResponse"/>
<xs:complexType name="op">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="opResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Fault">
<xs:sequence>
<xs:element minOccurs="0" name="code" type="xs:string"/>
<xs:element minOccurs="0" name="message" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>java.lang.NullPointerException</faultstring>
<detail/>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
Other exceptions
There are two other exceptions to note: WebServiceException and
ExecutionException.
WebServiceException
ExecutionException
proxy.opAsync), then does something until the asynchronous call is done. When
it's done it gets the response. If the service throws an exception, then this code falls
into the catch block. The actual exception that the service throws is in the cause field
of the ExecutionException instance. (For more details on the asynchronous
client programming model, see Resources.)
try {
PortProxy proxy = new PortProxy();
Response<OpResponse> response = proxy.opAsync("NPE");
while (!response.isDone()) {
// do something
}
OpResponse opR = response.get(); // This call fails if there is
a fault
System.out.println("response = " + opR.getOut());
} catch (ExecutionException ee) {
ee.printStackTrace();
Throwable t = ee.getCause();
System.out.println("t = " + t.getClass().getName());
}
Summary
This article showed you an example of a JAX-WS mapping of a WSDL fault to a
Java exception. You also saw a mapping from a Java exception to a WSDL fault.
Then you explored other JAX-WS exceptions:
Resources
Learn
• Get the specification, API classes, and Javadocs for JAX-RPC 1.1.
• Get the specification, API classes, and Javadocs for JAX-WS 2.0.
• Get the specification, API classes, and Javadocs for JAXB 2.0.
• Learn about all the features of Java 5.
• Read the WSDL 1.1 specification.
• Evaluate JAX-WS features with the IBM WebSphere Application Server Version
6.1 Feature Pack for Web Services.
• Read "JAX-RPC versus JAX-WS, Part 3, the service endpoint interface"
(developerWorks, Jun 2007) for a high-level comparison of the interface
mappings between the two specifications.
• Check out "Exception handling with JAX-RPC" (developerWorks, Feb 2004),
which is roughly equivalent to this article for JAX-RPC.
• Read "JAX-WS client APIs in the Web Services Feature Pack for WAS V6.1:
Using the JAX-WS asyn programming model" (developerWorks, Apr 2008).
• The SOA and Web services zone on IBM developerWorks hosts hundreds of
informative articles and introductory, intermediate, and advanced tutorials on
how to develop Web services applications.
• Play in the IBM SOA Sandbox! Increase your SOA skills through practical,
hands-on experience with the IBM SOA entry points.
• The IBM SOA Web site offers an overview of SOA and how IBM can help you
get there.
• Stay current with developerWorks technical events and webcasts.
• Browse for books on these and other technical topics at the Safari bookstore.
• Check out a quick Web services on demand demo.
Get products and technologies
• Download IBM product evaluation versions and get your hands on application
development tools and middleware products from DB2®, Lotus®, Rational®,
Tivoli®, and WebSphere®.
Discuss
• Participate in the discussion forum for this content.
Trademarks
IBM, the IBM logo, ibm.com, DB2, developerWorks, Lotus, Rational, Tivoli, and
WebSphere are trademarks or registered trademarks of International Business
Machines Corporation in the United States, other countries, or both. These and other
IBM trademarked terms are marked on their first occurrence in this information with
the appropriate symbol (® or ™), indicating US registered or common law
trademarks owned by IBM at the time this information was published. Such
trademarks may also be registered or common law trademarks in other countries.
See the current list of IBM trademarks.
Adobe, the Adobe logo, PostScript, and the PostScript logo are either registered
trademarks or trademarks of Adobe Systems Incorporated in the United States,
and/or other countries.
Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the
United States, other countries, or both.