[prev in list] [next in list] [prev in thread] [next in thread] 

List:       tuscany-user
Subject:    Re: Abstract exception classes and web services
From:       Simon Nash <nash () apache ! org>
Date:       2010-11-21 15:07:10
Message-ID: 4CE9359E.5050502 () apache ! org
[Download RAW message or body]

Simon Nash wrote:
> Simon Laws wrote:
> > On Thu, Sep 9, 2010 at 3:35 PM, Millies, Sebastian
> > <Sebastian.Millies@ids-scheer.com> wrote:
> > > thanks for the explanation. However, when I tested this just now, it 
> > > didn't
> > > work. Perhaps I misunderstood, or there's a bug in Tuscany.
> > > 
> > > What I did was annotate the abstract exception class as follows
> > > 
> > > @XmlJavaTypeAdapter(CurrencyConverterExceptionAdapter.class)
> > > public abstract class CurrencyConverterException extends Exception
> > > 
> > > and implement the adapter class in the same server-side package, so 
> > > it can
> > > get imported by the client together with the exception. The adapter 
> > > simply
> > > serializes the exception to and from a string in the format
> > > "concreteClassName#message".
> > > 
> > > On the client side I changed nothing. When I ran this code in Tuscany 
> > > 1.6
> > > (calling the server from a different node to make sure the ws-binding 
> > > is used),
> > > the unmarshal/marshal methods in the adapter do not even get called. 
> > > Is there
> > > anything more I have to do except implement the adapter class? I'm 
> > > sorry if
> > > this is a naive question, but it really sounded so simple in your post.
> > > 
> > > -- Sebastian
> > 
> > Hi Sebastien
> > 
> > Unfortunately I don't think the @XmlJavaTypeAdapter JAXB annotation is
> > supported in the 1.x code base. If was added to the 2.x code base at
> > r743192 if you want to look it up. The interface test was extended
> > here [1]
> > 
> > [1] 
> > http://svn.apache.org/repos/asf/tuscany/sca-java-2.x/trunk/modules/interface-java- \
> > jaxws/src/test/java/org/apache/tuscany/sca/interfacedef/java/jaxws/TestInterface.java \
> >  
> > 
> > Regards
> > 
> > Simon
> > 
> It looks like this code change (but not the test case?) was added to the
> Tuscany 1.x codebase under r744091.  This was marked as a fix for 
> TUSCANY-2840,
> and there were additional commits to 1.x for this JIRA under r745778 and
> r745779.  I'll do some investigation to try to find out why this annotation
> isn't working with 1.x.
> 
> Simon
> 
> 
> 
After spending some time looking at this, I have come to the following
conclusions.

1. There isn't any difference between Tuscany 1.x and 2.x in how they handle
    abstract classes, abstract exceptions and @XmlJavaTypeAdapter.

2. For Tuscany talking to Tuscany, abstract classes can be passed as method
    parameters over Web Services if they are correctly annotated with
    @XmlJavaTypeAdapter.  This includes abstract exception classes passed as
    method parameters.

3. For Tuscany services talking to non-Tuscany web service clients, using
    @XmlJavaTypeAdapter for custom marshalling and unmarshalling of method
    parameters doesn't work because of TUSCANY-3779.  This bug causes Tuscany
    to generate incorrect WSDL that isn't compatible with the data passed on
    the wire.

4. It isn't possible to declare an abstract exception class as a checked
    exception type in a service interface, pass a concrete subclass of the
    declared exception type from a service to a client over a Web Services
    binding, and have the exception unmarshalled by the client as the same
    concrete subclass of the declared exception type.  This is a JAX-WS
    limitation, not a Tuscany limitation.  Because SCA uses JAX-WS for mapping
    from interface.java to WSDL and vice versa, it's also an SCA limitation.

I'm surprised and disappointed by point 4, which deserves a more detailed
explanation.  In JAX-WS, service interface exceptions are converted to fault
beans and these fault beans are mapped to XML using JAXB.  Because JAXB
never sees the original exception object, it isn't possible to use the
@XmlJavaTypeAdapter annotation to customize how this exception object is
mapped to an XML schema type on the wire, or vice versa.

When marshalling a thrown exception object, the mapping from the exception
object to the fault bean is described in section 3.7 of the JAX-WS 2.1 spec.
It's possible to control this mapping either by using the @WebFault/getFaultInfo()
pattern in the declared Java exception class or by defining a getter method
in the declared Java exception class to extract runtime information from the
Java exception object, such as its concrete exception class name.  This means
that we do have some flexibility and options on the marshalling side, though
these require some tweaking of the abstract exception class definition.

Unfortunately the same flexibility isn't available when unmarshalling the
WSDL fault information on the client side to create a Java exception.
The problem is that JAX-WS doesn't provide any way to control the class of
the unmarshalled exception based on information passed in the WSDL fault.
The steps are as follows:
1. JAX-WS uses JAXB to create a fault bean from the XML passed.  The mapping
    from XML to the fault bean could be customized using @XmlJavaTypeAdapter,
    but this isn't particularly useful because of what happens next.
2. JAX-WS converts the fault bean to a Java exception whose class is the
    declared exception type in the service interface, with no opportunity to
    customise the exception class that JAX-WS instantiates.  If the declared
    exception type is abstract, this step fails.  JAXB isn't involved in this
    step, so no JAXB customization of this conversion is possible.

We could define some Tuscany-specific mechanism for adding flexibility to
step 2 above, but this wouldn't be interoperable when using Tuscany to talk
to non-Tuscany web services, which defeats the whole point of using an
interoperable Web Services binding.

Any suggestions for a solution would be most welcome.

   Simon


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic