13

i have a Java EE Webservice (REST) and would now like to use AspectJ, to create a rule that will print-out every incoming service call and their params.

I just read this tutorial and implemented the following code:

POM.XML

        <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.10</version>
    </dependency>
    
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.10</version>
    </dependency>
    
</dependencies>
<build>
  <plugins>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.7</version>
        <configuration>
            <complianceLevel>1.8</complianceLevel>
            <source>1.8</source>
            <target>1.8</target>
            <showWeaveInfo>true</showWeaveInfo>
            <verbose>true</verbose>
            <Xlint>ignore</Xlint>
            <encoding>UTF-8 </encoding>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <!-- use this goal to weave all your main classes -->
                    <goal>compile</goal>
                    <!-- use this goal to weave all your test classes -->
                    <goal>test-compile</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>

...and created a Test.aj File, with a Pointcut which should print-out a teststring after calling the getSignOfLife():

import de.jack.businesspartner.service.BusinessPartnerServiceImpl;
public aspect TestAspectJ {

    pointcut getSignOfLife() : 
      call(void BusinessPartnerServiceImpl.getSignOfLife());

    before() : getSignOfLife() {
        System.err.println("ADKL TEST ASPECT");
    }

}

--> But nothing happens if i call the getSignOfLife() Method. Can you help me?

Community
  • 1
  • 1
goblingift
  • 409
  • 4
  • 19

2 Answers2

8

Your point cut expression may be wrong:

pointcut getSignOfLife() : 
  call(void BusinessPartnerServiceImpl.getSignOfLife());

The expression in call should match the signature of your real method.

CheckList

  • return type: getSignOfLife seems has a return value, which you write a void return type in expression, which will fails the match;
  • parameter type: you can use f(..) to represent a method f with any parameter, but if you left it empty, it means no parameter. If your actual method has parameter, it will fails the match;
  • notice that int and Integer is different in expression, because primitives and boxing type is different;
  • you need original compiler plugin of maven in your pom;

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    

More

  • You may refer to here if you want to dive into AspectJ
  • In the most common cases, Spring AOP is enough to handle jobs like logging, auth etc, which can be used with annotation and I think, is more convenient.
  • Runnable code.
Tony
  • 5,972
  • 2
  • 39
  • 58
5

@Tony explained it pretty well.

Just regarding the tutorial you pointed out, I tested it by modifying slightly the account aspect:

public aspect AccountAspect {
    final int MIN_BALANCE = 10;

    pointcut callWithDraw(int amount, Account acc) : 
     call(boolean Account.withdraw(int)) && args(amount) && target(acc);

    before(int amount, Account acc) : callWithDraw(amount, acc) {
    }

    boolean around(int amount, Account acc) : 
      callWithDraw(amount, acc) {
        acc.balance -= 5;
        if (acc.balance < amount) {
            return false;
        }
        return proceed(amount, acc);
    }

    after(int amount, Account balance) : callWithDraw(amount, balance) {
        System.out.println("After withdraw " + amount);
    }
}

Then in a simple servlet:

@WebServlet("/Hello")
public class Hello extends HttpServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 482093033327453159L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        Account acc = new Account();
        resp.setContentType("text/html");
        PrintWriter out = resp.getWriter();
        out.println("Account before withdraw: " + acc.balance + "<br/>");
        acc.withdraw(10);
        out.println("Account after withdraw: " + acc.balance + "");
        out.close();
    }
}

I used:

  • Java 8
  • Wildfly 10.1.0.Final

It works as expected (when calling withdraw the account is withdrawn of 5 more, as you can see from the around in my aspectj file, and prints are written on the console)

Adonis
  • 4,670
  • 3
  • 37
  • 57