Results 1 to 6 of 6

Thread: Cannot get the simplest AOP example working

  1. #1
    Join Date
    Dec 2009
    Posts
    4

    Default Cannot get the simplest AOP example working

    Hello,

    I'm new to AOP and trying to create a very simple example based on the reference guide. I'm at the point of not getting any errors but my advice method does not get called. I already spent 10 hours finding the problem but without an error message, I have no clue how to figure this out. Please help. Is there a way to dump a list of created proxies so I can find out why is mine not getting created? Or is there any global XML tag I'm missing. I have seen various proxy creation methods in the reference but it was not clear whether I have to use them or it is automatic with the use of the <aop:config> tag.

    This is a web application running on Tomcat 5.5 and I'm using Eclipse to redeploy and launch it.

    Let me know if you need any more information.

    web.xml:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="2.4"
    	xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    	<display-name>test4</display-name>
    
    	<listener>
      		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    
    	<servlet>
    		<servlet-name>test4</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>test4</servlet-name>
    		<url-pattern>*.htm</url-pattern>
    	</servlet-mapping>
    
    
    	<welcome-file-list>
    		<welcome-file>index.jsp</welcome-file>
    	</welcome-file-list>
    
    	<jsp-config>
    		<taglib>
    			<taglib-uri>/spring</taglib-uri>
    			<taglib-location>/WEB-INF/tld/spring-form.tld</taglib-location>
    		</taglib>
    	</jsp-config>
    
    
    </web-app>
    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-2.5.xsd
    			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    
    	<aop:config>
    		<aop:pointcut id="logging" expression="execution(* db.Product.*(..))"/> 
    		<aop:aspect ref="loggerBean">
    		    <aop:before pointcut-ref="logging" method="logSaveMethods"/>
    		</aop:aspect>
    	</aop:config>
    
    	<bean id="loggerBean" class="service.Logger"/>
     
    </beans>
    db.Product:
    Code:
    package db;
    
    public class Product {
    	int id = -1;
    	String name = "";
    	String desc = "";
    	double price = 0;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    		System.out.println("setName called");
    	}
            ...
    }
    service.Logger:
    Code:
    package service;
    
    public class Logger
    {
    	public void logSaveMethods()
    	{
    		System.out.println("AOP: Saving record");
    	}
    }
    Program output includes "setName called" but never "AOP: Saving record".

  2. #2

    Smile

    Hi,

    You need to add the below entry in web.xml just before the listener(org.springframework.web.context.ContextLo aderListener).

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

    This entry will tell the Spring Container where the applicationContext is placed on basis of which Spring will instantiate the beans in applicationContext.xml.

    Hope this helps.

    kartik

  3. #3
    Join Date
    May 2007
    Location
    Saint Petersburg, Russian Federation
    Posts
    1,189

    Default

    Quote Originally Posted by nsomlai View Post
    ...
    Program output includes "setName called" but never "AOP: Saving record".
    Your snippets don't show either 'Product' bean definition on how it's 'setName()' method is called. You can't expect the method to be aop advised it it's called by the spring container.

  4. #4
    Join Date
    Dec 2009
    Posts
    4

    Default

    kravicha: thanks, I tried to add that but as far as I know this is the default location and filename and the listener should load the XML automatically.

    denis: You are right, I was using a class that is not defined as a bean. I made the necessary changes and now trying to intercept something in an XML-defined singleton bean:


    The result is still the same though: no error, no intercepts with this definition:

    Code:
    	<aop:config>
    		<aop:pointcut id="logging" expression="execution(public void service.ProductManager.saveProduct(..))"/> 
    		<aop:aspect ref="loggerBean">
    		    <aop:before pointcut-ref="logging" method="logSaveMethods"/>
    		</aop:aspect>
    	</aop:config>
    Changing the definition to this (which, to my knowledge, is equivalent)
    Code:
    <aop:config>
    		<aop:aspect ref="loggerBean">
    		    <aop:before pointcut="execution(public void service.ProductManager.saveProduct(..))" method="logSaveMethods"/>
    		</aop:aspect>
    	</aop:config>
    results in an exception:
    Code:
    SEVERE: Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productManager' defined in ServletContext resource [/WEB-INF/test4-servlet.xml]: Initialization of bean failed; nested exception is java.lang.NoSuchMethodError: net.sf.cglib.proxy.Enhancer.setInterceptDuringConstruction(Z)V
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
    	at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:402)
    	at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:316)
    	at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:282)
    	at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:126)
    	at javax.servlet.GenericServlet.init(GenericServlet.java:212)
    	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1139)
    	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:966)
    	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3996)
    	at org.apache.catalina.core.StandardContext.start(StandardContext.java:4266)
    	at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
    	at org.apache.catalina.core.StandardHost.start(StandardHost.java:736)
    	at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
    	at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
    	at org.apache.catalina.core.StandardService.start(StandardService.java:448)
    	at org.apache.catalina.core.StandardServer.start(StandardServer.java:700)
    	at org.apache.catalina.startup.Catalina.start(Catalina.java:552)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    	at java.lang.reflect.Method.invoke(Unknown Source)
    	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295)
    	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433)

    applicationContext.xml is empty. test4-servlet.xml is as follows:
    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-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    
      <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost/test4"/>
      </bean>
      
     <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"/>
        <property name="mappingResources">
          <list>
            <value>db/Product.hbm.xml</value>
          </list>
        </property>
        <property name="hibernateProperties">
          <value>
            hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
            hibernate.current_session_context_class=thread
          </value>
        </property>
      </bean>
    
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
            <property name="prefix" value="/WEB-INF/jsp/"></property>
            <property name="suffix" value=".jsp"></property>        
        </bean>
    
        <bean id="productManager" class="service.ProductManager" init-method="init">
        	<property name="sessionFactory" ref="mySessionFactory"/>
        </bean>
    
    	<aop:config>
    		<aop:pointcut id="logging" expression="execution(public void service.ProductManager.saveProduct(..))"/> 
    		<aop:aspect ref="loggerBean">
    		    <aop:before pointcut-ref="logging" method="logSaveMethods"/>
    		</aop:aspect>
    	</aop:config>
    
    	<bean id="loggerBean" class="service.Logger"/>
    
    	<bean name="/list.htm" class="web.ListController">
            <property name="manager" ref="productManager"/>
        </bean>
        
       <bean name="/edit.htm" class="web.EditController">
            <property name="sessionForm" value="true"/>
            <property name="commandName" value="Product"/>
            <property name="commandClass" value="db.Product"/>
            <property name="validator">
                <bean class="service.ProductValidator"/>
            </property>
            <property name="formView" value="edit"/>
            <property name="successView" value="list.htm"/>
            <property name="productManager" ref="productManager"/>
        </bean>
    
         <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
            <property name="basename" value="messages"/>
        </bean>
    </beans>
    One more attempt tomorrow to fix this then I will have to give up on AOP, it's taking too much time to understand the concept.

  5. #5
    Join Date
    May 2007
    Location
    Saint Petersburg, Russian Federation
    Posts
    1,189

    Default

    Not sure about exact reason of your problem but 'java.lang.NoSuchMethodError: net.sf.cglib.proxy.Enhancer.setInterceptDuringCons truction(Z)V' makes me think that you use inconsistent spring and cglib versions.

  6. #6
    Join Date
    Dec 2009
    Posts
    4

    Default

    I checked and CGLIB was OK but it gave me an idea. I rechecked the libs I'm using for Hibernate3 and found that the distribution contains commons-collections-3.1.jar but I have copied the 3.2 version to my app. Replacing that fixed the problem and the advice is now called.

    Thanks a lot for your help.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •