Blog-Archiv

Dienstag, 5. Dezember 2023

Java AspectJ Wildcards

It is a rare "pleasure" to get in touch with aspects in Java. Here is what I want to remember about it, without being an expert. I am doing this since the experts seem to be unable to provide quickly accessible explanations of these syntax constructs, in other words: what would we do without stackoverflow? Read through hundreds of AspectJ reference pages, just to find out that they forgot to document it?

Wildcards are expressions that describe something imprecisely, mostly character sequences. Lots of software bugs rise from such fuzzy expressions: "if you have a problem and try to solve it with regular expressions, then you have two problems". Same goes with aspects, do not use it just for fun, they will make life complicated.

Now here come the AspectJ wildcards, note that they have nothing to do with regular expressions. I refer to pointcut definitions that describe on which class and method an aspect's advice should work, something like:

@Pointcut( "execution(public * com.abc..dao..*(..))" )

Wildcards

*

The character '*' (asterisk) stands for any fully qualified Java class name, but only when it is used without any adjacent '.' (dot) character. It would match both MyClassWithoutPackageName or java.util.List.

..

The sequence ".." (dot dot) stands for any character sequence that starts and ends with a "." (dot), whereby it consumes the maximum of possible characters, including '.' (dots). It would match both .net. or .net.http. but not java.net. as the latter does not start with a '.' (dot). Typically this wildcard is used for Java package name fragments.

In context of methods, the sequence ".." (dot dot) has a different meaning. Here it stands for a list of zero or more parameters. The expression "foo(..)" would match all methods with name foo, having any number of parameters, and "foo(.., String)" would match all foo having a String as last parameter.

*..

The character '*' (asterisk) has a different meaning when used together with ".." (dot dot). Here it stands for zero or more characters except '.' (dot).

The sequence "*.." would match .net. or java.net. but not .net.URL as the latter does not end with a '.' (dot).

..*

The sequence "..*" would match .net. or .net.URL but not java.net. as the latter does not start with a '.' (dot).

*..*

The sequence "*..*" would match all of .net. or .net.http. or java.net. or .net.http.HttpClient or java.net.URL.

Note

AspectJ patterns seem to be not case-sensitive. Feel free to write java.util.map instead of java.util.Map. The violent psychopath that ends up maintaining your code will be delighted.