I have a filter to save requests to DB. But I get NullPointerException on autowired field: inboundRequestLogStore.
I've tried the suggestion from Using some beans in Filter bean class? (I've added SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, filterConfig.getServletContext()); to the filter init method and defined a bean in my root-context.xml )
and now it works for the RequestLogFilter class. But, in the InboundRequestLogStore class I have another autowired filed logService to save my entity to DB and now at this point I get NullPointerEception. Why I have the NPE and how to resolve it? I have the same services/components in another parts of my project and they autowires services without any problems. I have troubles only using the filter.
@Component
public class RequestLogFilter implements Filter {
@Autowired
private InboundRequestLogStore inboundRequestLogStore;
public RequestLogFilter() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, filterConfig.getServletContext());
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest requestToCache = new ContentCachingRequestWrapper((HttpServletRequest) request);
HttpServletResponseCopier responseCopier = new HttpServletResponseCopier((HttpServletResponse) response);
chain.doFilter(request, responseCopier);
responseCopier.flushBuffer();
if (request.getAttribute(InboundRequestAspect.INBOUND_LOG_MARKER) != null) {
InboundRequestLogRecord logRecord = new InboundRequestLogRecord();
setters....
inboundRequestLogStore.add(logRecord);
}
}
}
--
@Component("inboundRequestLogStore")
public class InboundRequestLogStore implements InitializingBean {
private ConcurrentLinkedQueue<InboundRequestLogRecord> queue = new ConcurrentLinkedQueue<>();
@Autowired
private LogService logService;
@Override
public void afterPropertiesSet() throws Exception {
reseterPool = new ScheduledThreadPoolExecutor(1);
reseterPool.scheduleWithFixedDelay(new LogRequestSaveQueueTask(), startupDelay, sleepTimeout, TimeUnit.SECONDS);
}
public InboundRequestLogStore() {
}
public void add(InboundRequestLogRecord logRequest) {
queue.add(logRequest);
}
private class LogRequestSaveQueueTask implements Runnable {
@Override
public void run() {
try {
if (queue.size() > 0) {
List<InboundRequestLogRecord> logRequestList = new ArrayList<>();
InboundRequestLogRecord obj;
while((obj = queue.poll()) != null) {
logRequestList.add(obj);
}
if (!logRequestList.isEmpty()) {
logService.save(logRequestList);
}
}
} catch(Exception e) {
logger.error(e.getMessage(), e);
}
}
}
}
StackTrace
java.lang.NullPointerException: null
at com.my.project.services.log.InboundRequestLogStore$LogRequestSaveQueueTask.run(InboundRequestLogStore.java:71) [classes/:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_131]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_131]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]
-
<context:component-scan base-package="com.my.project" />
-
<bean id="inboundRequestLogStore" class="com.my.project.services.log.InboundRequestLogStore" />
If use DelegatingFilterProxy then I get
SEVERE: Servlet.service() for servlet [appServlet] in context with path [] threw exception
java.lang.NullPointerException
at com.my.project.config.filter.RequestLogFilter.doFilter(RequestLogFilter.java:121)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
web.xml
<filter>
<filter-name>requestLogFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>requestLogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
root-context.xml
<bean id="inboundRequestLogStore" class="com.my.project.services.log.InboundRequestLogStore" />
<bean id="requestLogFilter" class="com.my.project.config.filter.RequestLogFilter" />
Components (marked with bean's id)
@Component("inboundRequestLogStore")
public class InboundRequestLogStore implements InitializingBean {
-
@Component("requestLogFilter")
public class RequestLogFilter implements Filter {
@Configurable on the RequestLogFilter not working.
As a result
ikettu, thank you!
after some attempts I've achieved autowired fields not to be nullable. I've added beans to the root-context.xml
<bean id="requestLogFilter" class="com.my.project.config.filter.RequestLogFilter">
<constructor-arg ref="inboundRequestLogStore"/>
</bean>
<bean id="inboundRequestLogStore" class="com.my.project.service.InboundRequestLogStore">
<constructor-arg ref="logService"/>
</bean>
<bean id="logService" class="com.my.project.service.LogService">
<constructor-arg ref="entityManagerFactory"/>
</bean>
In classes I've created constructors with params like this
private LogServic logService;
public InboundRequestLogStore(LogServic logService) {
this.logService = logService;
} ....
In the LogService
private EntityManagerFactory emf;
public void setEntityManagerFactory(EntityManagerFactory emf) {
this.emf = emf;
}
But when I tried to save my entity to DB nothing has happened. If I tried to flush a batch of inserts and release memory
entityManager.flush();
entityManager.clear();
then NotOpenedTransaction(like this, I can't call to mind) exception has occured
I'm tired of all and have created an interceptor. And all works perfetcly. If anyone can explain what was the problem with the filter please comment.
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- <filter> -->
<!-- <filter-name>requestLogFilter</filter-name> -->
<!-- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> -->
<!-- if set this parameter to true then filter init & destroy methods will be called -->
<!-- <init-param> -->
<!-- <param-name>targetFilterLifecycle</param-name> -->
<!-- <param-value>true</param-value> -->
<!-- </init-param> -->
<!-- </filter> -->
<!-- <filter-mapping> -->
<!-- <filter-name>requestLogFilter</filter-name> -->
<!-- <url-pattern>/*</url-pattern> -->
<!-- </filter-mapping> -->
</web-app>