Bug 45231 - Feature request: User-specifiable exception in "declare soft"
Summary: Feature request: User-specifiable exception in "declare soft"
Status: REOPENED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.2   Edit
Hardware: PC Windows XP
: P5 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Jim Hugunin CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-10-20 14:17 EDT by Ramnivas Laddad CLA
Modified: 2009-08-30 02:49 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ramnivas Laddad CLA 2003-10-20 14:17:59 EDT
Here is a feature request to enhance the "declare soft" construct in
a fully backward compatible way.

Currently, the "declare soft" construct is used to soften a checked
exception by throwing an org.aspectj.lang.SoftException wrapping in
original exception. I will like the possibility of specifying a
user-specifiable runtime exception. I intend to use such a feature to
specify a concern-specific runtime exception while softening. This
simple change will help in multiple ways. Here are a few: 

1. The exception call stack will be clearer. I will now have an
   indication of the concern involved by just looking at name of the
   exception thrown.
2. I can catch specific runtime exception at some higher level to
   process it in the most meaningful way. Currently, I need to trap the
   generic SoftException and examine the cause (using getCause()) to
   check if the checked exception needs to be handled.

As it stands now, I almost never use "declare soft" by
itself. Typically, I wrap the checked exceptions in question in a
concern-specific runtime exception and use a "declare soft" to avoid
exception-related compiler errors. A feature to easily support this
idiom will make the code easy to understand and explain.

Possible syntax: declare soft: <Exception to be softened> : <Pointcut>
                            [: <Runtime Exception>];

For example:
declare soft: RemoteException
            : call(* PaymentService. *(..) throws RemoteException)
            : RemoteRuntimeException;
declare soft: SystemException
            : call(* *.*(..) throws SystemException)
            : TransactionRuntimeException;

When the last part ([: <Runtime Exception>]) is omitted, we could
default to the current behavior, hence maintaining backward
compatibility.

The runtime exception specified must have a way to set the wrapped
exception. This is not a problem for JDK1.4+ as initCause() can always
be used. For the earlier JDKs, we could require that the runtime
exception specified must have the "initCuase(Throwable)" method.
Comment 1 Ron Bodkin CLA 2003-12-09 11:36:50 EST
I would like this even more if it were also possible to call a member function 
that returns a throwable or subtype thereof, which takes a single argument: 
the original exception. I use this idiom with abstract aspects and for 
polymorphic exception handling.

E.g.,
aspect Conversion {
  declare soft: Exception
            : call(* model..*(..))
            : convertException;

  ModelException convertException(Throwable cause) {
    throw new ModelException(cause);
  }
}

I know this proposal looks like C# delegates. However using a Java approach 
with worker objects would require exposing the cause as a special form. Maybe 
the 3rd part could be any Java expression and target could return the 
throwable, e.g.,
  declare soft: Exception
            : call(* model..*(..))
            : convertException(target);

or

  declare soft: Exception
            : call(* model..*(..))
            : new RuntimeException(target);
Comment 2 Jim Hugunin CLA 2004-01-14 11:31:41 EST
This can be solved by always using declare soft according to a standard idiom 
where it must be paired with an around advice that does the actual change of 
the exception.  This will increase the verbosity of the examples below, but 
only by a couple of lines.  For Ron's example, you can change it to:

aspect Conversion {
  pointcut soften(): call(* model..*(..));

  declare soft: Exception: soften();
  Object around(): soften() {
    try { return proceed(); }
    catch (Exception e) { throw new ModelException(cause); }
  }
}

This should probably be added to the FAQ.  We can revist this later if there
are a lot more programs out there using declare soft to drive the design.
Comment 3 Eclipse Webmaster CLA 2009-08-30 02:49:41 EDT
LATER/REMIND bugs are being automatically reopened as P5 because the LATER and REMIND resolutions are deprecated.