Hi Raphael,
You should add the exception to those you’ve
handled right after you log: the way your code reads it will never get added. Also,
I would recommend using a WeakHashSet rather than an ArrayList to hold the
exceptions that you’ve seen, so you don’t have a memory leak. I’d
also recommend logging the full stack trace. Here’s a similar aspect that
we use in Glassbox for monitoring applications to handle errors (and also
contain them from bubbling up into monitored code
/***
* Policy enforcement aspect that prevents exceptions from bubbling up into monitored code.
*/
public aspect
ErrorContainment {
// favor
safety over efficiency: containment even applies to the advice that prevents
disabled monitors from running
declare precedence:
ErrorContainment, glassbox.monitor.AbstractMonitor.RuntimeControl;
/**
Map
of
bottom-most stack trace elements that we've ever seen before */
private Map previousFailures = new
HashMap(); // if this is a material leak, we're in big
trouble!
// around/pass
through exceptions?
/**
we
apply
error
containment
to
any
agent
code,
i.e.,
code
that
interacts
with
external
code
(applications,
servers,
etc.)
*/
public pointcut
scope() :
(within(glassbox.monitor..*) || within(glassbox.summary..*)||
within(glassbox.agent..*) || within(glassbox.config..*))
&&
!within(ErrorContainment);// &&
!within(DontContainErrors+);// && !within(NondelegatingURLClassLoader);
// if there's a checked exception, we will pass it through
// we will
need to exclude "root" unchecked exceptions
// this
doesn't deal with proceed - this advice can only apply to before/after...
// kind of lame:
work-around for compiler not able to pick out advice that returns void
statically...
// we rely on
a naming pattern to exclude advice that doesn't match: write a static inner
aspect whose name
// is *Around,
and then code carefully!
Object around() : adviceexecution()
&& scope() && !within(*..*Around)
{ //&&
if(((AdviceSignature)thisJoinPointStaticPart.getSignature()).getReturnType() ==
void.class){ // too slow!
try {
return proceed();
} catch (Error e) {
handle(e);
} catch (RuntimeException rte) {
handle(rte);
}
return null;
// will only
be void
}
declare error:
scope() && call((Throwable+
&& !Exception+ && !Error+).new(..)):
"don't
create random throwables in the monitor code!";
pointcut
executionNotDeclaringCheckedException():
execution(* *(..)) && !execution(*
*(..) throws Exception+);
pointcut eitherExecution() :
executionNotDeclaringCheckedException() || adviceexecution();
declare soft:
Exception+: eitherExecution() && scope();
/**
log
and
swallow
*/
private void
handle(Throwable t) {
boolean shouldLog = true;
String desc = "";
try {
StackTraceElement elt = t.getStackTrace()[0];
MutableInteger val = (MutableInteger)previousFailures.get(elt);
if (val != null)
{
val.setValue(val.getValue()+1);
} else {
val = new
MutableInteger(1);
previousFailures.put(elt, val);
}
shouldLog = (val.getValue() % 1000 == 1);
if (shouldLog) {
desc = (val.getValue()>1 ? "( "+val.getValue() + ") times"
: "");
}
} catch (Throwable rte) {
// swallow
concurrent modifications, etc.
}
//basically
inlining a cflow test for a single point for efficiency...
if (shouldLog) {
// try using
the logger, but don't recurse infinitely if that errors out!
try {
if (loggingError.get() == null)
{
loggingError.set("recurse");
logError(desc, t);
}
} catch (Throwable cantLogError) {
System.err.println("failure
in monitoring aspect "+desc);
t.printStackTrace();
} finally {
loggingError.set(null);
}
}
}
/**
holds
null
if
not
logging
an
error,
or
non-null if already logging an error on the thread */
private ThreadLocal loggingError = new
ThreadLocal();
}
From: aspectj-users-bounces@xxxxxxxxxxx
[mailto:aspectj-users-bounces@xxxxxxxxxxx] On
Behalf Of Raphael Paiva
Sent: Thursday, May 11, 2006 6:32
AM
To: aspectj-users@xxxxxxxxxxx
Subject: Re: [aspectj-users]
Exception handling without duplicated exceptionscaugth
I´m using my solution
like above, some suggest??
public aspect LoggingAspect {
public static final Logger LOG =
Logger.getLogger(LoggingAspect.class.getName());
private List exceptionsHandle = new ArrayList();
pointcut not_aspect(): !within(com.sena.aspectos..*);
/**
* Advice to log all checked exceptions
*/
after() throwing (Exception ex): execution(* *.*(..))
&& not_aspect(){
Signature sig =
thisJoinPointStaticPart.getSignature();
String dadMethod = getDadStackMethod(ex);
if(!exceptionsHandle.contains(dadMethod)){
LOG.logp(Level.SEVERE,
sig.getDeclaringType().getSimpleName(),
sig.getName(),
ex.toString()+ "\n in ["+
dadMethod + "]");
}else{
exceptionsHandle.add(dadMethod);
}
}
/**
* This method get the first method in project who
cause the exception
*/
private String getDadStackMethod(Exception ex) {
int stackIndex = 0;
List listaExcecao = new ArrayList(4);
listaExcecao.add("sun");
listaExcecao.add("java");
listaExcecao.add("javax");
listaExcecao.add("org");
try{
while (true) {
StackTraceElement dadTrace =
ex.getStackTrace()[stackIndex++];
String excecao = dadTrace.getClassName();
if(!listaExcecao.contains(excecao.split("\\.")[0])){
return dadTrace.toString();
}
}
}catch (Exception e) {
return
(ex.getStackTrace()[0]).toString();
}
}
}
--
Thanks,
Raphael
Paiva Fernandes
Sena Informática
Fortaleza -
Ceará - Brasil
E-mail: raphael@xxxxxxxxxxx -
Office: : +55 85 3476-8550
Raphael Paiva wrote:
I´m implementing an
exception handling with aspect but I have a question:
How to ignore duplicated exceptions caugth??
Someone have a good and simple example of an exception handling component in
aspectj?
--
Thanks,
Raphael
Paiva Fernandes
Sena Informática
Fortaleza -
Ceará - Brasil
E-mail: raphael@xxxxxxxxxxx -
Office: : +55 85 3476-8550
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users