spring-cloud-commons icon indicating copy to clipboard operation
spring-cloud-commons copied to clipboard

@RefreshScope Filters Extending OncePerRequestFilter Fail to Work / Also @Lazy on filters can't work

Open omarmahamid opened this issue 1 year ago • 1 comments

When a filter class annotated with @RefreshScope extends OncePerRequestFilter, it fails to function correctly. The issue arises because the filter is instantiated as a proxy (using CGLIB), causing certain properties of the parent class, such as the logger in GenericFilterBean, to be null.

Reproduction Code:

@RefreshScope
public class MyFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // Filter logic here
        filterChain.doFilter(request, response);
    }
}

Root Cause: The @RefreshScope annotation creates a CGLIB proxy for the filter bean. The GenericFilterBean class, which is part of the Spring Framework and serves as a base class for OncePerRequestFilter, contains a protected final Logger logger field. This field is initialized directly in the parent class and does not work properly when the bean is proxied. As a result, the logger instance is null, leading to NullPointerException when logging is attempted.

spring-framework version: 6.2.1 spring-boot: 3.4.0 spring-cloud-context: 3.1.7

ERROR

java.lang.NullPointerException: Cannot invoke "org.apache.commons.logging.Log.isDebugEnabled()" because "this.logger" is null
	at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:239)
	at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:245)
	at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:102)
	at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3857)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4462)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193)
	at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
	at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
	at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749)
	at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:772)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193)
	at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
	at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
	at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749)
	at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:203)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
	at org.apache.catalina.core.StandardService.startInternal(StandardService.java:415)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
	at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:870)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
	at org.apache.catalina.startup.Tomcat.start(Tomcat.java:437)
	at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:128)
	at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:107)
	at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:516)

Suggested Solution:

to make logger defined in GenericFilterBean

	protected final Log logger = LogFactory.getLog(getClass());

static

	protected static final Log logger = LogFactory.getLog(getClass());

omarmahamid avatar Dec 29 '24 17:12 omarmahamid

@spring-cloud-issues @OlgaMaciaszek @spencergibb any idea of this issue ?

omarmahamid avatar Aug 25 '25 20:08 omarmahamid