I'm using aspectJ 1.8.10. In my code I have a bean with ScheduledExecutorService:
@Bean
public ScheduledExecutorService backgroundTaskExecutor() {
return Executors.newSingleThreadScheduledExecutor();
}
When bean instantiated, proxy class throws:
.AopConfigException: Could not generate CGLIB subclass of class [class java.util.concurrent.Executors$DelegatedScheduledExecutorService]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: No visible constructors in class java.util.concurrent.Executors$DelegatedScheduledExecutorService
I know, that ScheduledExecutorService haven't constructor, is the root cause. But I need to configure my aspect's pointcut to exclude FinalType classes. Like this:
@Before("!within(is(FinalType)) && execution(* your_method_name(..)) ")
But, as I mentioned, aspectJ version 1.8.10 is not recognize is(..) syntax. (Intellij IDEA warning Cannot resolve symbol 'is'). Application starts without AOP issues, but fails with
java.lang.IllegalArgumentException: No visible constructors in class java.util.concurrent.Executors$DelegatedScheduledExecutorService
What I'm doing wrong? Is there any changes is aspectj > 1.8.4? (is(..) syntax)
You have Spring AOP configured to force creation of CGLIB proxies even for interface types like ScheduledExecutorService
, probably via
@EnableAspectJAutoProxy(proxyTargetClass = true)
Just remove the proxyTargetClass = true
part or set to false
, then your aspect will work. You do not need any is(FinalType)
pointcut designator, just write something like
@Before("execution(* schedule*(..))")
in order to intercept scheduler methods.
Update: Let me explain why is(FinalType)
does not help you and why thinking it does not work is wrong:
Read the error messages again:
Could not generate CGLIB subclass of class
[class java.util.concurrent.Executors$DelegatedScheduledExecutorService]:
Common causes of this problem include using a final class or a non-visible class;
nested exception is
java.lang.IllegalArgumentException: No visible constructors in class
java.util.concurrent.Executors$DelegatedScheduledExecutorService
"No visible constructors" does not mean the class is final, it means what it says: There just are no visible constructors. Actually the inner static class Executors.DelegatedScheduledExecutorService
is package-protected in java.util.concurrent
where Executors
resides. If you look at the source code you see:
static class DelegatedScheduledExecutorService
extends DelegatedExecutorService
implements ScheduledExecutorService {
private final ScheduledExecutorService e;
DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
super(executor);
e = executor;
}
// (...)
}
See? No final
class here. The actual problem is that CGLIB just cannot create a subclass due to JVM limitations: You cannot subclass something that is in another package if it is not public
.
This is why I told you to let Spring use a JDK dynamic proxy and take advantage of the fact that in this case subclassing is not necessary but implementing an interface is enough.