Simon Nash wrote:
Simon Laws wrote:
On Thu, Sep 9, 2010 at 3:35 PM, Millies, Sebastian
<[email protected]> 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

Reply via email to