NullPointerException occurred at HttpServletRequestImpl.getLocalAddr() in JBoss EAP 7.1.2
Environment
- Red Hat JBoss Enterprise Application Platform (EAP) 7.1.2
Issue
The following NullPointerException occurred when calling javax.servlet .ServletRequest#getLocalAddr() or javax.servlet .http.HttpServletRequest#getLocalAddr() in an application:
UT005023: Exception handling request to /example.jsp: org.apache.jasper.JasperException: java.lang.NullPointerException
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:473)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:403)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:347)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.jsp.JspFileHandler.handleRequest(JspFileHandler.java:32)
at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:64)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:330)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:812)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at io.undertow.servlet.spec.HttpServletRequestImpl.getLocalAddr(HttpServletRequestImpl.java:937)
at org.apache.jsp.example_jsp._jspService(example_jsp.java:151)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:433)
... 43 more
Resolution
This is a bug reported as Content from issues.jboss.org is not included.JBEAP-14689 and this has been fixed in JBoss EAP 7.1 CP3 (EAP 7.1.3).
This issue happens when your application calls Content from docs.oracle.com is not included.ServletRequest#getLocalAddr() or HttpServletRequest.getLocalAddr() in the following conditions:
- The request contains "
X-Forwarded-Host" header and you configureproxy-address-forwarding="true"onhttp-listener/https-listener - The request come through
ajp-listener(regardless of having "X-Forwarded-Host" header in the request)
Until the above JIRA is fixed, this issue can be workaround by either of the followings:
-
Using
io.undertow.server.handlers.LocalNameResolvingHandler('resolve-local-name' in expression-filter):This can avoid this NPE issue unless the destination address (Host header in AJP request or the X-Forwarded-Host header in HTTP request) is really unresolved. However, using this handler can impact performance. If a DNS server is unresponsive this could potentially add seconds to the request processing time.
You can enable this by the following CLI:/subsystem=undertow/configuration=filter/expression-filter=resolve-local-name-filter:add(expression=resolve-local-name) /subsystem=undertow/server=default-server/host=default-host/filter-ref=resolve-local-name-filter:add()then
standalone.xmlconfiguration will be changed like the following:<subsystem xmlns="urn:jboss:domain:undertow:4.0"> ... <server name="default-server"> ... <host name="default-host" alias="localhost"> ... <filter-ref name="resolve-local-name-filter"/> <!-- add this --> </host> </server> ... <filters> ...(snip)... <expression-filter name="resolve-local-name-filter" expression="resolve-local-name"/> <!-- add this --> </filters> </subsystem> -
Using a custom servlet filter with
HttpServletRequestWrapperto overridegetLocalAddr().For example:
@WebFilter("/*")
public class ExampleFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
if (!(req instanceof HttpServletRequest)) {
chain.doFilter(req, res);
return;
}
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequestWrapper wrappedRequest = new HttpServletRequestWrapper(request) {
@Override
public String getLocalAddr() {
try {
return request.getLocalAddr();
} catch(NullPointerException npe) {
// When NPE happnes, just return request.getLocalName() instread
return request.getLocalName();
// If you want to resolve address, you can use the followin code. But this can impact performance.
// If a DNS server is unresponsive this could potentially add seconds to the request processing time.
// try {
// return InetAddress.getByName(request.getLocalName()).getHostAddress();
// } catch(Exception e){
// // Can not be resolved. Just return request.getLocalName() instread
// return request.getLocalName();
// }
}
}
};
chain.doFilter(wrappedRequest, res);
}
...
}
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.