As I'm trying to come up with an approach for using Exceptions and SOAPFaults for our web services here I'm trying to answer a basic question. I eventually will test it out, but someone here may already have the answer and that help expedite some choices..
I understand how declared excpetions on a method are converted to custom SOAP faults using a web services framework such as CXF, etc. The only examples though specify the exceptions as checked exceptions.
I would like to declare specific business exceptions on the methods, but I want them to be RunTimeExceptions so the consumer can decide whether they catch them or not on the consumer side.
So my question is: If you declare a custom exception that extends RunTimeException in the throws clause of a method and you expose that method in a web service, will it marshal into the SOAPFaults defined in a WSDL? And if so, will the consumer that receives the fault consider it a RunTimeException?
I'm working on getting a test to validate this. I just wanted other peoples experience. I wanted to declare business specific exceptions in the methods and have them be faults in the WSDL (because I consider these expected type of exceptions in the contract), but I don't want the contract to require the consumer to catch them like checked exceptions.
For the other generic exceptions unexpected by the code (NullPointerException, communication exceptions, etc) I would just wrap into a generic exception with a stack trace to aid in debugging.
Originally posted by John M Brown: So my question is: If you declare a custom exception that extends RunTimeException in the throws clause of a method and you expose that method in a web service, will it marshal into the SOAPFaults defined in a WSDL? And if so, will the consumer that receives the fault consider it a RunTimeException?
As a service provider you no influence on how those SOAP Faults will be mapped. That is totally up to the client and their SOAP stack. Their hosting environment may not even support exceptions so the faults may be mapped to error codes and some global error recording mechanism. If the client uses Java then their stack may give them the the option to map them to custom exceptions.
Under JAX-RPC communication faults (TCP/IP, HTTP problems) and Standard SOAP faults are mapped to java.rmi.RemoteException. Fault messages defined in the WSDL are mapped to subclasses of java.lang.Exception. The same is true in JAX-WS - however the mapping can be altered with an external binding files (See JSR-224 Spec).
The JAX-WS spec actually forbids the mapping of java.lang.RuntimeException, java.rmi.RemoteException and their subclasses to Faults declared in the WSDL.
John M Brown
posted 12 years ago
This information was very useful although not very promising for my approach.
It sounds like if we want to take advantage of custom business exceptions on most providers and clients, then the standard Jax-WS way of doing things is to use checked exceptions. I still think this makes for tight coupling (as now the consumer's code cannot compile unless it specifically catches these exceptions when using exceptions).
It even looks like Microsofts WCF follows the same pattern.
Some of our existing architecture declares custom RuntimeExceptions which supported Design By Contract, but gave the client code the option of catching the custom exception OR allowing the exception to bubble up without having to specifically declare it in it's own method.
The other option is to customize business exceptions into the message payload without using faults, but that would require everyone (consumers and other SOA components), to understand the custom payload.
Sometimes I feel like I'm on these specs.
Hopefully someone will see the light on this issue and the standards will evolve to include custom RunTimeExceptions for Web Services.
Originally posted by John M Brown: I would like to declare specific business exceptions on the methods, but I want them to be RunTimeExceptions so the consumer can decide whether they catch them or not on the consumer side.
This is completely contrary to Java's exception philosophy. The Java Programming Language, by Gosling, Arnold, and Holmes :
"Unchecked runtime exceptions represent conditions that, generally speaking, reflect errors in your program's logic and cannot be reasonably recovered from at run time."
Originally posted by John M Brown: Hopefully someone will see the light on this issue and the standards will evolve to include custom RunTimeExceptions for Web Services.
Highly unlikely. SOAP faults declared in the WSDL are application faults and according to the Java exception philosophy those must be checked exceptions - they are an integral part of the (possibly rare but) "expected" information exchange. So if a method does not wish to not process certain exchange scenarios (i.e. duck application exceptions) then it has to do so explicitly by declaring that in the throws clause.
General communications errors are also checked exceptions as absence of the remote party is an undesirable yet possible scenario during "normal" operations.
For my next trick, I'll need the help of a tiny ad ...