GeeCON Prague 2014*
The moose likes Web Services and the fly likes How to extract the exception that caused a SOAP fault Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Web Services
Bookmark "How to extract the exception that caused a SOAP fault" Watch "How to extract the exception that caused a SOAP fault" New topic
Author

How to extract the exception that caused a SOAP fault

Alec Swan
Ranch Hand

Joined: Feb 03, 2005
Posts: 39

I am implementing a SOAP 1.1 handler which needs to log Runtime exceptions that cause SOAP faults.

I wrote a class which implements SOAPHandler<SOAPMessageContext> and has the following method:


This code does not log the stacktrace that caused the fault. It only logs the line number where I create SOAPFaultException.

How can I log the exception that caused the SOAP fault?
Ivan Krizsan
Ranch Hand

Joined: Oct 04, 2006
Posts: 2198
    
    1
Hi!
As far as I understand, there is nothing that mandates a web service container to include information on exceptions in a SOAP fault.
I know that GlassFish can optionally do that, but haven't seen, or looked for, information on other web service containers.
If you want to catch and log runtime exceptions from the web service, the service interaction layer of the service implementation is the right place to do that, I feel.
Reference: JAX-WS 2.1 Specification section 3.7
Best wishes!
Alec Swan
Ranch Hand

Joined: Feb 03, 2005
Posts: 39

It may sound dumb, but what do you mean by "service interaction layer"?

As a side note it seems like the SOAP client successfully prints out the exception stack trace thrown by the server. I am wondering if I can use some client-side utility classes that convert the fault received from the server into a beautiful Java exception stack trace.

Thank you.

P.S. I am using Metro implementation of the SOAP protocol.
Ivan Krizsan
Ranch Hand

Joined: Oct 04, 2006
Posts: 2198
    
    1
Hi!
No, not dumb at all - ask and you shall learn. :-)
The interaction layer is the layer that takes care of things related to the communication technology, in this case web services, and perform any pre-processing and validation of requests before they are passed on to the business layer. Separation into these two layers is not necessary so you may not have an interaction layer.
Ah, you are using Metro, which is the web service stack used in GlassFish. As I said before, GlassFish (i.e. Metro) can enclose a stack trace with a SOAP fault. This is behaviour specific to Metro, so do not count on other web service stacks having this feature.
The stack trace is enclosed in some part of the SOAP fault, I don't remember exactly which at the moment. Use soapUI or some TCP packet monitor to view the SOAP messages sent by your web service to see what information is contained in the SOAP fault.
Best wishes!
Eben Hewitt
Author
Ranch Hand

Joined: Apr 16, 2004
Posts: 36
I posted an article on using web service operations that throw exceptions and how those get translated into SOAP faults using JAX-WS here:

http://io.typepad.com/eben_hewitt_on_java/2009/07/using-soap-faults-and-exceptions-in-java-jaxws-web-services.html

The code listings in this article were tested on WebLogic 10.3. It shows you how to build fault info beans on the service side and then retrieve the SOAP fault information and fault details in a JUnit test on the client side.

Hopefully this helps!

Eben Hewitt. SCJP, SCWCD, SCJD, SCJWSD for JEE 5, TOGAF 8 Certified Architect, author of Java SOA Cookbook (O'Reilly, 2009) and contributor to 97 Things Every Software Architect Should Know
Alec Swan
Ranch Hand

Joined: Feb 03, 2005
Posts: 39

Ivan and Eben, thank you both for the replies. Please let me describe the problem that I am trying to solve.

We have several web applications running in Tomcat. Each application implements several web services. The problem is that every time a web service throws a runtime exception the exception is logged to catalina.log file instead of the log file specific to the web application hosting this service.

The exception is then sent to the client in a form of a SOAP fault. The client correctly prints the server-side stack trace that caused the fault. However, we do not have access to client machines in production and would like to log the stack trace of the exception that caused the fault on the server.

In order to centralize exception logging on the server I created a new SOAP handler. At this point, my handler can log the content of the fault. I would like to enhance the handler to log the exception trace that caused the fault in a Java-like format.

So, that's the problem in a nutshell.

Let me know if you have more ideas.

Thanks.

Alec
Alec Swan
Ranch Hand

Joined: Feb 03, 2005
Posts: 39

Ivan, Metro sends the exception stack trace in the message details section. However, I don't know which API to use to convert from fault XML to Java stacktrace. I believe there is a way to do this with Metro, because Metro client logs the full server-side stack trace of the exception that caused the fault. Here is a small part of the stack trace showing how the Metro client uses SOAPFaultBuilder to extract server exception stack trace from the fault:


Any ideas how I can extract exception from fault on the server side?

Thanks.
Alec Swan
Ranch Hand

Joined: Feb 03, 2005
Posts: 39

Eben,

If I understood your blog correctly, it deals with the problem of propagating exceptions to the web service client. You are proposing adding a new type of CheckVerifyFault and serializing it over the wire.

The problem that I am trying to solve is exclusively on the server. Is there a way to use any of your blog ideas for the problem I described in my previous message to you and Ivan?

Thanks.

Alec
Ivan Krizsan
Ranch Hand

Joined: Oct 04, 2006
Posts: 2198
    
    1
Oh, I get it - I misunderstood your original question, sorry.

How about this:
Again, in the service interaction layer, catch all exceptions that occur during the invocation of your web service.
If an exception occurs, place the exception object in the MessageContext you can get by using the WebServiceContext.getMessageContext().
In your case, I guess you should let the exception propagate out, in order for the handleFault method in your handler to be invoked.
Now, in your handler, you can get the exception object from the MessageContext.
Best wishes!
Alec Swan
Ranch Hand

Joined: Feb 03, 2005
Posts: 39

We did not implement our own service layer and instead relied on JAX-WS annotations, such as @WebMethod, and Metro.

I would also like to solve my logging problem without having to go back and implement service layers in all applications that have already been deployed.

Do you agree that implementing this solution in a SOAP handler would be ideal or you think this is the wrong place to do this?

Thanks.

Alec
Ivan Krizsan
Ranch Hand

Joined: Oct 04, 2006
Posts: 2198
    
    1
Hi!
OK, well, if you replace "service interaction layer" with "endpoint classes", does it make more sense to you?
I would have considered AOP (Aspect Oriented Programming), considering that you have a number of existing services to which you want to add this functionality to. If you use AOP, it may be possible to avoid using handlers.
Yes, to me using handlers is the first idea that comes to mind. Your problem seems to be a little more complicated than I originally though, though. :-)
If you, in a handler, can get all the information you need, then fine. However, it seems like this is not the case.
Best wishes!
Alec Swan
Ranch Hand

Joined: Feb 03, 2005
Posts: 39

Hi Ivan, I think AOP is a great suggestion. I will have to look into performance overhead of runtime weaving.
 
GeeCON Prague 2014
 
subject: How to extract the exception that caused a SOAP fault