I've been getting these messages at startup of my Spring Boot service.
Unable to proxy interface-implementing method [public final void org.springframework.web.filter.OncePerRequestFilter.doFilter(javax.servlet.ServletRequest,javax.servlet.ServletResponse,javax.servlet.FilterChain) throws javax.servlet.ServletException,java.io.IOException] because it is marked as final: Consider using interface-based JDK proxies instead!
Unable to proxy interface-implementing method [public final void org.springframework.web.filter.GenericFilterBean.init(javax.servlet.FilterConfig) throws javax.servlet.ServletException] because it is marked as final: Consider using interface-based JDK proxies instead!
The problem's I can't figure out what classes are getting selected by my Pointcut that is causing this:
My Aspect file:
@Around("execution(public * com.torchai..*.*(..)) "
+ "&& loggingEnabledAndNotDisabled()"
+ "&& !allPublicControllerMethodsNotDisabled()"
+ "&& !allPublicControllerLayerMethodsNotDisabled()"
+ "&& !allPublicServiceMethodsNotDisabled()"
+ "&& !allPublicServiceLayerMethodsNotDisabled()")
public Object allPublicMethodsNotDisabledAndNotControllerOrService(
final ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
return log(proceedingJoinPoint, LogEvent.LAYER_OTHER);
}
@AfterThrowing(
pointcut = "execution(public * com.torchai..*.*(..)) "
+ "&& loggingEnabledAndNotDisabled()"
+ "&& !allPublicControllerMethodsNotDisabled()"
+ "&& !allPublicControllerLayerMethodsNotDisabled()"
+ "&& !allPublicServiceMethodsNotDisabled()"
+ "&& !allPublicServiceLayerMethodsNotDisabled()",
throwing = "t")
public void allPublicMethodsNotDisabledAndNotControllerOrService(
final JoinPoint joinPoint, final Throwable t) {
onException(joinPoint, t, LogEvent.LAYER_OTHER);
}
I'm not pasting in all the supporting Pointcuts, but you can see they are the same for @Around and @AfterThrowing. These points cuts should not be selecting anything at this point.
What I find really interesting is if I totally comment out the @Around code, the problem is still there.
But if I leave the @Around code and comment out @AfterThrowing, the problem is gone.
So even though these 2 things should be equivalent in terms of what they select, for some reason @AfterThrowing is selecting something that is causing the problem.
Update
@kriegaex Thanks for your through response. Here are my other pointcuts. Was just trying to keep things simple by not including them.
@Pointcut("@annotation(com.torchai.service.aspect.annotations.AspectLog) "
+ "|| @target(com.torchai.service.aspect.annotations.AspectLog)")
public void methodOrClassLoggingEnabled() {
}
@Pointcut("!@annotation(com.torchai.service.aspect.annotations.AspectNoLog)")
public void methodLoggingNotDisabled() {
}
@Pointcut("methodOrClassLoggingEnabled() && methodLoggingNotDisabled()")
public void loggingEnabledAndNotDisabled() {
}
/**
* Any public methods in classes which are specifically annotated as a Controller
*/
@Pointcut("within(@org.springframework.web.bind.annotation.RestController *) ||"
+ "within(@org.springframework.stereotype.Controller *)")
public void allPublicControllerMethods() {
}
/**
* Any public methods in classes which are specifically annotated as a Service
*/
@Pointcut("within(@org.springframework.stereotype.Service *)")
public void allPublicServiceMethods() {
}
// Controller classes are enabled by default, so don't need to be specifically enabled.
@Pointcut("allPublicControllerMethods() "
+ "&& methodLoggingNotDisabled()")
public void allPublicControllerMethodsNotDisabled() {
}
// Service classes are enabled by default, so don't need to be specifically enabled.
@Pointcut("allPublicServiceMethods() "
+ "&& methodLoggingNotDisabled()")
public void allPublicServiceMethodsNotDisabled() {
}
// Components which aren't Service classes, but in the service package need to be enabled with @AspectLog
@Pointcut("execution(public * com.torchai.service..service..*(..)) "
+ "&& loggingEnabledAndNotDisabled()")
public void allPublicServiceLayerMethodsNotDisabled() {
}
// Components which aren't Controller classes, but in the controller package need to be enabled with @AspectLog
@Pointcut("execution(public * com.torchai.service..controller..*(..)) "
+ "&& loggingEnabledAndNotDisabled()")
public void allPublicControllerLayerMethodsNotDisabled() {
}
@Around("allPublicControllerMethodsNotDisabled() "
+ "|| allPublicControllerLayerMethodsNotDisabled()")
public Object logController(final ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
return log(proceedingJoinPoint, LogEvent.LAYER_CONTROLLER);
}
@Around("allPublicServiceMethodsNotDisabled() "
+ "|| allPublicServiceLayerMethodsNotDisabled()")
public Object logService(final ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
return log(proceedingJoinPoint, LogEvent.LAYER_SERVICE);
}
I understand the basic meaning of the message, although admittedly, I'm not sure how to do the JDK proxy instead. But I don't think it really necessary. We do have a Filter class which implements OncePerRequestFilter, but I can't be sure that that is the one getting picked up, because it doesn't say.
But my real confusion is not just that a class is getting picked up that I didn't expect, but that it seems to only get picked up by the @AfterThrowing and not by @Around . Why wouldn't these be exactly the same?
Update #2 (a few minutes later)
I'm thinking this might have something to do with my used of execution as opposed to your suggestion of within. I don't fully understand the difference. But still, the definitions in @AfterThrowing and @Around are the same. And even where I'm using execution, it still needs to match the other conditions.
Update #3
I've created a repo that shows the problem: https://github.com/peterkronenberg/aoptest
At startup, Springboot issues these messages:
2022-03-24 15:58:57.261 INFO 35104 --- [ main] o.s.aop.framework.CglibAopProxy : Unable to proxy interface-implementing method [public final void org.springframework.web.filter.OncePerRequestFilter.doFilter(javax.servlet.ServletRequest,javax.servlet.ServletResponse,javax.servlet.FilterChain) throws javax.servlet.ServletException,java.io.IOException] because it is marked as final: Consider using interface-based JDK proxies instead!
2022-03-24 15:58:57.261 INFO 35104 --- [ main] o.s.aop.framework.CglibAopProxy : Unable to proxy interface-implementing method [public final void org.springframework.web.filter.GenericFilterBean.init(javax.servlet.FilterConfig) throws javax.servlet.ServletException] because it is marked as final: Consider using interface-based JDK proxies instead!
2022-03-24 15:58:57.310 ERROR 35104 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Exception starting filter [authFilter]
The service doesn't start up, which is not what I was seeing originally. But maybe that provides more clues. But if I disabled the Aspect code, simply by commenting out the @Aspect annotation in the AspectLayer class, then it seems to work.
Somehow, there is a conflict between my Aspect code and my Filter code
I do not want my AuthFilter class to be picked up by my Aspect code. I believe that's what is causing the problem, although I'm not sure why