0
votes

I am new to Spring AOP. I wrote an aspect with a simple @Before advice, which looks like this

package testing_spring;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class MyTestAspect {

  @Before("execution(public void open())")
  public void runThis() {
    System.out.println("About to open something ...");
  }
}

This is the context.xml file:

<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-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

  <aop:aspectj-autoproxy />

  <bean class="testing_spring.House" name="house">
    <property name="windows">
      <list>
        <ref bean="window1"/>
        <ref bean="window2"/>
        <ref bean="window3"/>
      </list>
    </property>
    <property name="doors">
      <list>
        <ref bean="door"/>
      </list>
    </property>
  </bean>

  <bean class="testing_spring.Window" name="window1" id="window1"/>
  <bean class="testing_spring.Window" name="window2" id="window2"/>
  <bean class="testing_spring.Window" name="window3" id="window3"/>

  <bean class="testing_spring.Door" name="door" id="door"/>


  <bean class="testing_spring.MyTestAspect" name="mta"/>
</beans>

The rest are just some simple classes for testing:

package testing_spring;

public abstract class Openable {

  private boolean open;

  public void open() {
    open = true;
  }

  public void close() {
    open = false;
  }

  public boolean isOpen() {
    return open;
  }
}

package testing_spring;

public class Door extends Openable {

}

package testing_spring;

public class Window extends Openable {

}

import java.util.*;

public class House {

  private List<Window> windows;
  private List<Door> doors;

  public void setWindows(List<Window> windows) {
    this.windows = windows;
  }

  public void setDoors(List<Door> doors) {
    this.doors = doors;
  }

  public List<Window> getWindows() {
    return windows;
  }

  public List<Door> getDoors() {
    return doors;
  }
}

package testing_spring;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

  public static void main(String[] args) {
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("context.xml");

    House house = (House) ctx.getBean("house");
    printHouseInfo(house);
  }

  public static void printHouseInfo(House house) {
    System.out.println("My house has " + house.getDoors().size() + " doors and " + house.getWindows().size() + " windows.");
  }
}

So, when I run the main method, what I get is:

cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'house' defined in class path resource [context.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException

But when I comment out the @Before annotation, everything works fine, it prints:

My house has 1 doors and 3 windows.

So there must be something wrong with the before-advice, but I do not understand, what it is.

1
There is nothing wrong with your advice. You just don't have the needed dependencies for applying AOP. That is what the java.lang.NoClassDefFoundError is telling you. - M. Deinum
Thanks, you were totally right! - DanielBK

1 Answers

0
votes

You might have not added classpath for aspectj-weaver.jar