Purpose: Send an email to admin every time an exception occurs while executing business logic.
Till now I have come across "throwing advice" which is fine and gets executed when an exception is raised from the target method.
This could have worked well for me but I have to do some additional processing in terms of setting request attribute and next page. I don't think it would be a good idea to share the objects from target class with advice by making those objects static. The code scenario is shown below:
try{
//normal processing
} catch (AuthenticationException ae) {
ae.printStackTrace();
req.setAttribute("msg", ae.getMessage());
//execute advice at this point
return loginPage;
}
Pls. see the point where I want to execute the advice and suggest solution accordingly.
Best Regards
As far as my understanding says why AuthenticationException is thrown in business logic code.If you really want to use aop keep urs business code far from cross cutting concern. In yours case you can take out AuthenticationException code from business logic.Before entering in business logic operation apply aop.for example
Custom exception
ok, after going through reference books like Spring in Action, I came to know that there is no way by which we can invoke spring advices at arbitrary points in our java code. Spring in Action book recommends to have a look at AspectJ for fine grain control over point cuts.
In order to avoid adding AspectJ, I came across the following solution which could help others and save their precious time:
1) Use an Around advice for the method where you want to invoke advice only when an exception occurs. Like in my case, I want to send email notification when an exception occurs and we get out of the catch block. Basically I wanted to do some processing in the catch block before invoking advice.
2) When using Around advice, we can read the member variables of target object as method arguments. If you want to share some data with the advice, it is also one of the way. In my case I wanted details from the target object about email subject and body.
Code for around advice:
Do share your feedback/queries on this approach.
AFAIK there is no pointcut expression for this...
You should consider configuring your logger to do what you need. Replace
ae.printStackTrace();
by something likelogger.warn(ae)
(to print stacktraces to the console is quite bad practice anyways), and configure one of the email-sending appenders of your logging tool, e.g. log4j's or logback's SMTPAppender. Additionally, to make your configuration easier, you may use a business-dedicated logger.If you really want to use aspects here, I think you'll have to expect all your business exceptions to bubble up at least one method, in order to use afterThrowing advices.
I know you want to avoid full AspectJ as opposed to Spring AOP. (BTW, I wonder why many people are so afraid of it.) Anyway, in AspectJ is is really easy to intercept exception handler execution (=catch blocks) by means of the
handler()
pointcut. There is one limitation though: It only works withbefore()
advice, notafter()
oraround()
. This is due to compiler limitations. Look at JVM byte code of exception handlers and you will see that there is no way to detect the end of a handler block. Anyway, because the concept is related to the original question, I want to show here how it is done. I have created a little driver application and a very simple aspect:As you can see, methods
foo
andbar
throw exceptions based on random values in ca. 50% of all cases, whereaszot
always throws a division by zero exception. So the output will differ from run to run.So how do we find out what is going on if all exceptions are silently swallowed and not logged? Like so:
This is really simple and elegant and works throughout your application. Here is some test output:
In the advice you can do more, e.g. access
this
and read/update some properties and so fort.