Announcement Announcement Module
Collapse
No announcement yet.
Spring AOP caching with AspectJ Weaving is not happening Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring AOP caching with AspectJ Weaving is not happening

    Hi all,

    My requirement is to cache internal private method of a class. Whenever this method gets invoked by a public method, which is invoked externally, that private method return object is to be cached.

    Since, as you all know, pure spring aop doesn't support this caching at this kind of self method invocation calls, I went for AspectJ Load Time Weaving(LTW) as it is full-brown framework.

    I believe i did all kind of configuration. But Aspect is not getting invoked. i'm providing all necessary code below. Please look into this, let me know where can i put my efforts still.

    aop.xml:

    <aspectj>
    <aspects>
    <!-- weave in just this aspect -->
    <aspect name="com.test.AspectJCachingHandler" />
    <aspect name="com.test.MethodCacheInterceptor" />
    </aspects>
    <weaver>
    <!-- only weave classes in our application-specific packages -->
    <include within="com.test.TestCache.*" />
    </weaver>
    </aspectj>

    spring-application.xml

    <context:load-time-weaver aspectj-weaving="on" />

    <bean id="myBean" class="com.test.TestCache" />

    Aspect:

    @Aspect
    public class AspectJCachingHandler{

    @Around("execution(private * com.test.TestCache.getMethod(String,int))")
    public void cacheGetMethod(ProceedingJoinPoint pjp) throws Throwable {

    MethodCacheInterceptor interceptor = new MethodCacheInterceptor();
    interceptor.intercept(pjp,"TestCache","getMethod") ;

    }
    }

    TestCache class:

    public class TestCache implements TestInterface{
    Person p = null;

    public TestCache(){
    p = new Person();
    p.name="CIT";
    p.age=20;
    }
    public String getMethod(int age){
    System.out.println("*** Called----public getMethod(**) ***");
    p = this.getMethod("MT",8);
    return new String(p.name+" "+p.age);
    }
    private Person getMethod(String name,int age){
    System.out.println("*** Called----private method (**) *** ");
    p.name = name;
    p.age = age;
    return p;
    }
    }


    Main Method to test:

    public static void main(String[] args) {

    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-application.xml");
    TestInterface testCache=new TestCache();
    testCache = (TestInterface)ctx.getBean("myBean");
    testCache.getMethod("ABCD",22);
    System.out.println("** Called ---> 1st Time **");
    testCache.getMethod("ABCD",22);
    System.out.println("** Called ---> 2nd Time **");
    }

    Result :

    [java] Apr 23, 2008 8:10:05 PM org.springframework.context.support.AbstractApplic ationContext prepareRefresh
    [java] INFO: Refreshing org.springframework.context.support.ClassPathXmlAp plicationContext@21ef53: display name [org.springframework.context.support.ClassPathXmlAp plicationContext@21ef53]; startup date [Wed Apr 23 20:10:04 GMT+05:30 2008]; root of context hierarchy
    [java] Apr 23, 2008 8:10:05 PM org.springframework.beans.factory.xml.XmlBeanDefin itionReader loadBeanDefinitions
    [java] INFO: Loading XML bean definitions from class path resource [spring-application.xml]
    [java] Apr 23, 2008 8:10:06 PM org.springframework.context.support.AbstractApplic ationContext obtainFreshBeanFactory
    [java] INFO: Bean factory for application context [org.springframework.context.support.ClassPathXmlAp plicationContext@21ef53]: org.springframework.beans.factory.support.DefaultL istableBeanFactory@48ef58
    [java] Apr 23, 2008 8:10:06 PM org.springframework.context.weaving.DefaultContext LoadTimeWeaver setBeanClassLoader
    [java] INFO: Found Spring's JVM agent for instrumentation
    [java] Apr 23, 2008 8:10:07 PM org.springframework.beans.factory.support.DefaultL istableBeanFactory preInstantiateSingletons
    [java] INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultL istableBeanFactory@48ef58: defining beans [org.springframework.context.weaving.AspectJWeaving Enabler#0,org.springframework.context.config.inter nalBeanConfigurerAspect,loadTimeWeaver,org.springf ramework.aop.aspectj.annotation.AnnotationAwareAsp ectJAutoProxyCreator#0,aspectJCachingHandler,myBea n]; root of factory hierarchy
    [java] *** Called----public getMethod(**) ***
    [java] *** Called----private method (**) ***
    [java] ** Called ---> 1st Time **
    [java] *** Called----public getMethod(**) ***
    [java] *** Called----private method (**) ***
    [java] ** Called ---> 2nd Time **


    This shows no methodcacheinterceptor is invoked by Caching Aspect.

    Could anybody throw light on this? Thanks in advance

    Regards,
    Ganesh

  • #2
    Well your Aspect is wrong already. You are defining a around advice that MUST return an Object. Also you no where return something or retrieve something from

    Also your wiring looks strange... You are instantiating a MethodInterceptor inside your other aspect?! Then why define it as an aspect?

    Comment


    • #3
      Thanks Marten for your kind response.

      I changed aspect as you said, I put @Before advice

      Aspect:

      @Aspect
      public class AspectJCachingHandler{

      @Before("execution(private * com.test.TestCache.getMethod(String,int))")
      public void cacheGetMethod(ProceedingJoinPoint pjp) throws Throwable {

      System.out.println("*** Aspect called ***");

      //Caching Logic will be implemented here

      }
      }

      META-INF/AOP.xml

      <aspectj>
      <aspects>
      <!-- weave in just this aspect -->
      <aspect name="com.test.AspectJCachingHandler" />
      </aspects>
      <weaver>
      <!-- only weave classes in our application-specific packages -->
      <include within="com.test.TestCache.*" />
      </weaver>
      </aspectj>


      Main Method to test:

      public static void main(String[] args) {

      ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-application.xml");
      TestInterface testCache=new TestCache();
      testCache = (TestInterface)ctx.getBean("myBean");
      testCache.getMethod(22);
      System.out.println("** Called ---> 1st Time **");
      testCache.getMethod(22);
      System.out.println("** Called ---> 2nd Time **");
      }


      But i'm getting the same result as i showed before.
      Aspect itself is not getting called at all. If it happens, i can implement logic for caching.

      Will you please figure out an expected solution.

      Thanks,
      Ganesh

      Comment


      • #4
        When posting code please use the [ code][/code ] tags.

        Can you zip your project (code only, no jars) so that I can test it in eclipse.

        Comment


        • #5
          I just uploaded, Marten.

          Here is my complete spring-application.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"
          	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
          		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
          
          
          	<context:load-time-weaver aspectj-weaving="on" />
          	<!-- Enabling @AspectJ Support -->
          
          <bean id="myBean" class="com.cit.ecommerce.test.TestCache" />
          
          </beans>
          Thank you very much for your attention.
          I hope it'll get solved soon.

          Regards,
          Ganesh

          Comment


          • #6
            How are you running your tests?

            Comment


            • #7
              Here is my build file:

              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <project name="AOPProject" basedir=".">	
              	<property name="src" location="src" />
              	<property name="build" location="${basedir}/build" />
              	<target name="run" depends="makeJar" description="run">
              		<java classname="com.cit.ecommerce.test.Test" fork="yes">
              			<sysproperty key="DEBUG" value="true" />
              			<classpath>
              				<pathelement location="lib/spring.jar" />
              				<pathelement location="lib/commons-logging-1.0.4.jar" />
              				<pathelement location="lib/spring-aspects.jar" />
              				<pathelement location="lib/aspectjrt.jar" />
              				<pathelement location="lib/aspectjweaver.jar" />
              				<pathelement location="lib/aop.jar" />
              				<pathelement path="${java.class.path}" />
              			</classpath>
              			<jvmarg value="-javaagent:lib/spring-agent.jar" />
              		</java>
              	</target>
              	<target name="makeJar">
              		<echo message="Making Jar....." />
              		<jar compress="no" jarfile="${basedir}/lib/aop.jar">
              			<zipfileset dir="${build}/classes/">
              				<include name="**/*.*" />
              			</zipfileset>
              		</jar>
              	</target>
              </project>
              Thanks,
              Ganesh

              Comment


              • #8
                You have 2 problems (at least in the code you send me).

                1) Your aspect is wrong a Before advice cannot have a ProceedingJoinPoint only a JoinPoint
                2) When you construct your jar file you don't include the aop.xml, hence nothing is getting weaved.

                if you fix that the output is

                Code:
                     [java] Apr 24, 2008 12:39:08 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
                     [java] INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@64dc11: display name [org.springframework.context.support.ClassPathXmlApplicationContext@64dc11]; startup date [Thu Apr 24 12:39:08 CEST 2008]; root of context hierarchy
                     [java] Apr 24, 2008 12:39:08 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
                     [java] INFO: Loading XML bean definitions from class path resource [spring-application.xml]
                     [java] Apr 24, 2008 12:39:08 PM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
                     [java] INFO: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@64dc11]: org.springframework.beans.factory.support.DefaultListableBeanFactory@76fba0
                     [java] Apr 24, 2008 12:39:08 PM org.springframework.context.weaving.DefaultContextLoadTimeWeaver setBeanClassLoader
                     [java] INFO: Found Spring's JVM agent for instrumentation
                     [java] [AppClassLoader@92e78c] info AspectJ Weaver Version 1.5.4 built on Thursday Dec 20, 2007 at 13:44:10 GMT
                     [java] [AppClassLoader@92e78c] info register classloader sun.misc.Launcher$AppClassLoader@92e78c
                     [java] [AppClassLoader@92e78c] info using configuration file:/C:/Users/mdeinum/Downloads/tmp/SpringAspectJ/lib/spring-aspects.jar!/META-INF/aop.xml
                     [java] [AppClassLoader@92e78c] info using configuration file:/C:/Users/mdeinum/Downloads/tmp/SpringAspectJ/dist/aop.jar!/META-INF/aop.xml
                     [java] [AppClassLoader@92e78c] info register aspect org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect
                     [java] [AppClassLoader@92e78c] info register aspect org.springframework.transaction.aspectj.AnnotationTransactionAspect
                     [java] [AppClassLoader@92e78c] info register aspect com.cit.ecommerce.test.AspectJCachingHandler
                     [java] Apr 24, 2008 12:39:09 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
                     [java] INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@76fba0: defining beans [org.springframework.context.weaving.AspectJWeavingEnabler#0,org.springframework.context.config.internalBeanConfigurerAspect,loadTimeWeaver,myBean]; root of factory hierarchy
                     [java] *** AspectJCachingHandler Aspect --> called  ***
                     [java] *** Called----public getContracts(**) ***
                     [java] *** Called----private method (**) *** 
                     [java] ** Called ---> 1st Time **
                     [java] *** AspectJCachingHandler Aspect --> called  ***
                     [java] *** Called----public getContracts(**) ***
                     [java] *** Called----private method (**) *** 
                     [java] ** Called ---> 2nd Time **
                BUILD SUCCESSFUL
                Total time: 1 second
                Also I still wonder HOW you want to do caching with a Before advice, you cannot return anything from it so you really need a Around advice.
                Last edited by Marten Deinum; Apr 24th, 2008, 05:41 AM.

                Comment


                • #9
                  Thank you Marten.

                  I checked my jar file. It has aop.xml file. And i changed @Before advice without ProceedingJoinPoint arg and build file.
                  Even then, aspect is not getting called for me.
                  i'm executing it on WebLogic Workshop 10.0 using ant build file.
                  i'm very happy when i saw could be able to run it there.

                  Here is my build file and aop.jar(aop.zip) file

                  Code:
                  <?xml version="1.0" encoding="UTF-8"?>
                  <project name="AOPProject" basedir=".">	
                  	<property name="src" location="src" />
                  	<property name="build" location="${basedir}/build" />
                  	<target name="run" depends="makeJar" description="run">
                  		<java classname="com.cit.ecommerce.test.Test" fork="yes">
                  			<sysproperty key="DEBUG" value="true" />
                  			<classpath>
                  				<pathelement location="lib/spring.jar" />
                  				<pathelement location="lib/commons-logging-1.0.4.jar" />
                  				<pathelement location="lib/spring-aspects.jar" />
                  				<pathelement location="lib/aspectjrt.jar" />
                  				<pathelement location="lib/aspectjweaver.jar" />
                  				<pathelement location="lib/aop.jar" />
                  				<pathelement path="${java.class.path}" />
                  			</classpath>
                  			<jvmarg value="-javaagent:lib/spring-agent.jar" />
                  		</java>
                  	</target>
                  	<target name="makeJar" depends="compile">
                  		<echo message="Making Jar....." />
                  		<jar compress="no" jarfile="${basedir}/lib/aop.jar">
                  			<zipfileset dir="${build}/aop">
                  				<include name="**/*.*" />
                  			</zipfileset>
                  			<fileset dir="${src}" id="id">
                  		    	<include name="**/*.*"/>					
                  			</fileset>			
                  		</jar>
                  	</target>	
                  	<target name="compile" description="compile the source " depends="init">
                  		<echo message="Compiling......." />		
                  	    <!-- Compile the java code from ${src} into ${build} -->
                  	    <javac srcdir="${src}" destdir="${build}/aop" debug="on">
                  	    	<classpath>
                  				<pathelement location="lib/spring.jar" />
                  				<pathelement location="lib/commons-logging-1.0.4.jar" />
                  				<pathelement location="lib/spring-aspects.jar" />
                  				<pathelement location="lib/aspectjrt.jar" />
                  				<pathelement location="lib/aspectjweaver.jar" />
                  				<pathelement location="lib/ehcache-1.3.0.jar" />	    						
                  				<pathelement path="${java.class.path}" />
                  	    		</classpath>
                  	    	</javac>	    	
                  	  </target>	
                  	<target name="init" depends="clean">
                  	    <!-- Create the time stamp -->
                  	    <tstamp/>
                  	    <!-- Create the build directory structure used by compile -->
                  	    <mkdir dir="${build}/aop"/>
                  	  </target>
                  	 <target name="clean"
                  	        description="clean up" >
                  	    <!-- Delete the ${build} and ${dist} directory trees -->
                  	    <delete dir="${build}/aop"/>
                  	  </target>	
                  </project>
                  Will you please have a look?

                  Many thanks in advance,
                  Ganesh

                  Comment


                  • #10
                    If I run the build script you provided I don't get a aop.xml inside the META-INF directory of the jar file, there is only a MANIFEST.MF. And also it isn't the MANIFEST.MF from the project... So there is something wrong with your build.xml imho.

                    There is also an error in your aop.xml.

                    Code:
                    	<weaver options="-verbose">
                    		<!-- only weave classes in our application-specific packages -->
                    		 <include within="com.cit.ecommerce.test.TestCache.*" /> 		
                    	</weaver>
                    You can only include packages/classes NOT methods, which is what you are doing here. It should read something like

                    Code:
                    	<weaver options="-verbose">
                    		<!-- only weave classes in our application-specific packages -->
                    		 <include within="com.cit.ecommerce.test.*" /> 		
                    	</weaver>
                    Last edited by Marten Deinum; Apr 24th, 2008, 06:40 AM.

                    Comment


                    • #11
                      Dear Marten,

                      I updated as you said.

                      i noticed two extra lines on your debug info:

                      Code:
                      [java] [AppClassLoader@92e78c] info register aspect org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect
                      [java] [AppClassLoader@92e78c] info register aspect org.springframework.transaction.aspectj.AnnotationTransactionAspect
                      My debug info:

                      Code:
                      [java] Apr 24, 2008 5:52:11 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
                           [java] INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@21bb53: display name [org.springframework.context.support.ClassPathXmlApplicationContext@21bb53]; startup date [Thu Apr 24 17:52:11 GMT+05:30 2008]; root of context hierarchy
                           [java] Apr 24, 2008 5:52:12 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
                           [java] INFO: Loading XML bean definitions from class path resource [spring-application.xml]
                           [java] Apr 24, 2008 5:52:12 PM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
                           [java] INFO: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@21bb53]: org.springframework.beans.factory.support.DefaultListableBeanFactory@1df738
                           [java] Apr 24, 2008 5:52:13 PM org.springframework.context.weaving.DefaultContextLoadTimeWeaver setBeanClassLoader
                           [java] INFO: Found Spring's JVM agent for instrumentation
                           [java] [AppClassLoader@223d6d] info AspectJ Weaver Version 1.5.3 built on Wednesday Nov 22, 2006 at 11:18:15 GMT
                           [java] [AppClassLoader@223d6d] info register classloader sun.misc.Launcher$AppClassLoader@223d6d
                           [java] [AppClassLoader@223d6d] info using configuration file:/D:/cepsPortalWorkspace/SpringAOP/lib/aop.jar!/META-INF/aop.xml
                           [java] [AppClassLoader@223d6d] info register aspect com.cit.ecommerce.test.AspectJCachingHandler
                           [java] Apr 24, 2008 5:52:13 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
                           [java] INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1df738: defining beans [org.springframework.context.weaving.AspectJWeavingEnabler#0,loadTimeWeaver,myBean]; root of factory hierarchy
                           [java] *** Called----public getContracts(**) ***
                           [java] *** Called----private method (**) ***
                           [java] ** Called ---> 1st Time **
                           [java] *** Called----public getContracts(**) ***
                           [java] *** Called----private method (**) ***
                           [java] ** Called ---> 2nd Time **

                      i'm not getting those lines. So something i need to include somewhere.
                      Will you please observe it and let me know the updates?



                      Thanks,
                      Ganesh

                      Comment


                      • #12
                        That is just some extra debugging info. Which you will get if you add '-Daj.weaving.verbose=true' that as a jvmarg.

                        Next to that have you fixed the error in your aop.xml as I suggested in the previous post?!

                        Comment


                        • #13
                          That's fine. I'm getting debug info same as yours.

                          but thing is not yet solved, Marten. i'm really upset on this.

                          Please see the updated aop.xml according to what you said.

                          Code:
                          <!DOCTYPE aspectj PUBLIC
                          "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
                          <aspectj>
                          	<aspects>
                          		<!-- weave in just this aspect -->
                          		<aspect name="com.cit.ecommerce.test.AspectJCachingHandler" />
                          		
                          	</aspects>
                          	<weaver options="-verbose">
                          		<!-- only weave classes in our application-specific packages -->
                          		<include within="com.cit.ecommerce.test.*" />
                          	</weaver>
                          
                          </aspectj>
                          i'm wondering where could be the problem.
                          ....still debugging it. please, could you spot the wrong?

                          Ganesh

                          Comment


                          • #14
                            Dear Marten,

                            I could be able to figure out the dirty problem.

                            Since i'm running it on Weblogic Workshop that is having 'jrocket' as jre, aspectj is not working. So i just deleted that dirty jre from build path.
                            Now it's working good. i don't know what could be the reason behind this.

                            Now i'll have to put my head on caching.

                            Thank you very much for all your efforts and having spent your valuable time for me.

                            See you,

                            Ganesh

                            Comment

                            Working...
                            X