Announcement Announcement Module
Collapse
No announcement yet.
Problem whe implementing interface Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem whe implementing interface

    Hello,

    I have a class MyClass implementing an interface MyInterface and I would like to execute some code injected by AOP each time a method of MyClass is invoked. My AOP class implementation is AOPImpl.
    To test all of this, I coded a junit test.

    The issue is that the test fails with the following exception

    SEVERE: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.Dependenc yInjectionTestExecutionListener@2a462a46] to prepare test instance [com.aop.test.TestAOP@60b460b4]
    Throwable occurred: org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'com.aop.test.TestAOP': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationExce ption: Could not autowire field: private com.aop.test.MyClass com.aop.test.TestAOP.dao; nested exception is org.springframework.beans.factory.NoSuchBeanDefini tionException: No matching bean of type [com.aop.test.MyClass] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Aut owired(required=true)}
    at org.springframework.beans.factory.annotation.Autow iredAnnotationBeanPostProcessor.postProcessPropert yValues(AutowiredAnnotationBeanPostProcessor.java: 287)
    at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.populateBean(AbstractAu towireCapableBeanFactory.java:1106)
    at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.autowireBeanProperties( AbstractAutowireCapableBeanFactory.java:374)
    at org.springframework.test.context.support.Dependenc yInjectionTestExecutionListener.injectDependencies (DependencyInjectionTestExecutionListener.java:110 )
    at org.springframework.test.context.support.Dependenc yInjectionTestExecutionListener.prepareTestInstanc e(DependencyInjectionTestExecutionListener.java:75 )
    at org.springframework.test.context.TestContextManage r.prepareTestInstance(TestContextManager.java:321)
    at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.createTest(SpringJUnit4ClassRunner.j ava:211)
    at org.springframework.test.context.junit4.SpringJUni t4ClassRunner$1.runReflectiveCall(SpringJUnit4Clas sRunner.java:288)
    at org.junit.internal.runners.model.ReflectiveCallabl e.run(ReflectiveCallable.java:15)
    at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.methodBlock(SpringJUnit4ClassRunner. java:290)
    at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.runChild(SpringJUnit4ClassRunner.jav a:231)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild( BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner. java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRu nner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentR unner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRu nner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRu nner.java:222)
    at org.springframework.test.context.junit4.statements .RunBeforeTestClassCallbacks.evaluate(RunBeforeTes tClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements .RunAfterTestClassCallbacks.evaluate(RunAfterTestC lassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.ja va:300)
    at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.run(SpringJUnit4ClassRunner.java:174 )
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestR eference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecutio n.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.main(RemoteTestRunner.java:197)
    Caused by: org.springframework.beans.factory.BeanCreationExce ption: Could not autowire field: private com.aop.test.MyClass com.aop.test.TestAOP.dao; nested exception is org.springframework.beans.factory.NoSuchBeanDefini tionException: No matching bean of type [com.aop.test.MyClass] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Aut owired(required=true)}
    at org.springframework.beans.factory.annotation.Autow iredAnnotationBeanPostProcessor$AutowiredFieldElem ent.inject(AutowiredAnnotationBeanPostProcessor.ja va:506)
    at org.springframework.beans.factory.annotation.Injec tionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.Autow iredAnnotationBeanPostProcessor.postProcessPropert yValues(AutowiredAnnotationBeanPostProcessor.java: 284)
    ... 26 more
    Caused by: org.springframework.beans.factory.NoSuchBeanDefini tionException: No matching bean of type [com.aop.test.MyClass] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Aut owired(required=true)}
    at org.springframework.beans.factory.support.DefaultL istableBeanFactory.raiseNoSuchBeanDefinitionExcept ion(DefaultListableBeanFactory.java:924)
    at org.springframework.beans.factory.support.DefaultL istableBeanFactory.doResolveDependency(DefaultList ableBeanFactory.java:793)
    at org.springframework.beans.factory.support.DefaultL istableBeanFactory.resolveDependency(DefaultListab leBeanFactory.java:707)
    at org.springframework.beans.factory.annotation.Autow iredAnnotationBeanPostProcessor$AutowiredFieldElem ent.inject(AutowiredAnnotationBeanPostProcessor.ja va:478)
    ... 28 more


    If I remove the inheritance from MyClass, all works fine. Anyone can explain please where am I wrong?
    Thanks for any suggestion.

    MyInterface
    public interface MyInterface {
    public void waitAMoment(long ms) throws InterruptedException;
    }

    MyClass
    public class MyClass implements MyInterface {

    public void waitAMoment(long ms) throws InterruptedException {
    Thread.sleep(ms);
    System.out.println("Waited " + ms + " ms");
    }
    }

    Test class

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "classpath:applicationContext.xml" })
    public class TestAOP {
    @Autowired
    private MyClass dao;

    @Test
    public void test() throws InterruptedException {
    dao.waitAMoment(10);
    }
    }

    Spring config applicationContext.xml
    <?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:context="http://www.springframework.org/schema/context"
    xmlns:ws="http://jax-ws.dev.java.net/spring/core" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schem...ring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schem...ng-context.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

    <bean name="testDAO" class="com.aop.test.MyClass"/>

    <bean id="logAspect" class="com.aop.test.AOPImpl" />

    <aop:config>
    <aop:aspect id="aspectLoggging" ref="logAspect">
    <!-- @Around -->
    <aopointcut id="pointCutAround" expression="execution(* com.aop..*MyInterface+.*(..))" />
    <aop:around method="logInvocationAndParameters"
    pointcut-ref="pointCutAround" />
    </aop:aspect>
    </aop:config>
    </beans>

  • #2
    In your test class, you should use MyInterface instead of MyClass to do @Autowired.

    @Autowired
    private MyInterface dao;

    In Spring, you should always use the interface to create instance variable and do dependency injection (using autowired or xml) and not the implementation class as Spring AOP creates dynamic proxy object while applying advice.

    Comment


    • #3
      Thank you very much Manjunatha, this fixes the issue.

      I knew that it was a best practice, but ignored that the use of interfaces was mandatory in some cases.
      I introduced AOP afterwards, so now I have to update all the JUnit that people implemented and that uses implementations instead of interfaces.

      Comment

      Working...
      X