一个奇怪的问题:tomcat 栈溢出 StackOverflowError错误

一个栈溢出错误:

ava.lang.StackOverflowError
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at 

   >>>>>>>>>>>>>>>>>>> 中间省略几百行同样的内容 <<<<<<<<<<<<<<<<<<<<<<< 
org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.findNext(ApplicationHttpRequest.java:996)
    at org.apache.catalina.core.ApplicationHttpRequest$AttributeNamesEnumerator.hasMoreElements(ApplicationHttpRequest.java:971)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:873)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:64)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)

tomcat版本是8.5.38版本,spring是4.2.6.RELEASE,出错的代码也找到了:
DispatcherServlet:

protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
        if (logger.isDebugEnabled()) {
            String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";
            logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +
                    " processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]");
        }

        // Keep a snapshot of the request attributes in case of an include,
        // to be able to restore the original attributes after the include.
        Map<String, Object> attributesSnapshot = null;
        if (WebUtils.isIncludeRequest(request)) {
            attributesSnapshot = new HashMap<String, Object>();
            Enumeration<?> attrNames = request.getAttributeNames();
            while (attrNames.hasMoreElements()) { //这个地方死循环了
                String attrName = (String) attrNames.nextElement();
                if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {
                    attributesSnapshot.put(attrName, request.getAttribute(attrName));
                }
            }
        }
        .....
}

ApplicationHttpRequest中的内部类AttributeNamesEnumerator:

@Override
        public boolean hasMoreElements() {
            return ((pos != last) || (next != null)
                    || ((next = findNext()) != null));
        }

        protected String findNext() {
            String result = null;
            while ((result == null) && (parentEnumeration.hasMoreElements())) {
                String current = parentEnumeration.nextElement();
                if (!isSpecial(current)) {
                    result = current;
                }
            }
            return result;
        }

从错误日志上来看,先调用hasMoreElements,再调用findNext, 以此为循环,直到栈溢出。

不知道怎么回事,只找到一篇tomcat的issue,有知道的指点一些。

相关推荐