Catch exceptions with AOP
Hi,
I try to use AOP aspects to catch exceptions in OSGi bundles.
The class AopTestThread calls an instance of IContactService to retrieve registered contacts. If the contact is not registered an exception occured.
The exception should be catched by a ContactAdvice which is in an another OSGi bundle but ...
I'm using eclipse Galileo + spring dm 1.2.1 + spring 2.5.6A
When running the com.perdigal.client.aop.osgi.test osgi bundle, i have got the following error :
Code:
INFO: Application context successfully refreshed (OsgiBundleXmlApplicationContext(bundle=com.perdigal.client.aop.osgi.test, config=osgibundle:/META-INF/spring/*.xml))
--- Get IContactService from OSGi Spring context ---
--- From function isRegistered : Contact Foo, Joe is registered
23 janv. 2011 00:34:19 org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor afterPropertiesSet
INFO: Looking for mandatory OSGi service dependency for bean [ContactAdvice] matching filter (objectClass=com.perdigal.server.aop.IContactAdvice)
23 janv. 2011 00:34:19 org.springframework.osgi.service.importer.support.internal.aop.ServiceDynamicInterceptor afterPropertiesSet
INFO: Found mandatory OSGi service for bean [ContactAdvice]
org.springframework.aop.AopInvocationException: Mismatch on arguments to advice method [public final void $Proxy2.methodForCatchingException(java.lang.Exception)]; pointcut expression [org.aspectj.weaver.internal.tools.PointcutExpressionImpl@c38157]; nested exception is java.lang.IllegalArgumentException: object is not an instance of declaring class
Thanks for any help or advices
Hervé
Bundle com.perdigal.client.aop.osgi.test
----------------------------------------
Code:
public class AopTestThread extends Thread {
private static final long TIMER = 5000;
private IContactService contactService;
public void setContactService(IContactService p_contactService) {
this.contactService = p_contactService;
}
@Override
public void run() {
while (!super.isInterrupted()) {
try {
// 1. Get contactService
IContactService contactService = getContactService();
if (contactService != null) {
// 2. Check contacts by using IContactService
contactService.isRegistered("Foo", "Joe");
contactService.isRegistered("Bar", "Mike");
} else {
System.out.println("--- From AopTestThread : Instance contactService is null");
}
} catch (Throwable e) {
e.printStackTrace();
// System.out.println("--- From AopTestThread : " + e.getLocalizedMessage());
} finally {
try {
if (!super.isInterrupted())
sleep(TIMER);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
}
private IContactService getContactService() {
System.out.println("--- Get IContactService from OSGi Spring context ---");
if (contactService != null) {
return contactService;
}
System.out.println("--- Cannot get contactService => contactService is null!");
return null;
}
@Override
public synchronized void start() {
System.out.println("--- Start Thread AopTestThread");
super.start();
}
@Override
public void interrupt() {
System.out.println("--- Interrupt Thread AopTestThread");
super.interrupt();
}
}
module-osgi-context.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="AopTestThread" class="com.perdigal.client.aop.osgi.test.AopTestThread" init-method="start" destroy-method="interrupt">
<property name="contactService" ref="ContactService"></property>
</bean>
</beans>
module-osgi-context.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<osgi:reference id="ContactService" interface="com.perdigal.server.services.IContactService" timeout="1000" />
</beans
Bundle com.perdigal.server.services.impl
----------------------------------------
Code:
public class ContactServiceImpl implements IContactService {
public void isRegistered(String p_lname, String p_fname) throws Exception {
if (p_fname.equalsIgnoreCase("Mike")) {
throw new Exception("--- From function isRegistered : Error - Duplicate key for " + p_fname);
} else {
System.out.println("--- From function isRegistered : Contact " + p_lname + ", " + p_fname + " is registered");
}
}
}
module-context.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<bean id="ContactService" class="com.perdigal.server.services.impl.ContactServiceImpl" />
<aop:config>
<aop:pointcut id="ContactServicePointCut" expression="execution(* com.perdigal.server.services.IContactService.isRegistered(..))" />
<aop:aspect id="ContactAspect" ref="ContactAdvice">
<aop:after-throwing pointcut-ref="ContactServicePointCut" method="methodForCatchingException" throwing="ex" />
</aop:aspect>
</aop:config>
</beans>
module-osgi-context.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<osgi:service ref="ContactService" interface="com.perdigal.server.services.IContactService" />
<osgi:reference id="ContactAdvice" interface="com.perdigal.server.aop.IContactAdvice" />
</beans>
Bundle com.perdigal.server.aop.impl
----------------------------------------
Code:
public class ContactAdviceImpl implements IContactAdvice {
public void methodForCatchingException(Exception ex) {
System.out.println("--- From methodForCatchingException : " + ex.getLocalizedMessage());
}
}
module-context.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<bean id="ContactAdvice" class="com.perdigal.server.aop.impl.ContactAdviceImpl" />
</beans>
module-osgi-context.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<osgi:service ref="ContactAdvice" interface="com.perdigal.server.aop.IContactAdvice" />
</beans>