I am using the following sample code to understand AspectJ:
public class Account {
int balance = 20;
public boolean withdraw(int amount) {
if (balance < amount) {
return false;
}
balance = balance - amount;
return true;
}
public static void main(String[] args) {
Account acc = new Account();
acc.withdraw(5);
Account acc2 = new Account();
acc2.withdraw(25);
}
}
and the following Aspect:
public aspect AccountAspect {
pointcut callWithDraw(int amount, Account acc) :
call(boolean Account.withdraw(int)) && args(amount) && target(acc);
before(int amount, Account acc) : callWithDraw(amount, acc) {
System.out.printf("[before] withDraw, current balance %d%n", acc.balance);
}
boolean around(int amount, Account acc) : callWithDraw(amount, acc) {
if (acc.balance < amount) {
System.out.println("[around] withDraw, check failed");
return false;
}
System.out.println("[around] withDraw, check success");
return proceed(amount, acc);
}
after(int amount, Account acc) : callWithDraw(amount, acc) {
System.out.printf("[after] withDraw, current balance %d%n", acc.balance);
}
}
I am using the following Gradle build file:
plugins {
id 'java'
id "io.freefair.aspectj.post-compile-weaving" version "4.1.4"
}
configurations {
ajc
aspects
aspectCompile
compile{
extendsFrom aspects
}
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation group: 'org.aspectj', name: 'aspectjrt', version: '1.9.4'
implementation group: 'org.aspectj', name: 'aspectjweaver', version: '1.9.4'
implementation group: 'org.codehaus.mojo', name: 'aspectj-maven-plugin', version: '1.8'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
compileJava {
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
//The following two lines are useful if you have queryDSL if not ignore
dependsOn configurations.ajc.getTaskDependencyFromProjectDependency(true, "compileJava")
}
and I am using Ajc compiler in Intellij to compile Java classes and aspects. In addition, I am setting the following VM options:
-javaagent:c:\\Users\\dev\\extlibs\\aspectjweaver-1.9.6.jar
The code compiles and runs without any issues but the aspect never triggers. I am not sure what I am missing in my configuration but I could not find anything else I can do when using AspectJ. If I use @Aspect annotation and register the annotated Aspect in META-INF/aop.xml, the aspect runs but annotated @Aspect Java classes does not allow to create privileged aspect which I need to catch/intercept a private method. Any suggestions on how to resolve this issue?
You are mixing a whole lot of stuff there:
-javaagent:
.I guess you could use all three options, compile-time, post-compile-time and load-time weaving, but you should decide which one and not mix them. You also should decide if you want to use Gradle or Maven and also not try to mix them.
This is how compile-time weaving works:
src/main/aspectj
.plugins {
id "java"
id "io.freefair.aspectj" version "5.1.1"
}
group "org.example"
version "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation "org.aspectj:aspectjrt:1.9.6"
}
> Task :compileJava NO-SOURCE
> Task :compileAspectj UP-TO-DATE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :Account.main()
[before] withDraw, current balance 20
[around] withDraw, check success
[after] withDraw, current balance 15
[before] withDraw, current balance 20
[around] withDraw, check failed
[after] withDraw, current balance 20
Of course you could also compile a separate aspect library and weave it into your application code, if the aspect library is to be re-used for several applications or modules or if the application source code is not written in Java (but e.g. in Kotlin, Groovy or Scala) and hence cannot compiled by the AspectJ compiler directly. I am not going into this here, though, because I wanted to show you the simplest solution, as you seem to be a beginner. (BTW, I am not a Gradle user either, I normally use AspectJ with Maven.)
Update: The plugin documentation is really bad, but you can see some example projects in the maintainer's GitHub repository:
All of this can also be done using Maven and AspectJ Maven Plugin, but you specifically asked for Gradle.