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?
> >
> > -----Original Message-----
> > From: Gary L Peskin [mailto:garyp@firstech.com]
> > Sent: Wednesday, August 27, 2003 11:44 AM
> > To: axis-user@ws.apache.org
> > Subject: RE: Soap Fault Explanation
> >
> >
> > The client is java. However, my Stub is called from a method
> > that can either call the Stub class or, in certain
> > situations, call the endpoint service class directly, not via
> > Axis. I want my service class to just throw the exception,
> > which the client will see. If the client called the service
> > class directly, it should see the exception via the normal
> > java exception mechanism. Therefor, I'd like the client to
> > always see the same exception and not have to worry if it's
> > wrapped in an AxisFault or not.
> >
> > I'm making good progress in my investigation. Using tcpmon,
> > it looks like the exception is properly thrown and serialized
> > back to the client. At the moment, I'm zeroing in on
> > SOAPFaultBuilder.createFault() which does not seem to be
> > deserializing this properly.
> >
> > Gary
> >
> > > -----Original Message-----
> > > From: Hansen, Richard [mailto:richard.hansen@thomson.com]
> > > Sent: Wednesday, August 27, 2003 9:35 AM
> > > To: 'axis-user@ws.apache.org'
> > > Subject: RE: Soap Fault Explanation
> > >
> > >
> > > I wonder if it depends on the client. Is it java or something else.
> > > If not Java then AxisFault could be useful to get the code and
> > > details the way you want. AxisFault has a
> > > writeDetails() method that serializes your service specific fields.
> > >
> > > > -----Original Message-----
> > > > From: Gary L Peskin [mailto:garyp@firstech.com]
> > > > Sent: Wednesday, August 27, 2003 11:22 AM
> > > > To: axis-user@ws.apache.org
> > > > Subject: RE: Soap Fault Explanation
> > > >
> > > >
> > > > Cory et al --
> > > >
> > > > I'm looking into this code very carefully at the moment.
> > I'm trying
> > > > to generate Service Specific Exceptions but having problems on the
> > > > client side where an AxisFault is thrown rather than my actual
> > > > exception. My Service
> > > > Specific Exceptions extend Exception but not AxisFault.
> > > >
> > > > Do your Service Specific Exceptions contain a no-argument
> > > > constructor? As I read JAX-RPC, this shouldn't be necessary.
> > > >
> > > > I'm currently heavily into investigating this code to see
> > > if there's
> > > > something wrong I'm doing on my end.
> > > >
> > > > Thanks,
> > > > Gary
> > > >
> > > > > -----Original Message-----
> > > > > From: Cory Wilkerson [mailto:cwilkerson@travelnow.com]
> > > > > Sent: Wednesday, August 27, 2003 8:02 AM
> > > > > To: axis-user@ws.apache.org
> > > > > Subject: RE: Soap Fault Explanation
> > > > >
> > > > >
> > > > > "I know that this question has been asked again and again but I
> > > > > can't find the answer." -- Sorry, didn't mean to sound terse or
> > > > > harsh there, just implying that maybe the Axis folk
> > would like to
> > > > > crank out some decent documentation regarding the matter. I've
> > > > > been using Axis for 4 or 5 months and didn't know you could
> > > > > specify all the parameters as you did below -- that's
> > all manner
> > > > > of interesting. Where did you find the documentation
>
=== message truncated ===
=====
Davanum Srinivas - http://webservices.apache.org/~dims/
|