To get the expected result, you can remove the comment on the line with joinPoint.proceed() and remove the line below. Eventually remove the AspectJ compiler or the JVM agent to avoid weaving in the advice.

The test class that asserts that the String‘s toLowerCase() method works as expected:

Without AspectJ weaving, the test finishes successfully, but with weaving the result is:

org.junit.ComparisonFailure: expected:<[this is a test]> but was:<[THIS IS A TEST]>

Best practice from enterprise frameworks

Features like transaction handling, security and concurrency support are good candidates to be done with aspects. Spring, Guice and EJB implementations all use aspects to provide such enterprise capabilities without cluttering the application’s source code with infrastructure logic.

You can see this post for a good example. Best practice with Java 5 and later is to add an annotation on methods that will be intercepted.

Annotations that says this method should be executed asynchronously in a transaction:

@Async
@Transactional
public void demoMethod() {
// logic ..
}

These annotations are excellent pointcuts for enterprise frameworks.

Cases where aspects should be avoided

To change the target method like the StringAspect above should be avoided. You can replace an instance with a mock/stub object with AspectJ. In situations where the called instance is an object of a final class that doesn’t implement any interfaces, then an aspect is your only choice. It mocks away the dependency, but refactoring the code and use a mocking framework should be the preferred choice. It makes the code much more readable.

Especially without a tool like AJDT that visualizes the joinpoints in the source code. Here’s an example with the AJDT Eclipse plugin.

You should be really careful about adding or changing any data inside an advice. Such modifications makes the code almost impossible to read and the chance for bugs are higher.

Else, if many of the developers in a team isn’t familiar with aspects, you should also limit the use since it adds “magic” to the application that only a few developers on the team can understand.