I observe a very strange behavior of method reference. We have a web app and chain of servlet hierarchy: Servlet A extends Servlet B extends HttpServlet
(let's overlooked why do we need this).
The web app is hosting under Tomcat/Java 8 (web.xml version="3.1" metadata-complete="true"). At my local laptop (Tomcat 8.0.35 or 8.5.15, Java 8 Update 131, OSX) I observe stack overflow for such servlet code:
public class A extends B {
@Override
protected void service(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException {
ServletCommon.servletServiceWrapper(pRequest, pResponse, super::service);
}
}
The stack overflow (see below) looks very suspicious - it doesn't contain class B in the hierarchy at all! Class A calls HttpServlet
directly (Why!? And how this even possible!!!????).
At the same time code with lambda works fine:
public class A extends B {
@Override
protected void service(HttpServletRequest pRequest, HttpServletResponse pResponse) throws ServletException, IOException {
ServletCommon.servletServiceWrapper(pRequest, pResponse, (t, u) -> super.service(t, u));
}
}
The wrapper also contains very simple code:
public class ServletCommon {
@FunctionalInterface
public interface MyBiConsumer<T, U>{
void accept(T t, U u) throws ServletException, IOException ;
}
public static void servletServiceWrapper(HttpServletRequest request, HttpServletResponse response,
MyBiConsumer<HttpServletRequest, HttpServletResponse> pDelegate) throws ServletException, IOException {
pDelegate.accept(request, response);
}
}
Stack trace
java.lang.StackOverflowError
ServletA.lambda$service$0(ServletA.java:19)
ServletCommon.servletServiceWrapper(ServletCommon.java:31)
ServletA.service(ServletA.java:19)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
ServletA.lambda$service$0(ServletA.java:19)
ServletCommon.servletServiceWrapper(ServletCommon.java:31)
ServletA.service(ServletA.java:19)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
...
Any ideas?