Announcement Announcement Module
Collapse
No announcement yet.
Problem with AspectJ and interfaces Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem with AspectJ and interfaces

    I already posted about this issue but I have been able to narrow cases where it happens.
    I get the following error:
    Code:
    "org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy0] to required type [TargetImpl] for property 'targetImpl'; nested exception is java.lang.IllegalArgumentException: No matching editors or conversion strategy found"
    It happens on a bean whose methods are woven with aspectJ aspects and only when the bean implements an interface.

    Here the code to reproduce it:
    Target Interface
    Code:
    public interface Target {
    	public void perform();
    }
    Target Implementation
    Code:
    public class TargetImpl implements Target {
    	public void perform() {
    	    System.out.println("Target invoked");			
    	}
    }
    A bean that will be injected a target (the implementation directly):
    Code:
    public class Init {
    	private TargetImpl targetimpl;	
    	public void setTargetImpl(TargetImpl target) {
    		this.targetimpl = target;
    	}	
    	public void start() {
    		targetimpl.perform();
    	}
    }
    My aspect:
    Code:
    public class SayHelloAdvice {
    	public void world() {
    		System.out.println("aspect invoked");
    	}
    }
    The applicationContext.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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 						http://www.springframework.org/schema/beans/spring-beans.xsd
    					    http://www.springframework.org/schema/aop 
    						http://www.springframework.org/schema/aop/spring-aop.xsd">
    		
    	<aop:config>
    		  <aop:aspect id="sayhelloadvice" ref="sayhelloaspect">
    		  	<aop:advice 
    				kind="before"
    				method="world"
    				pointcut="execution(* TargetImpl.perform(..))"/>
    		  </aop:aspect>
    	</aop:config>					
    	<bean id = "target" class="TargetImpl"/>	
    	<bean id="sayhelloaspect" class="SayHelloAdvice"/>		
    	<bean id="init" class="Init">
    	   <property name="targetImpl"><ref bean="target"/></property>
    	</bean>
    						
    </beans>
    And the test case:
    Code:
    public class AOPTest extends TestCase {	
    	public ApplicationContext context;
    	@Override
    	protected void setUp() throws Exception {
    		super.setUp();
    		this.context = new ClassPathXmlApplicationContext("/applicationContext.xml");
    	}
    	public void testHelloAdvice() {
    		Init init = (Init)context.getBean("init");
    		init.start();
    	}
    	
    	
    }
    Everything works fine when TargetImpl class does not implement the Target interface. If it implements the Target interface I get the error above.
    In my application the code is more complex and TargetImpl implements different interfaces that's why in the Init class a concrete class is injected and "not an interface".

  • #2
    Solved

    Juergen answered on Jira (thanks Juergen):

    " The problem here is that your target class implements an interface, but you still want your callers to talk to your target class directly. This conflicts with Spring AOP's default behavior: expose an interface-based proxy if interfaces are implemented, fall back to a full target class proxy (based on CGLIB) else.

    So you should either consider letting your callers talk to the target object through an interface (which we recommend), or specify the "proxyTargetClass" attribute at the <aop:config> level as "true". In the latter case, you will then always get CGLIB proxies, even if your target classes implement interfaces.

    Juergen"

    Comment

    Working...
    X