You cannot because the executed lambda methods are static, i.e. you cannot even check something like thisJoinPoint.getTarget() instanceof Runnable
because the target is null. With anonymous subclasses this would work.
I.e. before something has been done about my AspectJ Bugzilla issue, you cannot really solve this problem.
Update: I found a workaround for you. It is not nice, but at least it works until AspectJ supports lambdas better. You need to tailor it to the method calling the runnable in question, though:
Driver application:
package de.scrum_master.app;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
public class Application {
public static void main(String[] args) throws InterruptedException, ExecutionException {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
System.out.println("Separate thread lambda");
});
CompletableFuture<Void> future2 = CompletableFuture.runAsync(new Runnable() {
@Override
public void run() {
try {
MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
System.out.println("Separate thread anonymous Runnable");
}
});
System.out.println("Main thread");
future.get();
future2.get();
}
}
Aspect:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class AsyncRunInterceptor {
private static final String CLASS_ASYNC_RUN = "java.util.concurrent.CompletableFuture$AsyncRun";
private static final String METHOD_RUN = "run";
@Pointcut("execution(void *(..)) && !within(de.scrum_master.aspect.AsyncRunInterceptor) && if()")
public static boolean isAsyncRun() {
final StackTraceElement[] stackTrace = new Exception().getStackTrace();
if (stackTrace.length < 3)
return false;
final StackTraceElement stackTraceElement = stackTrace[2];
return
stackTraceElement.getClassName() == CLASS_ASYNC_RUN
&& stackTraceElement.getMethodName() == METHOD_RUN;
}
@Before("isAsyncRun()")
public void beforeAsyncRun(JoinPoint thisJoinPoint) {
System.out.println("[" + Thread.currentThread().getId() + "] BEFORE " + thisJoinPoint);
}
@After("isAsyncRun()")
public void afterAsyncRun(JoinPoint thisJoinPoint) {
System.out.println("[" + Thread.currentThread().getId() + "] AFTER " + thisJoinPoint);
}
}
Console log:
Main thread
[10] BEFORE execution(void de.scrum_master.app.Application.lambda$0())
[11] BEFORE execution(void de.scrum_master.app.Application.1.run())
Separate thread lambda
Separate thread anonymous Runnable
[11] AFTER execution(void de.scrum_master.app.Application.1.run())
[10] AFTER execution(void de.scrum_master.app.Application.lambda$0())