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 <[EMAIL PROTECTED]> 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:[EMAIL PROTECTED] > > Sent: Wednesday, August 27, 2003 9:52 AM > > To: [EMAIL PROTECTED] > > Subject: RE: Soap Fault Explanation > > > > > > Gary -- what version of Axis are you running? > > > > -----Original Message----- > > From: Gary L Peskin [mailto:[EMAIL PROTECTED] > > Sent: Wednesday, August 27, 2003 11:44 AM > > To: [EMAIL PROTECTED] > > 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:[EMAIL PROTECTED] > > > Sent: Wednesday, August 27, 2003 9:35 AM > > > To: '[EMAIL PROTECTED]' > > > 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:[EMAIL PROTECTED] > > > > Sent: Wednesday, August 27, 2003 11:22 AM > > > > To: [EMAIL PROTECTED] > > > > 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:[EMAIL PROTECTED] > > > > > Sent: Wednesday, August 27, 2003 8:02 AM > > > > > To: [EMAIL PROTECTED] > > > > > 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/
