一個奇怪的問題: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,有知道的指點一些。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章