标签 stackoverflowerror 下的文章

tomcat 7 servlet annotation StackOverflowError

今天部署代码的时候, 遇到如下的出错:

SEVERE: Error waiting for multi-thread deployment of WAR files to complete
java.util.concurrent.ExecutionException: java.lang.StackOverflowError
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252)
    at java.util.concurrent.FutureTask.get(FutureTask.java:111)
    at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:751)
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:471)
    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1412)
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:312)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:401)
    at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:346)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1145)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:782)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.StackOverflowError
    at java.util.Random.nextInt(Random.java:239)
    at sun.misc.Hashing.randomHashSeed(Hashing.java:254)
    at java.util.HashMap.<init>(HashMap.java:255)
    at java.util.HashMap.<init>(HashMap.java:305)
    at java.util.HashSet.<init>(HashSet.java:103)
    at org.apache.catalina.startup.ContextConfig.populateSCIsForCacheEntry(ContextConfig.java:2169)
    at org.apache.catalina.startup.ContextConfig.populateSCIsForCacheEntry(ContextConfig.java:2188)
    at org.apache.catalina.startup.ContextConfig.populateSCIsForCacheEntry(ContextConfig.java:2188)
    at org.apache.catalina.startup.ContextConfig.populateSCIsForCacheEntry(ContextConfig.java:2188)
    at org.apache.catalina.startup.ContextConfig.populateSCIsForCacheEntry(ContextConfig.java:2188)
    at org.apache.catalina.startup.ContextConfig.populateSCIsForCacheEntry(ContextConfig.java:2188)
    at org.apache.catalina.startup.ContextConfig.populateSCIsForCacheEntry(ContextConfig.java:2188)
    at org.apache.catalina.startup.ContextConfig.populateSCIsForCacheEntry(ContextConfig.java:2188)
    at org.apache.catalina.startup.ContextConfig.populateSCIsForCacheEntry(ContextConfig.java:2188)
    at org.apache.catalina.startup.ContextConfig.populateSCIsForCacheEntry(ContextConfig.java:2188)
    ......

上面出错stack递归, 导致溢出. 这段代码应该发生在Servlet 容器启动的时候自动扫描 servlet 的 annotation时.
google 一下, 发现上述的情况在下面这个bug 中有描述:
https://issues.apache.org/bugzilla/show_bug.cgi?id=53871, RESOLVED FIXED Version: 7.0.35
上面出错的代码所用的tomcat 版本为: Version 7.0.27

那么换做 tomcat 7.0.40实验一下, 报出如下的出错内容 (出错的error message 被优化, 明确指出出错的原因):

Caused by: java.lang.IllegalStateException: Unable to complete the scan for annotations for web application [] due to a StackOverflowError. Possible root causes
 include a too low setting for -Xss and illegal cyclic inheritance dependencies. The class hierarchy being processed was 
 [org.jaxen.util.AncestorOrSelfAxisIterator->org.jaxen.util.AncestorAxisIterator->org.jaxen.util.AncestorOrSelfAxisIterator]
        at org.apache.catalina.startup.ContextConfig.checkHandlesTypes(ContextConfig.java:2179)

问题出在2个Class的依赖关系, 在一个包中, A 是B的之类, 另外一个包中, B 却是A的之类:
jaxen-1.1.6.jar 包中的依赖关系

public class org.jaxen.util.AncestorOrSelfAxisIterator implements java.util.Iterator
public class org.jaxen.util.AncestorAxisIterator extends org.jaxen.util.AncestorOrSelfAxisIterator

jaxen-core-1.0-FCS.jar 包中的依赖关系:

public class org.jaxen.util.AncestorOrSelfAxisIterator extends org.jaxen.util.AncestorAxisIterator
public class org.jaxen.util.AncestorAxisIterator extends org.jaxen.util.StackedIterator

解决方案: 在pom.xml 中找到2个jar, 把其中一个 exclude 掉, 去试试, 是不是好了

有人也遇到同样的问题:
http://hongjiang.info/2014/06/