Performing post-compile weaving of projects using:
This project does not use Maven or Spring.
The projects include:
app.aspects
- Contains a single LogAspect
class annotated with @Aspect
.app.aspects.weaver
- No source files, only dependencies to declare aspects and project to weave.app.common
- Defines @Log
annotation referenced by pointcuts described in LogAspect
.app.program.main
- Files to be woven with jointpoints described in LogAspect
.Build files that relate to aspects are defined here. The idea is that weaving is independent from the application so neither the application's common classes nor the main program need know about weaving. Rather, the main program need only reference @Log
from the common package and AJC will take care of the weaving.
apply plugin: "io.freefair.aspectj.post-compile-weaving"
dependencies {
// For the @Log annotation
compileOnly project(':app.common')
// The LogAspect's joinpoint references the Main Program
compileOnly project(':app.program.main')
// Logging dependency is also compiled, but not shown here
}
apply plugin: "io.freefair.aspectj.post-compile-weaving"
dependencies {
compileOnly "org.aspectj:aspectjrt:1.9.4"
// This should set the -aspectpath ?
aspect project(":app.aspects")
// This should set the -inpath ?
inpath(project(":app.program.main")) {
// Only weave within the project
transitive = false
}
}
The Log
annotation is straightforward:
package com.app.common.aspects;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE, ElementType.CONSTRUCTOR })
public @interface Log {
boolean secure() default false;
}
The main program resembles:
package com.app.program.main;
import com.app.common.aspects.Log;
@Log
public class Program {
/** This is the method to weave. */
protected void run() throws InterruptedException, TimeoutException {
}
}
The logging aspect resembles (see the code from a related question):
@Aspect
public class LogAspect {
// In the future this will target points annotated with @Log
@Pointcut("execution(* com.app.program.main.Program.run(..))")
public void loggedClass() {
}
@Around("loggedClass()")
public Object log(final ProceedingJoinPoint joinPoint) throws Throwable {
return log(joinPoint, false);
}
private Object log(final ProceedingJoinPoint joinPoint, boolean secure) throws Throwable {
// See last year's code for the full listing
log.info("\u21B7| {}{}#{}({})", indent, className, memberName, params);
}
}
It appears weaving is taking place, but the advice cannot be found:
.../app.aspects/build/classes/java/main!com/app/aspects/LogAspect.class [warning] advice defined in com.app.aspects.LogAspect has not been applied [Xlint:adviceDidNotMatch]
What needs to change so that weaving of the LogAspect
into Program
's run()
method works using Gradle?
The ajc.options
file shows:
-inpath
.../app.aspects/build/classes/java/main
-classpath
.../.gradle/caches/modules-2/files-2.1/org.aspectj/...
-d
.../app.aspects/build/classes/java/main
-target
11
-source
11
It is disconcerting that -aspectpath
isn't shown and -inpath
is listing app.aspects
instead of app.program.main
.
Merging apps.aspects
and apps.aspects.weaver
into the same project has produced:
Join point 'method-execution(void com.app.program.main.Program.run())' in Type 'com.app.program.main.Program' (Program.java:396) advised by around advice from 'com.app.aspects.LogAspect' (LogAspect.class(from LogAspect.java))
While this solves the problem, I don't understand why LogAspect
needs to be in the same project that performs the weaving. The Gradle file becomes:
apply plugin: "io.freefair.aspectj.post-compile-weaving"
dependencies {
compileOnly "org.aspectj:aspectjrt:1.9.4"
compileOnly project(':app.common')
compileOnly project(':app.program.main')
compileOnly org_apache_logging_log4j__log4j_api
inpath(project(":app.program.main")) {
transitive = false
}
}
compileJava.ajc.options.compilerArgs += "-showWeaveInfo"
compileJava.ajc.options.compilerArgs += "-verbose"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With