Logging aspect example
Once upon time I was writing a plugin for a closed-source LMS J2EE application having such dependencies that it wasn’t feasible to run it locally. During an API call, a method deep inside the application was failing but the exception didn’t contain enough information to track the cause of the problem. I therefore needed to change the method to log the value of its argument when it fails.
The AspectJ code is quite simple:
LoggingAspect.java
@Aspect public class LoggingAspect { @Around("execution(private void TooQuiet3rdPartyClass.failingMethod(..))") public Object interceptAndLog(ProceedingJoinPoint invocation) throws Throwable { try { return invocation.proceed(); } catch (Exception e) { Logger.getLogger("AspectJ").warning( "THE INJECTED CODE SAYS: the method " + invocation.getSignature().getName() + " failed for the input '" + invocation.getArgs()[0] + "'. Original exception: " + e); throw e; } } }
Notes:
- The aspect is a normal Java class with the @Aspect annotation, which is just a marker for AspectJ
- The @Around annotation instructs AspectJ to execute the method instead of the one matched by the expression, i.e. instead of the failingMethod of the TooQuiet3rdPartyClass
- The around advice method needs to be public, return an Object, and take a special AspectJ object carrying information about the invocation – ProceedingJoinPoint – as its argument and it may have an arbitrary name (Actually this is the minimal form of the signature, it could be more complex.)
- We use the ProceedingJoinPoint to delegate the call to the original target (an instance of the TooQuiet3rdPartyClass) and, in the case of an exception, to get the argument’s value
- I’ve used an @Around advice though @AfterThrowing would be simpler and more appropriate but this shows better the capabilities of AspectJ and can be nicely compared to the dynamic java proxy example above
Since I hadn’t control over the application’s environment, I couldn’t enable the load-time weaving and thus had to use AspectJ’s Ant task to weave the code at the build time, re-package the affected JAR and re-deploy it to the server.
Related Article:
Reference: Practical Introduction into Code Injection with AspectJ, Javassist, and Java Proxy from our JCG partner Jakub Holý at The Holy Java blog