Return-Path: Mailing-List: contact axis-user-help@xml.apache.org; run by ezmlm Delivered-To: mailing list axis-user@xml.apache.org Received: (qmail 86891 invoked from network); 13 Jun 2002 15:47:43 -0000 Received: from gate2savvis.synxis.com (64.240.156.130) by daedalus.apache.org with SMTP; 13 Jun 2002 15:47:43 -0000 Received: from stout.synxis.com by gate2savvis.synxis.com via smtpd (for [63.251.56.142]) with SMTP; 13 Jun 2002 15:43:56 UT Received: (from root@localhost) by stout.synxis.com (8.11.6/8.11.6) id g5DFljV03830 for axis-user@xml.apache.org; Thu, 13 Jun 2002 09:47:45 -0600 Received: from water.synxis.com (water.synxis.com [192.168.3.95]) by stout.synxis.com (8.11.6/8.11.0) with ESMTP id g5DFlje03790 for ; Thu, 13 Jun 2002 09:47:45 -0600 Subject: Re: Custom Exceptions From: David Owens To: axis-user@xml.apache.org In-Reply-To: <3D079CDE.3060503@borland.com> References: <3D079CDE.3060503@borland.com> Content-Type: text/plain Content-Transfer-Encoding: 7bit X-Mailer: Ximian Evolution 1.0.6.99 Date: 13 Jun 2002 09:47:45 -0600 Message-Id: <1023983265.25403.56.camel@water> Mime-Version: 1.0 X-scanner: scanned by Inflex 0.1.5c - (http://www.inflex.co.za/) X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N Sam/Sylvain Bob is on vacation, but I worked with him on this stuff, so I thought I'd post it out there for you so you could take a look at it.... We got our custom exception to work. We had to make one hack to the axis code base to make it possible, and did the rest with a handler. We have an exception called SrmsException which extends exception. It has one data variable, and int called "code". This exception is thrown from the server. From that, we code-generate a client version which extends AxisFault, this is what we catch on the client. To get the data (code) into the exception we had to do the following: We hacked org.apache.axis.providers.java.JavaProvider.java to put the data we need into the messageContext. The JavaProvider catches the server exceptions (search for catch block in the file near processMessage()) and then rethrows it. We changed it to catch it, put info in the context, and then throw it. The code looks like this: try { processMessage(msgContext, clsName, allowedMethods, reqEnv, resEnv, jc, obj); } catch (Exception exp) { msgContext.setProperty("ThrownException", exp); throw exp; } finally { That was the only change we had to make to axis. Then we added a custome handler which sits in the chain on the request to the server, in the chain for the response from the server to client. (We did this by creating and adding the client-config.wsdd which introduces our handler in the globalConfiguration portion.) Here is the code for our handler: package com.synxis.srms.webservices.handlers (Sorry about the formatting): import org.apache.axis.AxisFault; import org.apache.axis.Message; import org.apache.axis.MessageContext; import org.apache.axis.Constants; import org.apache.axis.message.SOAPEnvelope; import org.apache.axis.message.SOAPHeaderElement; import com.synxis.srms.webservices.client.exception.SrmsException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class SrmsExceptionDataHandler extends org.apache.axis.handlers.BasicHandler { public void invoke(MessageContext msgContext) throws AxisFault { if (msgContext.isClient()) { if (msgContext.getPastPivot()) { //System.out.println( "INVOKE CALLED" ); // This is a response. Check it for the session header. Message msg = msgContext.getResponseMessage(); if (msg == null) return; SOAPEnvelope env = null; try { env = msg.getSOAPEnvelope(); } catch (Exception e) { System.out.println("Caught from getSOAPEnvelope, trying again"); env = msg.getSOAPEnvelope(); } SOAPHeaderElement header = env.getHeaderByName("http://xml.apache.org/axis/exception", "exceptionCode"); if (header == null) return; env.clearBody(); Integer code = null; // Got one! try { code = (Integer)header. getValueAsType(Constants.XSD_INT); } catch (Exception e) { throw AxisFault.makeFault(e); } if(code != null) { throw new SrmsException(code.intValue()); } } } } public void onFault(MessageContext msgContext) { try { Exception e = (Exception) msgContext.getProperty("ThrownException"); if (e != null && e instanceof java.lang.reflect.InvocationTargetException) { Throwable re = ((java.lang.reflect.InvocationTargetException)e).getTargetException(); if (re instanceof com.synxis.srms.exception.SrmsException) { com.synxis.srms.exception.SrmsException ex = (com.synxis.srms.exception.SrmsException)re; //System.out.println("Encoding exception code in to header " + ex.getCode()); Message msg = msgContext.getRequestMessage(); if (msg == null) return; SOAPEnvelope env = msg.getSOAPEnvelope(); SOAPHeaderElement header = new SOAPHeaderElement("http://xml.apache.org/axis/exception", "exceptionCode", new Integer(ex.getCode())); env.addHeader(header); } } } catch(Exception e) { System.out.println("Got exception in OnFault in Handler"); e.printStackTrace(); } } }; So, on the request, if there is an fault, onFault() is called. If the exception is one of our SrmsExceptions we get the code (ex.getCode()) and stick it in the header (env.addHeader(header)). Then, on the response, to the client, we check for an envelope and a header. If one exists we look for our header element and get the data (code) from it. We then create a new SrmsException with the code as the value and throw that to be caught by the client. The only strange thing we had to do (besides the rest of it. ;]) was to clear the envelope body so that the original fault is not maintained and sent back to the client. I hope this isn't too confusing, and I hope it helps. As you can tell, we haven't cleaned it all up yet, but it works. |)ave dowens@synxis.com On Wed, 2002-06-12 at 13:11, Sam Kapoor wrote: > Hi Sylvain: > > Yes that's what I thought too. If I can throw an AxisFault then I > should be able to throw a descendant. > Well actually the exception class that I have defined on my server side > is a descendant of Exception. > EInvalidCustomer = class(Exception) > > And I am throwing that on my server. > If I catch it on the client it never goes to that catch block. It will > however go to an AxisFault catch block. > I think that custom exception mappings is not yet supported in Axis. > > Any custom Java exception is converted to an AxisFault by the Axis > Engine and on the client you can catch an AxisFault but not an > EInvalidCustomer > > If you get this to work please let me know. > > Thanks: > > -Sam > > St-Germain, Sylvain wrote: > > >I may be misunderstanding your question but since I can throw an AxiFault > >shouldn't I be able to throw a descendent of AxisFault and, assuming it is a > >known type, expect the serialization to occur? > > > >Sylvain. > > > > > >-----Original Message----- > >From: Bob Cotton [mailto:bcotton@synxis.com] > >Sent: Tuesday, June 11, 2002 8:41 PM > >To: axis-user@xml.apache.org > >Subject: Re: Custom Exceptions > > > > > >>>>>>"Sam" == Sam Kapoor writes: > >>>>>> > > > > Sam> Hi: what I want to do is write a custom exception class and > > Sam> propagate it from one of the methods on my Web-Service to the > > Sam> client. So I define a Java exception class: > > > > Sam> public class EInvalidCustomer extends Exception { > > Sam> public EInvalidCustomer(String err){ > > Sam> super(err); > > Sam> } > > > > Sam> The method on my web-service throws this EInvalidCustomer > > Sam> exception. Now I run the WSDL2Java and I get public class > > Sam> EInvalidCustomer extends org.apache.axis.AxisFault > > > > Sam> Also in my WSDL I have a > Sam> message="intf:EInvalidCustomer" name="EInvalidCustomer"/> > > > > Sam> So in my client when I call the method I catch 2 exceptions, > > Sam> 1 is the RemoteException and the other is EInvalidCustomer > > Sam> excpetion. However, the catch is always going to the > > Sam> RemoteException. Now if I replace EInvalidCustomer with > > Sam> AxisFault then the catch will go to the AxisFault. > > > > > > Sam> I cannot find any example on Axis doc's that show how to pass > > Sam> a custom exception class. > > Sam> Do you have any ideas???? > > > >Working through this same issue now. > > > >Axis can describe the Exception in the WSDL (as you've discovered), > >but actually SENDING the data is not implemented. > > > >Until this happens I'm hacking something in using custom Handlers and > >SOAP headers to pass the data in my exception. > > > >Can the development guys shed some light on this? Possibly by beta3? > > > >Thanks > >- Bob > > > -- And in my spare time, I think I'll write some code.