You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tuscany.apache.org by Scott Kurz <sc...@gmail.com> on 2007/09/16 05:33:03 UTC

handling exceptions and faults better with the Tuscany databinding framework

In doing some work trying to leverage the Tuscany databinding framework to
transform business exceptions across a binding, I noticed a couple issues
relating to the need to handle both exception and fault DataType(s) .

Basically, I'd like to discuss:

* getting rid of the exception DataType and replacing it with simply a fault
DataType.
* decoupling the fault databinding from the way that the exception maps to a
fault.

Let me explain:

Today, for Java interfaces, we build exception DataTypes during the
introspection phase and we set a databinding upon it.  This DB identifies an
exceptionHandler which can (via getFaultType())  construct a fault DataType
from the exc DataType.

Different exception patterns result in different mappings between exception
and fault data types.   For example, we have the pattern defined by JAX-WS
Sec 2.5 in which the Java exception class wrappers a "fault bean" returned
by the exception's getFaultInfo().   I'm thinking we also want to support
POJO exceptions as well in certain contexts.

Today we would support the JAX-WS Sec. 2.5 pattern by constructing an
DataType wrappering the exception, introspecting the exception to find the
fault and its databinding.   This databinding's exception handler would, at
transform time, be used to construct a fault DataType representing the fault
bean, distinct from the exception DataType.     This more or less works the
same for JAXB and SDO, except that for SDO we have the Tuscany-ism of
looking at FAULT_ELEMENT instead of @WebFault ( which I mention below I'd
like to change).

For the POJO exception pattern, on the other hand, the fault DataType and
exception DataType collapse into one as we see in the logic of
JavaBeansExceptionHandler.

I don't think we need the complexity of the two DataTypes;  I think all we
really need from the exception DataType is its "physical', i.e. the Java
Class of the exception type.   We use this to match the exception we have
in-hand from the Java runtime with the DataType on the operation.   It is
only the fault that gets transformed by the Tuscany databinding framework.

Perhaps what would be better, instead of an exception DataType and fault
DataType, would be to simply have the fault DataType with an additional
"exceptionPhysical" member.    (We still need ExceptionHandler with
getFaultInfo() and createFaultException() as well).

This would let us get the exception handlers out of the introspection
business.

If we look at DataBindingJavaInterfaceProcessor.processInterface() today,
and see how the various databindings' exception handlers' getFaultType()s
are called in order to find the right databinding to set on the exception
DataType, it does seem messy to have to rely on this same getFaultType()
method to work in a certain way and introspection time and transform
time.

The best reason, I think is elegance:  if it is the actual fault DataType
which is interesting at transform time, and if we have an introspect step,
let's have the introspect step set up this interesting fault DataType.
As an example, in  working on some binding impl code in the past, I found
myself calling this same getFaultType() method to get the fault from the
exc...   making for at least three times this same getFaultType() method was
called (Java introspect, my binding construction, and transform time).

Then there is also performance to consider...

---------

In addition, (and to some degree this is a separate point),  I think we
should recognize certain patterns in which a Java exception relates to both
the Java type of the "fault bean" and to a logical type and decouple these
patterns from association with one of the various databinding impls we
support.

So, as an example, if you take the pattern in JAX-WS Sec. 2.5, you can have
an exception with @WebFault(<fault elem>)  with a getFaultInfo() method
returning a fault bean of any of the simple, SDO, or JAXB databindings.
I don't see the rationale for using FAULT_ELEMENT to denote the logical type
when the fault bean is an SDO vs. using the @WebFault for a JAXB;  I think
this pattern should be decoupled from the choice of databinding, and we
don't want the same  algorithm (looking for @WebFault and using reflection
to find the type returned by getFaultInfo(), etc.) to be re-coded for each
databinding.

(Though I don't think Tuscany has it presently, I coded a Simple DB
ExceptionHandler which is largely just a copy of the SDOExceptionHandler,
wihch illustrates my point.   Someone please correct me if Tuscany can
already handle simple-typed fault beans in the JAX-WS Sec 2.5 pattern).


In addition we'd have other patterns like POJO exception and maybe the Axis2
exception which Simon Nash recently did some work regarding.


At this point I'd like to show some sample code, which is part of some
changes I've run with successfully (some of my own tests in my own sandbox -
not Tuscany tests yet).


    public DataType<?> getFaultFromExceptionDataType(DataType<?>
excDataType) {

        //
        // 1. Find the Java type of the fault bean, construct fault DT and
set exc physical
        //
        Object excPhysical = excDataType.getPhysical();
        if (!(excPhysical instanceof Class)) {
            return null;    // Should we be throwing exc instead?
        }
        Class excClass = (Class)excPhysical;
        Class faultBeanClass = null;
        try {
            Method method = excClass.getMethod("getFaultInfo",
EMPTY_CLASS_ARRAY);
            faultBeanClass = method.getReturnType();
        } catch (NoSuchMethodException e) {
            faultBeanClass = null;
        }
        if (faultBeanClass == null) {
            return null;
        }

        // Only the physical is set here.
        DataType faultDataType = new DataTypeImpl(null, faultBeanClass,
null);
        faultDataType.setExceptionPhysical(excClass);

        //
        // 2. Send through already-existing introspection routine
        //

        // Don't try to propagate annotations yet.  Note the DB on the
faultDataType
        // is set by the databinding according to the implied contract we
have going.
        dataBindingRegistry.introspectType(faultDataType, null);

        //
        // 3) instantiate an exception handler for this fault from the
appropriate DB and
        //    set in the fault DT
        //

        DataBinding faultDataBinding = dataBindingRegistry.getDataBinding(
faultDataType.getDataBinding());
        ExceptionHandler excHandler = faultDataBinding.getExceptionHandler
();
        faultDataType.setExceptionHandler(excHandler);

        //
        // 4) set the logical from the @WebFault (FAULT_ELEMENT for now)
        //
        QName faultElement = null;
        try {
            Field field = excClass.getField("FAULT_ELEMENT");
            faultElement = (QName)field.get(null);
        } catch (NoSuchFieldException e) {
            // Ignore
        } catch (Throwable e) {
            // Ignore
        }
        if (faultElement == null) {
            // Should we be responsible for calculating a default fault_elem
            // or leave this to someone else???
            return null;
        }

        // Having set the physical and DB already, we now set the logical of
the fault
        faultDataType.setLogical(new XMLType(faultElement, null));

        return faultDataType;

    }


The above is code that would be called in some form from
DataBindingJavaInterfaceProcessor.processInterface(), passing in the
exception DataType.

In this code, I'm finding the fault bean class through a databinding-neutral
look at the getFaultInfo() return type.  I'm then setting the DB on this
based on the normal DB.introspect() routine (i.e. the same introspection of
input and output types to find the databinding).
Step 4 is to set the logical, again in a databinding-neutral way.

I also have a step 3 where the ExceptionHandler is now stored in the
DataType.   This is a non-trivial change which could probably
really use some improvement (it brings up build and intra-project dependency
issues).     I wanted to have a working prototype before
posting this, however, and this is how I did it.    The ExceptionHandler
still has the job of implementing createException() and getFaultInfo() but
not getFaultType() any more

I also have a simple routine to do something similar for "POJO exceptions"
which do not have a fault bean and which have a Java, not an XML
logical type.

    public DataType<?> getFaultFromExceptionDataType(DataType<?>
excDataType) {

        //
        // 1. Fault physical and Exception physical are one and the same
        //
        Object excPhysical = excDataType.getPhysical();
        if (!(excPhysical instanceof Class)) {
            return null;    // Should we be throwing exc instead?
        }
        Class excClass = (Class)excPhysical;

        // Only the physical is set here.
        DataType faultDataType = new DataTypeImpl(null, excClass, null);
        faultDataType.setExceptionPhysical(excClass);

        //
        // 2. Send through already-existing introspection routine
        //

        // Don't try to propagate annotations yet.  Note the DB on the
faultDataType
        // is set by the databinding according to the implied contract we
have going.
        dataBindingRegistry.introspectType(faultDataType, null);

        //
        // 3) instantiate an exception handler for this fault from the
appropriate DB and
        //    set in the fault DT
        //

        DataBinding faultDataBinding = dataBindingRegistry.getDataBinding(
faultDataType.getDataBinding());
        ExceptionHandler excHandler = faultDataBinding.getExceptionHandler
();
        faultDataType.setExceptionHandler(excHandler);

        //
        // 4) set the logical to be the exc class as well
        //

        // Having set the physical and DB already, we now set the logical of
the fault
        faultDataType.setLogical(excClass);

        return faultDataType;

    }

Assuming it gets that far, I'm not sure whether it would be better to have
these pieces of code in classes which are added to some registry
(like the databinding registry), or whether it would be better to have one,
master, order in which the exception to fault
mapping is assumed to take place in Tuscany.

I coded up a parallel modification in WSDL introspection in the class:
org.apache.tuscany.sca.interfacedef.wsdl.introspect.WSDLOperation.
Basically I just need to set "FaultException" as the exceptionPhysical on
top of what had been done, as the "logical" was being set just fine already.

------------------------------------------------------------------------------

So, this is getting long........

Where I see this going from here is.. if this sounds interesting to people,
it would be interesting to try incorporating
the Axis2 exc->fault mapping pattern with the example from the recent JIRA
Simon worked on into this new view I'm working on.

Another pattern I could imagine would be the one mentioned in JAX-WS Sec.
3.7 in cases in which the exceptions don't conform to the Sec 2.5 pattern.

And it might be that my point about "decoupling" is only partially right.
Maybe the POJO exception case will always be associated with JavaBeans DB
and maybe the JAX-WS Sec 3.7 case will always be associated with JAXB.

However, I wanted to get this posted before thinking through all those
permutations.

Thanks,
Scott

Re: handling exceptions and faults better with the Tuscany databinding framework

Posted by Scott Kurz <sc...@gmail.com>.
OK... so at least it sounds reasonable ;)     I attached a patch a the
r558780 level to TUSCANY-1206 to keep the discussion going.    It could
really use some careful review from you, Raymond, at least, and some rework
is needed to the newest code level, as this is pretty old.

There are some questions to answer..  a couple of these I already raised in
my note and at least one or two more (e.g. in the interface-wsdl
introspection is it OK to ignore the fault physical like I did?).

We can discuss in something like IRC if that's easier.

Thanks,
Scott






On 10/19/07, Raymond Feng <en...@gmail.com> wrote:
>
> Hi, Scott.
>
> Sorry for the long .... delay. Your proposal sounds reasonable to me.
> Would
> you consider helping us by providing a patch?
>
> Thanks,
> Raymond
>
> ----- Original Message -----
> From: "Scott Kurz" <sc...@gmail.com>
> To: <tu...@ws.apache.org>
> Sent: Wednesday, October 10, 2007 8:20 AM
> Subject: Re: handling exceptions and faults better with the Tuscany
> databinding framework
>
>
> >I posted this and it probably got lost in the midst of  releasing 1.0 ...
> > let me resend now.
> >
> > Thanks,
> > Scott
> >
> >
> > On 9/15/07, Scott Kurz <sc...@gmail.com> wrote:
> >>
> >> In doing some work trying to leverage the Tuscany databinding framework
> >> to
> >> transform business exceptions across a binding, I noticed a couple
> issues
> >> relating to the need to handle both exception and fault DataType(s) .
> >>
> >> Basically, I'd like to discuss:
> >>
> >> * getting rid of the exception DataType and replacing it with simply a
> >> fault DataType.
> >> * decoupling the fault databinding from the way that the exception maps
> >> to
> >> a fault.
> >>
> >> Let me explain:
> >>
> >> Today, for Java interfaces, we build exception DataTypes during
> >> theintrospection phase
> >> and we set a databinding upon it.  This DB identifies an
> exceptionHandler
> >> which can (via getFaultType())  construct a fault DataType from the exc
> >> DataType.
> >>
> >> Different exception patterns result in different mappings between
> >> exception and fault data types.   For example, we have the pattern
> >> defined
> >> by JAX-WS Sec 2.5 in which the Java exception class wrappers a "fault
> >> bean" returned by the exception's getFaultInfo().   I'm thinking we
> also
> >> want to support POJO exceptions as well in certain contexts.
> >>
> >> Today we would support the JAX-WS Sec. 2.5 pattern by constructing an
> >> DataType wrappering the exception, introspecting the exception to find
> >> thefault
> >> and its databinding.   This databinding's exception handler would, at
> >> transform time, be used to construct a fault DataType representing
> >> thefault bean, distinct from
> >> the exception DataType.     This more or less works the same for JAXB
> >> andSDO, except that for SDO we have
> >> the Tuscany-ism of looking at FAULT_ELEMENT instead of @WebFault (
> which
> >> I
> >> mention below I'd like to change).
> >>
> >> For the POJO exception pattern, on the other hand, the fault DataType
> >> andexception DataType collapse into one as we see in
> >> the logic of JavaBeansExceptionHandler.
> >>
> >> I don't think we need the complexity of the two DataTypes;  I think all
> >> we
> >> really need from the exception DataType is its "physical', i.e. the
> Java
> >> Class of the exception type.   We use this to match the exception we
> have
> >> in-hand from the Java runtime with the DataType on the operation.   It
> is
> >> only the fault that gets transformed by the Tuscany databinding
> >> framework.
> >>
> >>
> >> Perhaps what would be better, instead of an exception DataType and
> fault
> >> DataType, would be to simply have the fault DataType with an additional
> >> "exceptionPhysical" member.    (We still need ExceptionHandler
> >> withgetFaultInfo()
> >> and createFaultException() as well).
> >>
> >> This would let us get the exception handlers out of the introspection
> >> business.
> >>
> >> If we look at DataBindingJavaInterfaceProcessor.processInterface()
> today,
> >> and see how the various databindings' exception handlers'
> getFaultType()s
> >> are called in order to find the right databinding to set on the
> exception
> >> DataType, it does seem messy to have to rely on this same
> getFaultType()
> >> method to work in a certain way and introspection time and transform
> >> time.
> >>
> >> The best reason, I think is elegance:  if it is the actual fault
> DataType
> >> which is interesting at transform time, and if we have an introspect
> >> step,
> >> let's have the introspect step set up this interesting fault
> >> DataType.      As an example, in  working on some binding impl code in
> >> thepast, I found myself calling this same getFaultType() method to get
> >> the fault from the exc...   making for at least three times this same
> >> getFaultType() method was called (Java introspect, my binding
> >> construction,
> >> and transform time).
> >>
> >> Then there is also performance to consider...
> >>
> >> ---------
> >>
> >> In addition, (and to some degree this is a separate point),  I think we
> >> should recognize certain patterns in which a Java exception relates to
> >> both
> >> the Java type of the "fault bean" and to a logical type and decouple
> >> these
> >> patterns from association with one of the various databinding impls we
> >> support.
> >>
> >> So, as an example, if you take the pattern in JAX-WS Sec. 2.5, you can
> >> have an exception with @WebFault(<fault elem>)  with a getFaultInfo()
> >> method returning a fault bean of any of the simple, SDO, or JAXB
> >> databindings.     I don't see the rationale for using FAULT_ELEMENT to
> >> denote the logical type when the fault bean is an SDO vs. using
> >> the@WebFault for a JAXB;  I think this pattern should be decoupled from
> >> the choice of databinding, and we don't want the same  algorithm
> (looking
> >> for @WebFault and using reflection to find the type returned by
> >> getFaultInfo(), etc.) to be re-coded for each databinding.
> >>
> >> (Though I don't think Tuscany has it presently, I coded a Simple DB
> >> ExceptionHandler which is largely just a copy of the
> SDOExceptionHandler,
> >> wihch illustrates my point.   Someone please correct me if Tuscany can
> >> already handle simple-typed fault beans in the JAX-WS Sec 2.5 pattern).
> >>
> >>
> >> In addition we'd have other patterns like POJO exception and maybe
> >> theAxis2 exception which Simon Nash recently did some work regarding.
> >>
> >>
> >> At this point I'd like to show some sample code, which is part of some
> >> changes I've run with successfully (some of my own tests in my own
> >> sandbox
> >> - not Tuscany tests yet).
> >>
> >>
> >>     public DataType<?> getFaultFromExceptionDataType(DataType<?>
> >> excDataType) {
> >>
> >>         //
> >>         // 1. Find the Java type of the fault bean, construct fault DT
> >> andset exc physical
> >>         //
> >>         Object excPhysical = excDataType.getPhysical();
> >>         if (!(excPhysical instanceof Class)) {
> >>             return null;    // Should we be throwing exc instead?
> >>         }
> >>         Class excClass = (Class)excPhysical;
> >>         Class faultBeanClass = null;
> >>         try {
> >>             Method method = excClass.getMethod("getFaultInfo",
> >> EMPTY_CLASS_ARRAY);
> >>             faultBeanClass = method.getReturnType();
> >>         } catch (NoSuchMethodException e) {
> >>             faultBeanClass = null;
> >>         }
> >>         if (faultBeanClass == null) {
> >>             return null;
> >>         }
> >>
> >>         // Only the physical is set here.
> >>         DataType faultDataType = new DataTypeImpl(null, faultBeanClass,
> >> null);
> >>         faultDataType.setExceptionPhysical(excClass);
> >>
> >>         //
> >>         // 2. Send through already-existing introspection routine
> >>         //
> >>
> >>         // Don't try to propagate annotations yet.  Note the DB on
> >> thefaultDataType
> >>         // is set by the databinding according to the implied contract
> we
> >> have going.
> >>         dataBindingRegistry.introspectType(faultDataType, null);
> >>
> >>         //
> >>         // 3) instantiate an exception handler for this fault from
> >> theappropriate DB
> >> and
> >>         //    set in the fault DT
> >>         //
> >>
> >>         DataBinding faultDataBinding =
> >> dataBindingRegistry.getDataBinding(
> >> faultDataType.getDataBinding());
> >>         ExceptionHandler excHandler =
> >> faultDataBinding.getExceptionHandler();
> >>         faultDataType.setExceptionHandler(excHandler);
> >>
> >>         //
> >>         // 4) set the logical from the @WebFault (FAULT_ELEMENT for
> now)
> >>         //
> >>         QName faultElement = null;
> >>         try {
> >>             Field field = excClass.getField("FAULT_ELEMENT");
> >>             faultElement = (QName)field.get(null);
> >>         } catch (NoSuchFieldException e) {
> >>             // Ignore
> >>         } catch (Throwable e) {
> >>             // Ignore
> >>         }
> >>         if (faultElement == null) {
> >>             // Should we be responsible for calculating a default
> >> fault_elem
> >>             // or leave this to someone else???
> >>             return null;
> >>         }
> >>
> >>         // Having set the physical and DB already, we now set the
> logical
> >> of the fault
> >>         faultDataType.setLogical(new XMLType(faultElement, null));
> >>
> >>         return faultDataType;
> >>
> >>     }
> >>
> >>
> >> The above is code that would be called in some form from
> >> DataBindingJavaInterfaceProcessor.processInterface(), passing in the
> >> exception DataType.
> >>
> >> In this code, I'm finding the fault bean class through a
> >> databinding-neutral
> >> look at the getFaultInfo() return type.  I'm then setting the DB on
> this
> >> based on the normal DB.introspect() routine (i.e. the same
> introspection
> >> of input and output types to find the databinding).
> >> Step 4 is to set the logical, again in a databinding-neutral way.
> >>
> >> I also have a step 3 where the ExceptionHandler is now stored in
> >> theDataType.   This is a non-trivial change which could probably
> >> really use some improvement (it brings up build and intra-project
> >> dependency issues).     I wanted to have a working prototype before
> >> posting this, however, and this is how I did it.    The
> ExceptionHandler
> >> still has the job of implementing createException() and getFaultInfo()
> >> but
> >>
> >> not getFaultType() any more
> >>
> >> I also have a simple routine to do something similar for "POJO
> >> exceptions"
> >> which do not have a fault bean and which have a Java, not an XML
> >> logical type.
> >>
> >>     public DataType<?> getFaultFromExceptionDataType(DataType<?>
> >> excDataType) {
> >>
> >>         //
> >>         // 1. Fault physical and Exception physical are one and the
> same
> >>         //
> >>         Object excPhysical = excDataType.getPhysical();
> >>         if (!(excPhysical instanceof Class)) {
> >>             return null;    // Should we be throwing exc instead?
> >>         }
> >>         Class excClass = (Class)excPhysical;
> >>
> >>         // Only the physical is set here.
> >>         DataType faultDataType = new DataTypeImpl(null, excClass,
> null);
> >>         faultDataType.setExceptionPhysical(excClass);
> >>
> >>         //
> >>         // 2. Send through already-existing introspection routine
> >>         //
> >>
> >>         // Don't try to propagate annotations yet.  Note the DB on
> >> thefaultDataType
> >>         // is set by the databinding according to the implied contract
> we
> >> have going.
> >>         dataBindingRegistry.introspectType(faultDataType, null);
> >>
> >>         //
> >>         // 3) instantiate an exception handler for this fault from
> >> theappropriate DB
> >> and
> >>         //    set in the fault DT
> >>         //
> >>
> >>         DataBinding faultDataBinding =
> >> dataBindingRegistry.getDataBinding(
> >> faultDataType.getDataBinding());
> >>         ExceptionHandler excHandler =
> >> faultDataBinding.getExceptionHandler();
> >>         faultDataType.setExceptionHandler(excHandler);
> >>
> >>         //
> >>         // 4) set the logical to be the exc class as well
> >>         //
> >>
> >>         // Having set the physical and DB already, we now set the
> logical
> >> of the fault
> >>         faultDataType.setLogical(excClass);
> >>
> >>         return faultDataType;
> >>
> >>     }
> >>
> >> Assuming it gets that far, I'm not sure whether it would be better to
> >> have
> >> these pieces of code in classes which are added to some registry
> >> (like the databinding registry), or whether it would be better to have
> >> one, master, order in which the exception to fault
> >> mapping is assumed to take place in Tuscany.
> >>
> >> I coded up a parallel modification in WSDL introspection in the class:
> >> org.apache.tuscany.sca.interfacedef.wsdl.introspect.WSDLOperation.
> >> Basically I just need to set "FaultException" as the exceptionPhysical
> on
> >> top of what had been done, as the "logical" was being set just fine
> >> already.
> >>
> >>
> >>
> ------------------------------------------------------------------------------
> >>
> >> So, this is getting long........
> >>
> >> Where I see this going from here is.. if this sounds interesting to
> >> people, it would be interesting to try incorporating
> >> the Axis2 exc->fault mapping pattern with the example from the recent
> >> JIRA
> >> Simon worked on into this new view I'm working on.
> >>
> >> Another pattern I could imagine would be the one mentioned in JAX-WS
> Sec.
> >> 3.7 in cases in which the exceptions don't conform to the Sec 2.5
> >> pattern.
> >>
> >> And it might be that my point about "decoupling" is only partially
> >> right.   Maybe the POJO exception case will always be associated
> >> withJavaBeans DB
> >> and maybe the JAX-WS Sec 3.7 case will always be associated withJAXB.
> >>
> >> However, I wanted to get this posted before thinking through all those
> >> permutations.
> >>
> >> Thanks,
> >> Scott
> >>
> >>
> >>
> >>
> >>
> >>
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>
>

Re: handling exceptions and faults better with the Tuscany databinding framework

Posted by Raymond Feng <en...@gmail.com>.
Hi, Scott.

Sorry for the long .... delay. Your proposal sounds reasonable to me. Would 
you consider helping us by providing a patch?

Thanks,
Raymond

----- Original Message ----- 
From: "Scott Kurz" <sc...@gmail.com>
To: <tu...@ws.apache.org>
Sent: Wednesday, October 10, 2007 8:20 AM
Subject: Re: handling exceptions and faults better with the Tuscany 
databinding framework


>I posted this and it probably got lost in the midst of  releasing 1.0 ...
> let me resend now.
>
> Thanks,
> Scott
>
>
> On 9/15/07, Scott Kurz <sc...@gmail.com> wrote:
>>
>> In doing some work trying to leverage the Tuscany databinding framework 
>> to
>> transform business exceptions across a binding, I noticed a couple issues
>> relating to the need to handle both exception and fault DataType(s) .
>>
>> Basically, I'd like to discuss:
>>
>> * getting rid of the exception DataType and replacing it with simply a
>> fault DataType.
>> * decoupling the fault databinding from the way that the exception maps 
>> to
>> a fault.
>>
>> Let me explain:
>>
>> Today, for Java interfaces, we build exception DataTypes during 
>> theintrospection phase
>> and we set a databinding upon it.  This DB identifies an exceptionHandler
>> which can (via getFaultType())  construct a fault DataType from the exc
>> DataType.
>>
>> Different exception patterns result in different mappings between
>> exception and fault data types.   For example, we have the pattern 
>> defined
>> by JAX-WS Sec 2.5 in which the Java exception class wrappers a "fault
>> bean" returned by the exception's getFaultInfo().   I'm thinking we also
>> want to support POJO exceptions as well in certain contexts.
>>
>> Today we would support the JAX-WS Sec. 2.5 pattern by constructing an
>> DataType wrappering the exception, introspecting the exception to find 
>> thefault
>> and its databinding.   This databinding's exception handler would, at
>> transform time, be used to construct a fault DataType representing 
>> thefault bean, distinct from
>> the exception DataType.     This more or less works the same for JAXB 
>> andSDO, except that for SDO we have
>> the Tuscany-ism of looking at FAULT_ELEMENT instead of @WebFault ( which 
>> I
>> mention below I'd like to change).
>>
>> For the POJO exception pattern, on the other hand, the fault DataType 
>> andexception DataType collapse into one as we see in
>> the logic of JavaBeansExceptionHandler.
>>
>> I don't think we need the complexity of the two DataTypes;  I think all 
>> we
>> really need from the exception DataType is its "physical', i.e. the Java
>> Class of the exception type.   We use this to match the exception we have
>> in-hand from the Java runtime with the DataType on the operation.   It is
>> only the fault that gets transformed by the Tuscany databinding 
>> framework.
>>
>>
>> Perhaps what would be better, instead of an exception DataType and fault
>> DataType, would be to simply have the fault DataType with an additional
>> "exceptionPhysical" member.    (We still need ExceptionHandler 
>> withgetFaultInfo()
>> and createFaultException() as well).
>>
>> This would let us get the exception handlers out of the introspection
>> business.
>>
>> If we look at DataBindingJavaInterfaceProcessor.processInterface() today,
>> and see how the various databindings' exception handlers' getFaultType()s
>> are called in order to find the right databinding to set on the exception
>> DataType, it does seem messy to have to rely on this same getFaultType()
>> method to work in a certain way and introspection time and transform
>> time.
>>
>> The best reason, I think is elegance:  if it is the actual fault DataType
>> which is interesting at transform time, and if we have an introspect 
>> step,
>> let's have the introspect step set up this interesting fault
>> DataType.      As an example, in  working on some binding impl code in 
>> thepast, I found myself calling this same getFaultType() method to get
>> the fault from the exc...   making for at least three times this same
>> getFaultType() method was called (Java introspect, my binding 
>> construction,
>> and transform time).
>>
>> Then there is also performance to consider...
>>
>> ---------
>>
>> In addition, (and to some degree this is a separate point),  I think we
>> should recognize certain patterns in which a Java exception relates to 
>> both
>> the Java type of the "fault bean" and to a logical type and decouple 
>> these
>> patterns from association with one of the various databinding impls we
>> support.
>>
>> So, as an example, if you take the pattern in JAX-WS Sec. 2.5, you can
>> have an exception with @WebFault(<fault elem>)  with a getFaultInfo()
>> method returning a fault bean of any of the simple, SDO, or JAXB
>> databindings.     I don't see the rationale for using FAULT_ELEMENT to
>> denote the logical type when the fault bean is an SDO vs. using 
>> the@WebFault for a JAXB;  I think this pattern should be decoupled from
>> the choice of databinding, and we don't want the same  algorithm (looking
>> for @WebFault and using reflection to find the type returned by
>> getFaultInfo(), etc.) to be re-coded for each databinding.
>>
>> (Though I don't think Tuscany has it presently, I coded a Simple DB
>> ExceptionHandler which is largely just a copy of the SDOExceptionHandler,
>> wihch illustrates my point.   Someone please correct me if Tuscany can
>> already handle simple-typed fault beans in the JAX-WS Sec 2.5 pattern).
>>
>>
>> In addition we'd have other patterns like POJO exception and maybe 
>> theAxis2 exception which Simon Nash recently did some work regarding.
>>
>>
>> At this point I'd like to show some sample code, which is part of some
>> changes I've run with successfully (some of my own tests in my own 
>> sandbox
>> - not Tuscany tests yet).
>>
>>
>>     public DataType<?> getFaultFromExceptionDataType(DataType<?>
>> excDataType) {
>>
>>         //
>>         // 1. Find the Java type of the fault bean, construct fault DT 
>> andset exc physical
>>         //
>>         Object excPhysical = excDataType.getPhysical();
>>         if (!(excPhysical instanceof Class)) {
>>             return null;    // Should we be throwing exc instead?
>>         }
>>         Class excClass = (Class)excPhysical;
>>         Class faultBeanClass = null;
>>         try {
>>             Method method = excClass.getMethod("getFaultInfo",
>> EMPTY_CLASS_ARRAY);
>>             faultBeanClass = method.getReturnType();
>>         } catch (NoSuchMethodException e) {
>>             faultBeanClass = null;
>>         }
>>         if (faultBeanClass == null) {
>>             return null;
>>         }
>>
>>         // Only the physical is set here.
>>         DataType faultDataType = new DataTypeImpl(null, faultBeanClass,
>> null);
>>         faultDataType.setExceptionPhysical(excClass);
>>
>>         //
>>         // 2. Send through already-existing introspection routine
>>         //
>>
>>         // Don't try to propagate annotations yet.  Note the DB on 
>> thefaultDataType
>>         // is set by the databinding according to the implied contract we
>> have going.
>>         dataBindingRegistry.introspectType(faultDataType, null);
>>
>>         //
>>         // 3) instantiate an exception handler for this fault from 
>> theappropriate DB
>> and
>>         //    set in the fault DT
>>         //
>>
>>         DataBinding faultDataBinding = 
>> dataBindingRegistry.getDataBinding(
>> faultDataType.getDataBinding());
>>         ExceptionHandler excHandler = 
>> faultDataBinding.getExceptionHandler();
>>         faultDataType.setExceptionHandler(excHandler);
>>
>>         //
>>         // 4) set the logical from the @WebFault (FAULT_ELEMENT for now)
>>         //
>>         QName faultElement = null;
>>         try {
>>             Field field = excClass.getField("FAULT_ELEMENT");
>>             faultElement = (QName)field.get(null);
>>         } catch (NoSuchFieldException e) {
>>             // Ignore
>>         } catch (Throwable e) {
>>             // Ignore
>>         }
>>         if (faultElement == null) {
>>             // Should we be responsible for calculating a default
>> fault_elem
>>             // or leave this to someone else???
>>             return null;
>>         }
>>
>>         // Having set the physical and DB already, we now set the logical
>> of the fault
>>         faultDataType.setLogical(new XMLType(faultElement, null));
>>
>>         return faultDataType;
>>
>>     }
>>
>>
>> The above is code that would be called in some form from
>> DataBindingJavaInterfaceProcessor.processInterface(), passing in the
>> exception DataType.
>>
>> In this code, I'm finding the fault bean class through a 
>> databinding-neutral
>> look at the getFaultInfo() return type.  I'm then setting the DB on this
>> based on the normal DB.introspect() routine (i.e. the same introspection
>> of input and output types to find the databinding).
>> Step 4 is to set the logical, again in a databinding-neutral way.
>>
>> I also have a step 3 where the ExceptionHandler is now stored in 
>> theDataType.   This is a non-trivial change which could probably
>> really use some improvement (it brings up build and intra-project
>> dependency issues).     I wanted to have a working prototype before
>> posting this, however, and this is how I did it.    The ExceptionHandler
>> still has the job of implementing createException() and getFaultInfo() 
>> but
>>
>> not getFaultType() any more
>>
>> I also have a simple routine to do something similar for "POJO 
>> exceptions"
>> which do not have a fault bean and which have a Java, not an XML
>> logical type.
>>
>>     public DataType<?> getFaultFromExceptionDataType(DataType<?>
>> excDataType) {
>>
>>         //
>>         // 1. Fault physical and Exception physical are one and the same
>>         //
>>         Object excPhysical = excDataType.getPhysical();
>>         if (!(excPhysical instanceof Class)) {
>>             return null;    // Should we be throwing exc instead?
>>         }
>>         Class excClass = (Class)excPhysical;
>>
>>         // Only the physical is set here.
>>         DataType faultDataType = new DataTypeImpl(null, excClass, null);
>>         faultDataType.setExceptionPhysical(excClass);
>>
>>         //
>>         // 2. Send through already-existing introspection routine
>>         //
>>
>>         // Don't try to propagate annotations yet.  Note the DB on 
>> thefaultDataType
>>         // is set by the databinding according to the implied contract we
>> have going.
>>         dataBindingRegistry.introspectType(faultDataType, null);
>>
>>         //
>>         // 3) instantiate an exception handler for this fault from 
>> theappropriate DB
>> and
>>         //    set in the fault DT
>>         //
>>
>>         DataBinding faultDataBinding = 
>> dataBindingRegistry.getDataBinding(
>> faultDataType.getDataBinding());
>>         ExceptionHandler excHandler = 
>> faultDataBinding.getExceptionHandler();
>>         faultDataType.setExceptionHandler(excHandler);
>>
>>         //
>>         // 4) set the logical to be the exc class as well
>>         //
>>
>>         // Having set the physical and DB already, we now set the logical
>> of the fault
>>         faultDataType.setLogical(excClass);
>>
>>         return faultDataType;
>>
>>     }
>>
>> Assuming it gets that far, I'm not sure whether it would be better to 
>> have
>> these pieces of code in classes which are added to some registry
>> (like the databinding registry), or whether it would be better to have
>> one, master, order in which the exception to fault
>> mapping is assumed to take place in Tuscany.
>>
>> I coded up a parallel modification in WSDL introspection in the class:
>> org.apache.tuscany.sca.interfacedef.wsdl.introspect.WSDLOperation.
>> Basically I just need to set "FaultException" as the exceptionPhysical on
>> top of what had been done, as the "logical" was being set just fine
>> already.
>>
>>
>> ------------------------------------------------------------------------------
>>
>> So, this is getting long........
>>
>> Where I see this going from here is.. if this sounds interesting to
>> people, it would be interesting to try incorporating
>> the Axis2 exc->fault mapping pattern with the example from the recent 
>> JIRA
>> Simon worked on into this new view I'm working on.
>>
>> Another pattern I could imagine would be the one mentioned in JAX-WS Sec.
>> 3.7 in cases in which the exceptions don't conform to the Sec 2.5 
>> pattern.
>>
>> And it might be that my point about "decoupling" is only partially
>> right.   Maybe the POJO exception case will always be associated 
>> withJavaBeans DB
>> and maybe the JAX-WS Sec 3.7 case will always be associated withJAXB.
>>
>> However, I wanted to get this posted before thinking through all those
>> permutations.
>>
>> Thanks,
>> Scott
>>
>>
>>
>>
>>
>>
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-dev-help@ws.apache.org


Re: handling exceptions and faults better with the Tuscany databinding framework

Posted by Scott Kurz <sc...@gmail.com>.
I posted this and it probably got lost in the midst of  releasing 1.0 ...
let me resend now.

Thanks,
Scott


On 9/15/07, Scott Kurz <sc...@gmail.com> wrote:
>
> In doing some work trying to leverage the Tuscany databinding framework to
> transform business exceptions across a binding, I noticed a couple issues
> relating to the need to handle both exception and fault DataType(s) .
>
> Basically, I'd like to discuss:
>
> * getting rid of the exception DataType and replacing it with simply a
> fault DataType.
> * decoupling the fault databinding from the way that the exception maps to
> a fault.
>
> Let me explain:
>
> Today, for Java interfaces, we build exception DataTypes during theintrospection phase
> and we set a databinding upon it.  This DB identifies an exceptionHandler
> which can (via getFaultType())  construct a fault DataType from the exc
> DataType.
>
> Different exception patterns result in different mappings between
> exception and fault data types.   For example, we have the pattern defined
> by JAX-WS Sec 2.5 in which the Java exception class wrappers a "fault
> bean" returned by the exception's getFaultInfo().   I'm thinking we also
> want to support POJO exceptions as well in certain contexts.
>
> Today we would support the JAX-WS Sec. 2.5 pattern by constructing an
> DataType wrappering the exception, introspecting the exception to find thefault
> and its databinding.   This databinding's exception handler would, at
> transform time, be used to construct a fault DataType representing thefault bean, distinct from
> the exception DataType.     This more or less works the same for JAXB andSDO, except that for SDO we have
> the Tuscany-ism of looking at FAULT_ELEMENT instead of @WebFault ( which I
> mention below I'd like to change).
>
> For the POJO exception pattern, on the other hand, the fault DataType andexception DataType collapse into one as we see in
> the logic of JavaBeansExceptionHandler.
>
> I don't think we need the complexity of the two DataTypes;  I think all we
> really need from the exception DataType is its "physical', i.e. the Java
> Class of the exception type.   We use this to match the exception we have
> in-hand from the Java runtime with the DataType on the operation.   It is
> only the fault that gets transformed by the Tuscany databinding framework.
>
>
> Perhaps what would be better, instead of an exception DataType and fault
> DataType, would be to simply have the fault DataType with an additional
> "exceptionPhysical" member.    (We still need ExceptionHandler withgetFaultInfo()
> and createFaultException() as well).
>
> This would let us get the exception handlers out of the introspection
> business.
>
> If we look at DataBindingJavaInterfaceProcessor.processInterface() today,
> and see how the various databindings' exception handlers' getFaultType()s
> are called in order to find the right databinding to set on the exception
> DataType, it does seem messy to have to rely on this same getFaultType()
> method to work in a certain way and introspection time and transform
> time.
>
> The best reason, I think is elegance:  if it is the actual fault DataType
> which is interesting at transform time, and if we have an introspect step,
> let's have the introspect step set up this interesting fault
> DataType.      As an example, in  working on some binding impl code in thepast, I found myself calling this same getFaultType() method to get
> the fault from the exc...   making for at least three times this same
> getFaultType() method was called (Java introspect, my binding construction,
> and transform time).
>
> Then there is also performance to consider...
>
> ---------
>
> In addition, (and to some degree this is a separate point),  I think we
> should recognize certain patterns in which a Java exception relates to both
> the Java type of the "fault bean" and to a logical type and decouple these
> patterns from association with one of the various databinding impls we
> support.
>
> So, as an example, if you take the pattern in JAX-WS Sec. 2.5, you can
> have an exception with @WebFault(<fault elem>)  with a getFaultInfo()
> method returning a fault bean of any of the simple, SDO, or JAXB
> databindings.     I don't see the rationale for using FAULT_ELEMENT to
> denote the logical type when the fault bean is an SDO vs. using the@WebFault for a JAXB;  I think this pattern should be decoupled from
> the choice of databinding, and we don't want the same  algorithm (looking
> for @WebFault and using reflection to find the type returned by
> getFaultInfo(), etc.) to be re-coded for each databinding.
>
> (Though I don't think Tuscany has it presently, I coded a Simple DB
> ExceptionHandler which is largely just a copy of the SDOExceptionHandler,
> wihch illustrates my point.   Someone please correct me if Tuscany can
> already handle simple-typed fault beans in the JAX-WS Sec 2.5 pattern).
>
>
> In addition we'd have other patterns like POJO exception and maybe theAxis2 exception which Simon Nash recently did some work regarding.
>
>
> At this point I'd like to show some sample code, which is part of some
> changes I've run with successfully (some of my own tests in my own sandbox
> - not Tuscany tests yet).
>
>
>     public DataType<?> getFaultFromExceptionDataType(DataType<?>
> excDataType) {
>
>         //
>         // 1. Find the Java type of the fault bean, construct fault DT andset exc physical
>         //
>         Object excPhysical = excDataType.getPhysical();
>         if (!(excPhysical instanceof Class)) {
>             return null;    // Should we be throwing exc instead?
>         }
>         Class excClass = (Class)excPhysical;
>         Class faultBeanClass = null;
>         try {
>             Method method = excClass.getMethod("getFaultInfo",
> EMPTY_CLASS_ARRAY);
>             faultBeanClass = method.getReturnType();
>         } catch (NoSuchMethodException e) {
>             faultBeanClass = null;
>         }
>         if (faultBeanClass == null) {
>             return null;
>         }
>
>         // Only the physical is set here.
>         DataType faultDataType = new DataTypeImpl(null, faultBeanClass,
> null);
>         faultDataType.setExceptionPhysical(excClass);
>
>         //
>         // 2. Send through already-existing introspection routine
>         //
>
>         // Don't try to propagate annotations yet.  Note the DB on thefaultDataType
>         // is set by the databinding according to the implied contract we
> have going.
>         dataBindingRegistry.introspectType(faultDataType, null);
>
>         //
>         // 3) instantiate an exception handler for this fault from theappropriate DB
> and
>         //    set in the fault DT
>         //
>
>         DataBinding faultDataBinding = dataBindingRegistry.getDataBinding(
> faultDataType.getDataBinding());
>         ExceptionHandler excHandler = faultDataBinding.getExceptionHandler();
>         faultDataType.setExceptionHandler(excHandler);
>
>         //
>         // 4) set the logical from the @WebFault (FAULT_ELEMENT for now)
>         //
>         QName faultElement = null;
>         try {
>             Field field = excClass.getField("FAULT_ELEMENT");
>             faultElement = (QName)field.get(null);
>         } catch (NoSuchFieldException e) {
>             // Ignore
>         } catch (Throwable e) {
>             // Ignore
>         }
>         if (faultElement == null) {
>             // Should we be responsible for calculating a default
> fault_elem
>             // or leave this to someone else???
>             return null;
>         }
>
>         // Having set the physical and DB already, we now set the logical
> of the fault
>         faultDataType.setLogical(new XMLType(faultElement, null));
>
>         return faultDataType;
>
>     }
>
>
> The above is code that would be called in some form from
> DataBindingJavaInterfaceProcessor.processInterface(), passing in the
> exception DataType.
>
> In this code, I'm finding the fault bean class through a databinding-neutral
> look at the getFaultInfo() return type.  I'm then setting the DB on this
> based on the normal DB.introspect() routine (i.e. the same introspection
> of input and output types to find the databinding).
> Step 4 is to set the logical, again in a databinding-neutral way.
>
> I also have a step 3 where the ExceptionHandler is now stored in theDataType.   This is a non-trivial change which could probably
> really use some improvement (it brings up build and intra-project
> dependency issues).     I wanted to have a working prototype before
> posting this, however, and this is how I did it.    The ExceptionHandler
> still has the job of implementing createException() and getFaultInfo() but
>
> not getFaultType() any more
>
> I also have a simple routine to do something similar for "POJO exceptions"
> which do not have a fault bean and which have a Java, not an XML
> logical type.
>
>     public DataType<?> getFaultFromExceptionDataType(DataType<?>
> excDataType) {
>
>         //
>         // 1. Fault physical and Exception physical are one and the same
>         //
>         Object excPhysical = excDataType.getPhysical();
>         if (!(excPhysical instanceof Class)) {
>             return null;    // Should we be throwing exc instead?
>         }
>         Class excClass = (Class)excPhysical;
>
>         // Only the physical is set here.
>         DataType faultDataType = new DataTypeImpl(null, excClass, null);
>         faultDataType.setExceptionPhysical(excClass);
>
>         //
>         // 2. Send through already-existing introspection routine
>         //
>
>         // Don't try to propagate annotations yet.  Note the DB on thefaultDataType
>         // is set by the databinding according to the implied contract we
> have going.
>         dataBindingRegistry.introspectType(faultDataType, null);
>
>         //
>         // 3) instantiate an exception handler for this fault from theappropriate DB
> and
>         //    set in the fault DT
>         //
>
>         DataBinding faultDataBinding = dataBindingRegistry.getDataBinding(
> faultDataType.getDataBinding());
>         ExceptionHandler excHandler = faultDataBinding.getExceptionHandler();
>         faultDataType.setExceptionHandler(excHandler);
>
>         //
>         // 4) set the logical to be the exc class as well
>         //
>
>         // Having set the physical and DB already, we now set the logical
> of the fault
>         faultDataType.setLogical(excClass);
>
>         return faultDataType;
>
>     }
>
> Assuming it gets that far, I'm not sure whether it would be better to have
> these pieces of code in classes which are added to some registry
> (like the databinding registry), or whether it would be better to have
> one, master, order in which the exception to fault
> mapping is assumed to take place in Tuscany.
>
> I coded up a parallel modification in WSDL introspection in the class:
> org.apache.tuscany.sca.interfacedef.wsdl.introspect.WSDLOperation.
> Basically I just need to set "FaultException" as the exceptionPhysical on
> top of what had been done, as the "logical" was being set just fine
> already.
>
>
> ------------------------------------------------------------------------------
>
> So, this is getting long........
>
> Where I see this going from here is.. if this sounds interesting to
> people, it would be interesting to try incorporating
> the Axis2 exc->fault mapping pattern with the example from the recent JIRA
> Simon worked on into this new view I'm working on.
>
> Another pattern I could imagine would be the one mentioned in JAX-WS Sec.
> 3.7 in cases in which the exceptions don't conform to the Sec 2.5 pattern.
>
> And it might be that my point about "decoupling" is only partially
> right.   Maybe the POJO exception case will always be associated withJavaBeans DB
> and maybe the JAX-WS Sec 3.7 case will always be associated withJAXB.
>
> However, I wanted to get this posted before thinking through all those
> permutations.
>
> Thanks,
> Scott
>
>
>
>
>
>