I'll
let other on the list share experiences from their applications, but let me make
a general comment about the use of AspectJ, or really any AOP tool for pervasive
logging.
Sometimes, in order to get the logging you want, you have to refactor the
main code some, for example to introduce method calls in the right places.
For example, you might have a big method like:
/* do part 1 */
foo(a);
bar(b);
baz(c);
/* do part 2 */
more(a, b)
evenMore(b, c)
and
you end up refactoring it to something like:
doPartOne(a, b, c);
doPartTwo(a, b, c);
(of
course the names would all be more reasonable).
so
that you can easily log the two parts.
The issues you mention
may be amenable to such refactoring, as above, or for example to make sure there
is a method call at each point where you enter a scope in which the meaning of a
certain kind of throw changes.
Sometimes people have an initial reluctance to have to refactor the base
code, believing that the base code should be entirely oblivious to the aspects
that advise it. But, experience suggests that refactoring the base code is fine,
as long as the refactoring is actually making the base code more clear, as
opposed to changing it in some idiosyncratic way, just for the aspects. For
example, the refactoring above probably makes the base code more clear, and so
its reasonable to do.
In applications that
have a clean module structure for the non-crosscutting concerns, judicious use
of pointcuts with wildcards can often be very effective in handling logging. You
can also use the cflow && !cflowbelow idiom for logging the outermost
throw, or percflow and a flag for logging the innermost one.
This next part is speculation: I believe that
as more advanced research in AOP continues, and finds its way into the
commercial tools, we will develop pointcuts that are subtle enough that less of
this kind of refactoring will be required. I don't know how popular such fancy
pointcuts will prove to be in practice though, and in any event they are several
years away.