Announcement Announcement Module
Collapse
No announcement yet.
Aspect is not being called while testing with JUnit. Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Aspect is not being called while testing with JUnit.

    Hi

    I am trying to Lazy Load an object using Aspect. My scenario is, a domain object Customer has another domain object Phone. For each domain object I have corresponding Dao Impl. In my Customer.java, there is a method to get Phone object,
    Code:
    getPhone()
    . I want to have lazy loading of Phone object and for this purpose I am trying to write an aspect.

    To test it I have written a Junit class which uses
    Code:
    SpringJUnit4ClassRunner.class
    . Since the Customer instance is created by CustomerDaoImpl.java using "new", I am trying to do load time weaving using spring. I have set VM arguments for javagent -
    Code:
    -javaagent:C:/Projects/lib/org.springframework.instrument-3.0.5.jar
    I am making some mistake in the configuration as my aspect is not being called and am getting exception messages. Kindly let me know if there is mistake in my understanding or in the configuration. Files are shown below:


    application-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:context="http://www.springframework.org/schema/context"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:util="http://www.springframework.org/schema/util"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
    		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
    	<description>Configuration File.</description>
    
    	<context:component-scan base-package="com.docsample"/>
    	<context:annotation-config />
    	<context:load-time-weaver />
    	
    
    </beans>
    Aspect Code

    Code:
    package com.docsample.aspect;
    
    import java.util.Arrays;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class PhoneObjectLazyLoadingAspect {
    	@Around ("execution(* com.docsample.domain.ICustomer.getPhone(..))")
    	public void getPhoneSysobj(JoinPoint joinPoint){
    		System.out.println("------  In PhoneObjectLazyLoadingAspect --------");
    		System.out.println("The method " + joinPoint.getSignature().getName()
    				+ "() begins with " + Arrays.toString(joinPoint.getArgs()));
    		//TODO:Implement Lazy Loading code
    
    	}
    
    }
    aop.xml

    Code:
    <!DOCTYPE aspectj PUBLIC
            "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
    <aspectj>
    
        <weaver>
    
            <!-- only weave classes in our application-specific packages -->
            <include within="com.docsample.domain.*"/>
    
        </weaver>
    
        <aspects>
    
            <!-- weave in just this aspect -->        
            <aspect name="com.docsample.aspect.PhoneObjectLazyLoadingAspect"/>
    
        </aspects>
    
      </aspectj>
    CustomerDaoTests.java

    Code:
    package com.docsample;
    
    import static org.junit.Assert.assertNotNull;
    import static org.junit.Assert.assertTrue;
    import static org.junit.Assert.*;
    
    import javax.inject.Inject;
    
    import org.junit.After;
    import org.junit.AfterClass;
    import org.junit.Before;
    import org.junit.BeforeClass;
    import org.junit.Rule;
    import org.junit.Test;
    import org.junit.rules.ExpectedException;
    import org.junit.runner.RunWith;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import com.docsample.dao.CustomerDao;
    import com.docsample.domain.Customer;
    import com.docsample.domain.ICustomer;
    import com.docsample.domain.IPhone;
    import com.docsample.domain.Phone;
    
    @ContextConfiguration
    @RunWith(SpringJUnit4ClassRunner.class)
    public class CustomerDaoTests {
    	
    	@Inject
    	CustomerDao custDao;
    
    	@Rule
    	public ExpectedException exception = ExpectedException.none();
    	
    	
    	@Test
    	public void testFindCustomer() throws Exception {
    		ICustomer customer = custDao.findCustomer("091a2071800103f6");
    		assertNotNull(customer);
    		assertEquals("Scott", customer.getFname());
    		assertEquals("091a2071800103f6",customer.getId());
    		IPhone custPhone = customer.getPhone();
    		assertEquals("0091-22-2222222", custPhone.getPhonenumber());
    	}
    }
    Exceptions:

    Code:
    [AppClassLoader@130c19b] error can't determine annotations of missing type org.springframework.transaction.annotation.Transactional
    when weaving type com.docsample.domain.IPhone
    when weaving classes 
    when weaving 
     [Xlint:cantFindType]
    [AppClassLoader@130c19b] error can't determine annotations of missing type org.springframework.transaction.annotation.Transactional
    when weaving type com.docsample.domain.IPhone
    when weaving classes 
    when weaving 
     [Xlint:cantFindType]
    [AppClassLoader@130c19b] error can't determine annotations of missing type org.springframework.transaction.annotation.Transactional
    when weaving type com.docsample.domain.IPhone
    when weaving classes 
    when weaving 
     [Xlint:cantFindType]
    [AppClassLoader@130c19b] error can't determine annotations of missing type org.springframework.transaction.annotation.Transactional
    when weaving type com.docsample.domain.IPhone
    when weaving classes 
    when weaving 
     [Xlint:cantFindType]
    [AppClassLoader@130c19b] error at com\docsample\aspect\PhoneObjectLazyLoadingAspect.java::0 applying to join point that doesnt return void: {0}
    [AppClassLoader@130c19b] error at com\docsample\domain\Customer.java:39::0 applying to join point that doesnt return void: {0}
    Last edited by JayGaba; Jan 18th, 2011, 05:24 PM.

  • #2
    Hi

    while using the @Around advice , your method getPhoneSysobj() should return an Object and not void , since the adviced method return and Int ...

    try something like this in your aspect :


    public Object getPhoneSysobj(ProceedingJoinPoint joinPoint){
    System.out.println("------ In PhoneObjectLazyLoadingAspect --------");
    System.out.println("The method " + joinPoint.getSignature().getName()
    + "() begins with " + Arrays.toString(joinPoint.getArgs()));
    //TODO:Implement Lazy Loading code

    return joinPoint.proceed();

    }


    ==> Notice the use of ProceedingJoinPoint ,which extends the basic JoinPoint class,and provide a proceed method that actually runs the advice method .

    Hope this helps

    Regards
    Anis

    Comment


    • #3
      java.lang.NoSuchMethodError:com.docsample.aspect.P honeObjectLazyLoadingAspect.aspect

      Thank you Anis, that was one of the problem. After fixing that I ran into another problem:

      Code:
      java.lang.NoSuchMethodError: com.docsample.aspect.PhoneObjectLazyLoadingAspect.aspectOf()Lcom/docsample/aspect/PhoneObjectLazyLoadingAspect;
      	at com.docsample.domain.Customer.getPhone(Customer.java:39)
      	at com.docsample.domain.Customer.getPhone(Customer.java:1)
      	at com.docsample.CustomerDaoTests.testFindCustomer(CustomerDaoTests.java:125)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
      	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
      	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
      	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
      	at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:110)
      	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
      	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
      	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
      	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
      	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
      	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
      	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
      	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
      	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
      	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
      	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
      	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
      	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
      	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
      	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
      	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
      	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
      	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
      	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
      	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
      	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
      	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
      	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
      	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
      I tried googling it and found the solution to it. I had to modify the aop.xml file to include weaving for aspect's. Updated aop.xml file is as below:

      Code:
      <!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
      <aspectj>
          <weaver options="-XnoInline -Xset:weaveJavaPackages=true,weaveJavaxPackages=true"> <!-- -verbose -showWeaveInfo -Xlint:ignore  -->
              <!-- only weave classes in our application-specific packages -->
              <include within="com.docsample.domain.*"/>
              <include within="com.docsample.aspect.*"/>
          </weaver>
      
          <aspects>
              <!-- weave in just this aspect -->        
              <aspect name="com.docsample.aspect.PhoneObjectLazyLoadingAspect"/>
          </aspects>
      
      </aspectj>
      Any idea why I should include the aspect in the weaving? I have a sample which works with older version of Spring 2.5.4 and Spring Agent 2.5.4. It does not require weaving of Aspects.

      Thank you once again.

      Regards
      Jay Gaba

      Comment


      • #4
        Ok, what I believe is , that Spring on LTW(Blieve also in CTW) , create a Bean that refs to the aspect , and sets as a Factory Method , the aspectOf() method, this is why he complained that the method was not existing , not sure about the old releases, but indeed in the Spring 3.x , it does do so .

        you could proove that by removing the added code on the aop.xml , and simply create a bean on the Spring context , and sets the factory Method to aspectOf() , this also should work. It's deeply related to the Dependency Injenction mechanism.

        Comment


        • #5
          Hi, to fix the error "error can't determine annotations of missing type org.springframework.transaction.annotation.Transac tional" you should add the following dependency:

          <groupId>org.springframework</groupId>
          <artifactId>spring-tx</artifactId>

          Comment

          Working...
          X