java.lang.IllegalStateException。WebClassLoader 可能出错

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11842927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 06:36:28  来源:igfitidea点击:

java.lang.IllegalStateException. Possible error with WebClassLoader

javaspringexceptionsoap

提问by Stugal

I'm developing a web application with Spring and I have this strange error. I can't figure out where it comes from, I've been google'ing hard and found nothing so far.

我正在使用 Spring 开发 Web 应用程序,但遇到了这个奇怪的错误。我不知道它是从哪里来的,我一直在用谷歌搜索,到目前为止一无所获。

In the project I'm using: MongoDB, Spring, WSS4J (X.509 security headers for soap), Apache CXF. I've been trying to discover whether there is something that causes this error, any particular action, behaviour, condition something, but I found nothing so far, sometimes it happens after 3 min of running sometimes after 3h or not at all, any clues and hints appreciated.

在我使用的项目中:MongoDB、Spring、WSS4J(SOAP 的 X.509 安全标头)、Apache CXF。我一直在试图发现是否有什么原因导致了这个错误,任何特定的动作、行为、条件,但到目前为止我什么也没发现,有时它在运行 3 分钟后发生,有时在 3 小时后发生或根本没有,任何线索和提示表示赞赏。

INFO: Illegal access: this web application instance has been stopped already.  Could not load net.sf.ehcache.store.disk.Segment.  The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1597)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
    at net.sf.ehcache.store.disk.Segment$HashIterator.<init>(Segment.java:988)
    at net.sf.ehcache.store.disk.Segment.hashIterator(Segment.java:936)
    at net.sf.ehcache.store.disk.DiskStore$HashIterator.<init>(DiskStore.java:1038)
    at net.sf.ehcache.store.disk.DiskStore$KeyIterator.<init>(DiskStore.java:1111)
    at net.sf.ehcache.store.disk.DiskStore$KeyIterator.<init>(DiskStore.java:1111)
    at net.sf.ehcache.store.disk.DiskStore$KeySet.iterator(DiskStore.java:949)
    at net.sf.ehcache.store.disk.DiskStorageFactory$DiskExpiryTask.run(DiskStorageFactory.java:838)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)`

回答by user1516873

It means the ehcache thread is trying to interact with the application after the application has been stopped or redeployed. It happens only when ehcache reach limits you have in ehcache.xml and trying to overflow to disk.

这意味着 ehcache 线程在应用程序停止或重新部署后试图与应用程序交互。只有当 ehcache 达到您在 ehcache.xml 中的限制并试图溢出到磁盘时才会发生这种情况。

Look at tomcat logs for warnings when stop your application:

停止应用程序时查看 tomcat 日志以获取警告:

SEVERE: The web application [/APP] appears to have started a thread named [Ehcache_Worker-1] but has failed to stop it. This is very likely to create a memory leak

严重:Web 应用程序 [/APP] 似乎已启动名为 [Ehcache_Worker-1] 的线程,但未能将其停止。这很可能造成内存泄漏

If find something like this, you should stop ecache properly in your ServletContextListener:

如果发现这样的事情,你应该在你的 ServletContextListener 中正确地停止 ecache:

public void contextDestroyed(ServletContextEvent servletContextEvent){
      CacheManager.getInstance().shutdown();
}

maybe with 1 sec sleep after that, to be sure ehcache is stopped.

之后可能会休眠 1 秒,以确保 ehcache 已停止。

As mentioned in http://ehcache.org/documentation/faq

http://ehcache.org/documentation/faq 所述

If the JVM keeps running after you stop using Ehcache, you should call CacheManager.getInstance().shutdown() so that the threads are stopped and cache memory is released back to the JVM. Calling shutdown also insures that your persistent disk stores get written to disk in a consistent state and will be usable the next time they are used. If the CacheManager does not get shut down, it should not be a problem. There is a shutdown hook which calls the shutdown on JVM exit.

如果在您停止使用 Ehcache 后 JVM 继续运行,您应该调用 CacheManager.getInstance().shutdown() 以便停止线程并将缓存内存释放回 JVM。调用 shutdown 还可以确保您的永久性磁盘存储以一致的状态写入磁盘,并在下次使用时可用。如果 CacheManager 没有被关闭,那应该不是问题。有一个关闭钩子,它在 JVM 退出时调用关闭。

Or you can set property overflowToDisk="false"in ehcache.xml or restart tomcat every time you deploy apllication.

或者你可以overflowToDisk="false"在 ehcache.xml 中设置属性或在每次部署应用程序时重新启动 tomcat。