PDA

View Full Version : Problem in Spring Java config with @AfterThrowing



jenad
Jun 14th, 2011, 03:37 AM
Hi,

I am new to Spring java config with aop.So please help me to resolve the issue.

I have created a simple project where i am using Spring Java config instead of xml config and spring aop to print something in console when exception thrown in any method.

<Code>
My Configuration class is :

import org.springframework.aop.aspectj.annotation.Annotat ionAwareAspectJAutoProxyCreator;
import org.springframework.context.annotation.Bean;

public class AppConfig {


@Bean
public ExceptionTest exceptionTest() {
return new ExceptionTest();
}

@Bean
public AopException aopException() {
return new AopException();
}

@Bean
public AnnotationAwareAspectJAutoProxyCreator annotationAwareAspectJAutoProxyCreator(){

AnnotationAwareAspectJAutoProxyCreator aop=new AnnotationAwareAspectJAutoProxyCreator();
return aop;
}

My AOP Exception class is :

import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.aop.ThrowsAdvice;

@Aspect
public class AopException implements ThrowsAdvice {

@AfterThrowing(pointcut="execution(* com.acs.AopException.method1())",throwing="ex")
public void afterThrowing(Throwable ex)
{
System.out.println("Inside afterThrowing()");
}

}

My Business Java class is :

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationC onfigApplicationContext;

public class ExceptionTest {

public void method1()
{
try {
int x=10;
int y=x/0;
} catch (ArithmeticException ex) {
System.out.println("Exception Occured");
ex.printStackTrace();
}
}

public static void main(String args[])
{
ApplicationContext con=new AnnotationConfigApplicationContext(AppConfig.class );
ExceptionTest t =(ExceptionTest)con.getBean(ExceptionTest.class);
t.method1();
}

}


When i run the Exception java class, it is throwing the arithmatic exception and come out of the execution.It is not invoking the afterThrowing(Throwable ex) method of AopException class.

So could you please let me know what is wrong in my code.

nicolas.loriente
Jun 20th, 2011, 01:56 PM
"method1()" is not throwing an exception... you are catching it!


nicolas.loriente

jenad
Jun 22nd, 2011, 03:53 AM
Hi Nicolas,

@afterThrowing annotation is working fine in one project and the same is not working in another project.

Please find the below code for which it is not working.

<Code>
package com.org.acsserver.cs.bo;
public class CustomerService {
public RequestResponse createIncident(
CreateIncidentRequest createIncidentRequest) throws BaseException {

createdIncidentVO = customerServiceBO.createCSTicket(createIncidentReq uest);
}
catch (BaseException be) {

requestResponse = exceptionResponseCreator
.createExceptionResponse(be);
}

return requestResponse;
}
<Code>



<Code>
package com.org.acsserver.cs.bo
public interface CustomerServiceBO {
public CreatedIncidentVO createCSTicket(
CreateIncidentRequest createIncidentRequest) throws BaseException;
}
<Code>





<Code>
package com.org.acsserver.cs.bo.impl

public class CustomerServiceBOImpl implements CustomerServiceBO{
public CreatedIncidentVO createCSTicket(
CreateIncidentRequest createIncidentRequest) throws CustomerServiceException{
return invokeIncidentCreateWS(reqObject);
}


public CreatedIncidentVO invokeIncidentCreateWS(HelpDesk_Submit_Service reqObject) throws CustomerServiceException
{
try
{
//Throwing exception in try block
}
catch(Exception e){
throw new CustomerServiceException(ErrorConstants.WEB_SERVIC E_INVOCATION_FAILED, e);
}
createdIncidentVO.setTicketNumber(ticketNumber);
return createdIncidentVO;
}
}
<Code>


<Code>
package com.org.acsserver.common.aop
@Aspect
public class AopExceptionMailerAdvice {


@AfterThrowing(
pointcut="execution(* com.org.acsserver.cs.bo.CustomerServiceBO.*(..))", throwing="ex")
public void afterThrowing(Exception ex)
{
//Code for sending mail to specific group.
}
}

<Code>

By seeing this code if you will say, i am catching the exception that why it is not working then please download the project i have uploaded in JIRA and run the ExceptionTest.java ans see after catching also it is working. And i am using Java Config instead of xml config

https://jira.springsource.org/browse/SPR-8478
So could you please let me know what is the wrong in my code.
.
Your help is highly appriciated.

Thanks
Jenad

nicolas.loriente
Jun 22nd, 2011, 10:29 AM
OK, I finally was able to find out what you were talking about.

Please use
tags next time so it makes it easier to read the posted code.

The original post was catching the exception and that was why it wouldn't get adviced. Now the project you uploaded to JIRA has a different issue and the problem is here:
[CODE]
public int method1(int z) throws CustomerServiceException
{
return method2(z);
}

public int method2(int z) throws CustomerServiceException
{
try {
int x=10;
int y=x/0;
} catch (Exception e) {
throw new CustomerServiceException(ErrorConstants.AMP_WEB_SE RVICE_INVOCATION_FAILED, e);
}

return z;

}

The issue is simple..... method2() is being call from within method1(). Spring AOP is Proxy Based and that has some implications. Because your method call is internal on "this" reference method2() call is not going through the proxy and in turn is not getting advised.

This is stated very clear in the documentation ( 7.6.1 Understanding AOP proxies http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html)

See AOP proxy call diagram: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/images/aop-proxy-call.png


...method calls on that object reference will be calls on the proxy, and as such the proxy will be able to delegate to all of the interceptors (advice) that are relevant to that particular method call. However, once the call has finally reached the target object, the SimplePojo reference in this case, any method calls that it may make on itself, such as this.bar() or this.foo(), are going to be invoked against the this reference, and not the proxy. This has important implications. It means that self-invocation is not going to result in the advice associated with a method invocation getting a chance to execute.

What does this mean? It means that calls from "this", protected/private methods, and constructors will not be advised. If you need to advice such methods you'll need use a full blown AOP implementation such as AspectJ.

I hope it helps!


nicolas.loriente

jenad
Jun 24th, 2011, 12:53 AM
Hi Nicolas,

Thanks it is working fine now.
Thanks for your help.

Thanks
Daitari Jena