You are on page 1of 9

Faults and exceptions in JAX-WS

Skill Level: Intermediate

Russell Butek (butek@us.ibm.com)


Certified IT Specialist
IBM

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/"

Faults and exceptions in JAX-WS


© Copyright IBM Corporation 1994, 2007. All rights reserved. Page 1 of 9
developerWorks® ibm.com/developerWorks

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.

Faults and exceptions in JAX-WS


Page 2 of 9 © Copyright IBM Corporation 1994, 2007. All rights reserved.
ibm.com/developerWorks developerWorks®

• 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.

Listing 2. Generated Java interface: PT.java

package sample.fault;
public interface PT {
public String op(String in) throws FaultMsg;
}

Listing 3. Generated Java exception: FautMsg.java

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() {...}
}

Listing 4. Generated Java fault info class: Fault.java

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

Faults and exceptions in JAX-WS


© Copyright IBM Corporation 1994, 2007. All rights reserved. Page 3 of 9
developerWorks® ibm.com/developerWorks

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.

Listing 5. Natural PT.java

package sample2.fault;
public interface PT {
public String op(String in) throws Fault;
}

Listing 6. Natural Fault.java

package sample2.fault;
public class Fault extends Exception {
public Fault(String code) {...}
public String getCode() {...}
public void setCode(String value) {...}
}

The JAX-WS mapping of exceptions to faults is essentially identical to the JAX-RPC


mapping.

Listing 7. WSDL generated from above Java: PTImplService.wsdl

<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">

Faults and exceptions in JAX-WS


Page 4 of 9 © Copyright IBM Corporation 1994, 2007. All rights reserved.
ibm.com/developerWorks developerWorks®

<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>

Listing 8. Schema generated from above Java: PTImplService_schema1.xsd

<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>

What about unmodeled faults?


What happens when an unmodeled fault occurs? For example, what happens when
the service above throws an exception other than sample2.fault.Fault (for
instance, NullPointerException)? What happens on the client? The answer to
that depends on the messaging protocol. For instance, when communicating via

Faults and exceptions in JAX-WS


© Copyright IBM Corporation 1994, 2007. All rights reserved. Page 5 of 9
developerWorks® ibm.com/developerWorks

SOAP/HTTP, the server-side SOAP engine creates a SOAP message containing a


SOAP fault (see Listing 9) with information relevant to the problem in the
faultcode and faultstring fields. Because a SOAP fault is returned to the
client, JAX-WS has defined an exception named SOAPFaultException. When the
service throws an unmodeled fault, the client receives a SOAPFaultException.

javax.xml.ws.soap.SOAPFaultException is a protocol-specific exception. It


extends javax.xml.ws.ProtocolException. JAX-WS defines another
extension of ProtocolException: javax.xml.ws.http.HTTPException for
the XML/HTTP communication channel. Those are the only standardized bindings
defined for WSDL. For other bindings, assume the binding provider defines other
extensions of ProtocolException, one for each new binding.

Listing 9. SOAP fault response message

<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

javax.xml.ws.WebServiceException is not particularly interesting. JAX-WS


defines a number of Java classes, such as Service, BindingProvider, and
Dispatch. If calls to those classes fail, they throw WebServiceException, the
general-purpose exception for the JAX-WS APIs.

ExecutionException

java.util.concurrent.ExecutionException is not a JAX-WS exception (as


you can tell from the package name); it's part of the Java Futures model. Because
JAX-WS's asynchronous client programming models rely on the Java Future's
model, it makes use of this exception. In the Futures model, exceptions thrown by
asynchronous calls aren't thrown directly. They are wrapped by an
ExecutionException. This exception is thrown when the client tries to get the
response from an asynchronous call. Listing 10 shows a code snippet that makes an
asynchronous call to the Web service defined in Listing 1. It makes the call (to

Faults and exceptions in JAX-WS


Page 6 of 9 © Copyright IBM Corporation 1994, 2007. All rights reserved.
ibm.com/developerWorks developerWorks®

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.)

Listing 10. Asynchronous exception snippet

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:

• SOAPFaultException and its relatives, used when the client receives


an unmodeled fault
• WebServiceException, used in the JAX-WS APIs
• ExecutionException, used in asynchronous client programs

Faults and exceptions in JAX-WS


© Copyright IBM Corporation 1994, 2007. All rights reserved. Page 7 of 9
developerWorks® ibm.com/developerWorks

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.

Faults and exceptions in JAX-WS


Page 8 of 9 © Copyright IBM Corporation 1994, 2007. All rights reserved.
ibm.com/developerWorks developerWorks®

• Get involved in the developerWorks community by participating in


developerWorks blogs.

About the author


Russell Butek
Russell Butek is an IBM SOA and Web services consultant. He has been one of the
developers of the IBM WebSphere Web services engine and a member the JAX-RPC
Java Specification Request (JSR) expert group. He was involved in the
implementation of the Apache Axis SOAP engine, driving Axis 1.0 to comply with
JAX-RPC.

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.

Faults and exceptions in JAX-WS


© Copyright IBM Corporation 1994, 2007. All rights reserved. Page 9 of 9

You might also like