Announcement Announcement Module
Collapse
No announcement yet.
newbie: AOP question Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Yes, if you are not letting Spring manage your class, then SpringAOP could be an issue. You could use @Configurable for the class that is not managed by the Spring container, but that would only work if you had access to the source code (which in your case you don't).

    The best thing about Spring is that there is more then 1 way to do anything which means you can still do it.
    In your situation AspectJ would be a solution (as some of the guys have pointed out earlier).

    Below you'll find a working example, but i would seriously suggest to read up on chapters 6 and 7 of Spring reference manual.



    Aspect:

    Code:
    import org.apache.log4j.Logger;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.Signature;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class FooAspect {
    	Logger logger = Logger.getLogger(FooAdvice.class);
    	
    	@Pointcut("execution(public Object org.apache.commons.beanutils.PropertyUtilsBean.getProperty(..))")
    	public void getProperty() {
    	}
    
    	@Around("getProperty()")
    	public Object profile(ProceedingJoinPoint pjp) throws Throwable {
    		Object returnValue = null;
    		Signature signature = pjp.getStaticPart().getSignature();
    		Object parameter = (Object) pjp.getArgs()[0];
    		if (parameter != null){
    			logger.debug(">>> Proceeding with execution");
    			returnValue = pjp.proceed();
    		} else {
    			logger.debug(">>> Hijacking the execution");
    			returnValue = "Hijacked execution of " + signature.getName() + " method";
    		}
    		return returnValue;
    	}
    }
    META-INF/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="org.apache.commons.beanutils.*" />
    	</weaver>
    	
    	<aspects>
    		<!-- weave in just this aspect -->
    		<aspect name="org.oz.spring.prototype.thread49824.FooAspect" />
    	</aspects>
    </aspectj>
    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"  
    	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/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd 
                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
    	
    	
    	<context:load-time-weaver/>
    </beans>
    Test:

    Code:
    public void testSpringAOP() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{
    		PropertyUtilsBean utilBean = new PropertyUtilsBean();
    		utilBean.getProperty(null, null);
    }
    Good luck

    Comment


    • #17
      re:

      Hi,
      Thanks for the info I am trying to get it to work, but I think the error I am getting is just some with the environment I am trying to get it to work in (grails)

      2008-02-15 17:46:32.519::WARN: Failed startup of context org.mortbay.jetty.webapp.WebAppContext@94cbe2{/,C:\zem\grails_projects\op
      enmrm/web-app}
      org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'org.springframework.context.weaving.AspectJWeav
      ingEnabler#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationExce ption: Error creati
      ng bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [ja
      va.net.URLClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your
      Java virtual machine with Spring's agent: -javaagent:spring-agent.jar
      at java.security.AccessController.doPrivileged(Native Method)
      at RunApp_groovy$_run_closure2_closure7.doCall(RunApp _groovy:74)
      at RunApp_groovy$_run_closure2_closure7.doCall(RunApp _groovy)
      at Init_groovy$_run_closure6.doCall(Init_groovy:127)
      at RunApp_groovy$_run_closure2.doCall(RunApp_groovy:7 3)
      at RunApp_groovy$_run_closure2.doCall(RunApp_groovy)
      at RunApp_groovy$_run_closure1.doCall(RunApp_groovy:6 5)
      at RunApp_groovy$_run_closure1.doCall(RunApp_groovy)
      at gant.Gant.dispatch(Gant.groovy:271)
      at gant.Gant.this$2$dispatch(Gant.groovy)
      at gant.Gant.invokeMethod(Gant.groovy)
      at gant.Gant.processTargets(Gant.groovy:436)
      at gant.Gant.processArgs(Gant.groovy:372)
      Caused by: org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'loadTimeWeaver': Initialization of b
      ean failed; nested exception is java.lang.IllegalStateException: ClassLoader [java.net.URLClassLoader] does NOT provide an 'addTransfor
      mer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:s
      pring-agent.jar

      Comment


      • #18
        I've had a similar problem. Starting my Spring application without Jetty:

        Code:
        	public static void main(String[] args) {
        		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-configuration/demoQuartz-applicationContext.xml");
        works fine. With VM argument given as follows:

        Code:
        -javaagent:~/tools/spring-framework-2.5/dist/weaving/spring-agent.jar
        Starting the same application inside Jetty

        Code:
        	public static void main(String[] args) {
        		// start spring container
        		String[] configLocations = new String[] { "classpath:spring-configuration/demoQuartz-applicationContext-jetty.xml" };
        
        		ApplicationContext context = new FileSystemXmlApplicationContext(configLocations);
        		Server server = (Server) context.getBean("jettyServer");
        		// get host
        		String host = server.getConnectors()[0].getHost();
        		if (host == null) {
        			host = "localhost";
        		}
        		// get port
        		int port = server.getConnectors()[0].getPort();
        		// get context path
        		Handler[] handlers = ((ContextHandlerCollection) server.getHandlers()[0]).getHandlers();
        		String contextPath = ((WebAppContext) handlers[0]).getContextPath();
        		if (LOG.isInfoEnabled()) {
        			LOG.info("server started - 'http://" + host + ":" + port + contextPath + "'");
        		}
        
        	}
        fails:

        Code:
        java.lang.IllegalStateException: ClassLoader [org.mortbay.jetty.webapp.WebAppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method.
        	at org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver.<init>(ReflectiveLoadTimeWeaver.java:103)
        	at org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver.<init>(ReflectiveLoadTimeWeaver.java:86)
        	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        I started Jetty with the following Spring configuration:

        Code:
        	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        		<property name="locations">
        			<list>
        				<value>classpath:/spring-configuration/jetty.properties</value>
        			</list>
        		</property>
        		<property name="ignoreResourceNotFound" value="true"/>
        		<property name="propertiesArray">
        			<props>
        				<prop key="jetty.port">8080</prop>
        				<prop key="jetty.contextPath">/</prop>
        				<prop key="jetty.war">src/main/webapp</prop>
        			</props>
        		</property>
        	</bean>
        
            <bean id="jettyServer" class="org.mortbay.jetty.Server" init-method="start" destroy-method="stop">
                <property name="connectors">
                    <list>
                        <bean id="Connector" class="org.mortbay.jetty.nio.SelectChannelConnector">
                            <property name="port" value="${jetty.port}"/>
                        </bean>
                    </list>
                </property>
        
                <property name="handler">
                    <bean id="handlers" class="org.mortbay.jetty.handler.HandlerCollection">
                        <property name="handlers">
                            <list>
                                <bean id="contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection">
                                    <property name="handlers">
                                        <list>
                                            <bean class="org.mortbay.jetty.webapp.WebAppContext">
                                                <property name="contextPath" value="${jetty.contextPath}"/>
                                                <property name="war" value="${jetty.war}">
                                                </property>
                                            </bean>
                                        </list>
                                    </property>
                                </bean>
                            </list>
                        </property>
                    </bean>
                </property>
            </bean>
        The problem was one missing line of configuration in the jetty-XML above. After i added the load-time-weaver configuration to the jetty running the Spring application everything runs as smoothly as outside the container.

        Code:
            <context:load-time-weaver />
        Now all my @Configurable beans get @Autowired inside Jetty, too.

        Spring is

        Comment

        Working...
        X