axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Davanum Srinivas <d...@yahoo.com>
Subject RE: Soap Fault Explanation (long)
Date Mon, 08 Sep 2003 08:35:35 GMT
+1 to "have wsdl2java generate exception classes that do not extend AxisFault" - BUT will that
solve ur problem?

-- dims

--- Gary L Peskin <garyp@firstech.com> wrote:
> Hi, Dims --
> 
> I do have time to work up some patches.  However, I'm unclear as to what
> part of wsdl2java you're referring.  Are you referring to the generation of
> the Exception classes or the Stubs?  I already have my exception classes so,
> as I said, I just throw this part of the generated code away.  However, I'm
> happy to tackle the issue and have wsdl2java generate exception classes that
> do not extend AxisFault.
> 
> Is this what you mean?
> 
> Thanks,
> Gary
> 
> > -----Original Message-----
> > From: Davanum Srinivas [mailto:dims@yahoo.com] 
> > Sent: Friday, September 05, 2003 11:15 PM
> > To: axis-user@ws.apache.org
> > Cc: axis-dev@ws.apache.org
> > Subject: RE: Soap Fault Explanation (long)
> > 
> > 
> > Great thread for the axis-dev@ mailing list. Please post this 
> > there. Please note that Axis passes the JAX-RPC TCK, so we 
> > are JAX-RPC compliant.
> > 
> > First step is to revamp wsdl2java to generate code that does 
> > not depend on AxisFault when it finds a wsdl:fault. Do you 
> > have patches that can do this? The catch would be to run "ant 
> > clean all-tests" and make sure that none of the existing test 
> > harness breaks. Do you have a few cycles to do this? Any help 
> > is much appreciated.
> > 
> > Thanks,
> > dims
> > 
> > --- Gary L Peskin <garyp@firstech.com> wrote:
> > > I am developing a product that can run in two modes.  It can run 
> > > on-platform, where classes A and B are on the same 
> > platform, in which 
> > > case Axis is uninvolved.  An object of class A calls an object of 
> > > class B and that's all there is to it.  However, it can also run 
> > > off-platform where class B sits on an Axis server and class 
> > A sits on 
> > > a client.  In this case, class A invokes a method on class 
> > B via Axis 
> > > using an RPC service.
> > > 
> > > Class A uses a small loader that I wrote.  If it is running 
> > > on-platform, it loads the service class directly.  When running off 
> > > platform, it loads the stub generated by wsdl2java.
> > > 
> > > Class B throws a service specific exception (MyException) 
> > that is not 
> > > a RuntimeException and not a RemoteException.  It doesn't extend 
> > > AxisFault since Axis is not present when running 
> > on-platform.  I don't 
> > > want Axis to be required when running on-platform.
> > > 
> > > MyException is pretty much a regular old java exception.  It is 
> > > immutable so all of the parameters needed are contained in the 
> > > constructors for the exception.  As I read JAX-RPC section 4.3.6, 
> > > MyException conforms to the requirements set forth there.
> > > 
> > > The problem is that, when I use wsdl2java, Axis wants to 
> > deserialize 
> > > this exception with a BeanDeserializer and MyException is not an 
> > > Axis-compatible bean.  It doesn't have a no-argument 
> > constructor.  And 
> > > it doesn't have any setXXX methods.  As I said, MyException 
> > is used in 
> > > regular java processing and I want it to look like a regular java 
> > > exception.  So BeanDeserializer won't work for me.
> > > 
> > > Reading the JAX-RPC spec, section 4.3.6, it seems awfully 
> > vague about 
> > > how Service Specific Exceptions are supposed to be constructed.  It 
> > > requires getXXX methods for each field as well as a 
> > constructor that 
> > > contains all of the fields.  However, you can't find out from 
> > > reflection what order the various parameters are supposed 
> > to be fed to 
> > > the constructor.  So, you need some sort of metadata for 
> > this for each 
> > > constructor.  Unfortunately, this is not currently 
> > supported by Axis, 
> > > to my knowledge.  It creates a FieldDesc for each field but doesn't 
> > > have create OperationDescs for the constructors.
> > > 
> > > I have found that, by making certain assumptions and a few 
> > > modifications, I can get Axis to generate MyException just 
> > as I'd like 
> > > it.  It works for me but it is not entirely satisfactory for the 
> > > general case.  I realize that this is boring for most 
> > people who never 
> > > want to throw MyException and are content to subclass AxisFault and 
> > > make their exception classes bean-like. However, if anyone 
> > is really 
> > > interested in bouncing ideas back and forth, I'd be happy 
> > to work up 
> > > the patches to Axis to implement a view of Service Specific 
> > Exceptions 
> > > more in keeping with the JAX-RPC ideas.  What follows is what works 
> > > for me and is a starting point for discussion, if anyone but me is 
> > > interested.
> > > 
> > > To keep my exception classes as vanilla as possible, I used the -H 
> > > option of wsdl2java to generate Helper classes.  This means that 
> > > wsdl2java generates a MyException_Helper class to contain 
> > all of the 
> > > metadata and leaves MyException itself alone.  The metadata is 
> > > important because it controls the order in which the fields will be 
> > > serialized when running in off-platform mode.  wsdl2java also 
> > > generates a new MyException class that extends AxisFault and has a 
> > > no-argument constructor and setXXX methods for each field.  I throw 
> > > that generated class away.  Then, I manually edit the
> > > getDeserializer() method in the _Helper class to return an
> > > ExceptionDeserializer which is a deserializer that I wrote.
> > > ExceptionDeserializer collects the various fields into a 
> > List and then uses
> > > that List to find the appropriate constructor and invoke it in
> > > ExceptionDeserializer.onEndElement(...).
> > > 
> > > This allows me to create MyException provided I follow 
> > certain rules.  
> > > The fields in the exception are serialized on the server 
> > side in the 
> > > order that the FieldDescs appear in the metadata.  So, I need to be 
> > > sure that I have a constructor that takes the fields in the 
> > same order 
> > > as the metadata (ie the same order in which the fields were 
> > > serialized).  JAX-RPC is pretty weak in describing how the JAX-RPC 
> > > implementation is supposed to invoke the constructor.  I suppose I 
> > > could add in OperationDescs for each constructor but that 
> > seemed too 
> > > much like work.  And what if I had two constructors taking the same 
> > > parameters in a different order.  How would I choose which one to 
> > > invoke?  It seems like someone needs to come up with 
> > various use cases 
> > > for throwing Service Specific Exceptions and follow those out when 
> > > revising the JAX-RPC spec.
> > > 
> > > If I want to include the message in my constructor, I have to add a
> > > getMessage() method into my exception class since it is not 
> > picked up 
> > > in the metadata from Throwable.  That is no problem.
> > > 
> > > The next issue comes with actually throwing MyException.  The big 
> > > problem here is that a service may be invoked using the 
> > > Call.invoke(...) methods. JAX-RPC specifies in the Call 
> > interface that 
> > > these methods throw RemoteException.  Therefore, any 
> > exception that I 
> > > throw needs to be wrapped in a RemoteException if I'm using a 
> > > conforming JAX-RPC implementation. Since other classes called from 
> > > invoke() have a signature indicating that they throw an 
> > AxisFault, my 
> > > ExceptionDeserializer creates an AxisFault (which is a 
> > > RemoteException) specifying my actual MyException instance as the 
> > > cause.
> > > 
> > > Since the stub calls Call.invoke(Object[]), it needs to catch the 
> > > AxisFault that gets thrown and determine if this is wrapping a 
> > > RuntimeException or a Service Specific Exception.  If so, it is the 
> > > stub that needs to "unwind" the AxisFault and throw the original 
> > > exception back to the caller of the Stub.  This forces me to add a 
> > > little bit of code into the generated Stub. As it is, the Stub is 
> > > checking for a return value (not a throw) of a 
> > RemoteException which 
> > > is something that I find very curious.
> > > 
> > > At the moment, I'm editing the generated stub by hand but this is a 
> > > pain because I have to re-edit it every time I regenerate 
> > it.  As the 
> > > number of generated stubs increases, this will become increasingly 
> > > annoying so I'm going to have to modify that part of wsdl2java that 
> > > generates the stub.
> > > 
> > > If anyone has thoughts or questions on this, fire away.  At least, 
> > > I've gotten pretty familiar with wsdl:fault handling which 
> > seems to be 
> > > an area of confusion for many.
> > > 
> > > Can any of the developers comment on whether there are 
> > plans to revamp 
> > > the Service Specific Exception handling to make it JAX-RPC 
> > compliant?  
> > > If so, is someone looking for help?
> > > 
> > > Gary
> > > 
> > > 
> > > > -----Original Message-----
> > > > From: Cory Wilkerson [mailto:cwilkerson@travelnow.com]
> > > > Sent: Wednesday, August 27, 2003 9:52 AM
> > > > To: axis-user@ws.apache.org
> > > > Subject: RE: Soap Fault Explanation
> > > > 
> > > > 
> > > > Gary -- what version of Axis are you running?
> > > > 
> 
=== message truncated ===


=====
Davanum Srinivas - http://webservices.apache.org/~dims/

Mime
View raw message