java.lang.IllegalStateException 正在重新加载 Tomcat

java.lang.IllegalStateException while reloading Tomcat

我正在 Spring 使用 Hibernate 应用程序,它工作正常,但在启动或重新加载 tomcat 服务器时,我收到 java.lang.IllegalStateException 异常。

任何人都可以解释为什么会出现此异常以及如何解决它??

INFO: Illegal access: this web application instance has been stopped already. Could not load java.net.BindException. 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:1600) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559) at com.mysql.jdbc.SQLError.createLinkFailureMessageBasedOnHeuristics(SQLError.java:1220) at com.mysql.jdbc.exceptions.jdbc4.CommunicationsException.<init>(CommunicationsException.java:57) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074) at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3270) at com.mysql.jdbc.MysqlIO.quit(MysqlIO.java:1659) at com.mysql.jdbc.ConnectionImpl.realClose(ConnectionImpl.java:4296) at com.mysql.jdbc.ConnectionImpl.cleanup(ConnectionImpl.java:1265) at com.mysql.jdbc.ConnectionImpl.finalize(ConnectionImpl.java:2667) at java.lang.System.invokeFinalize(Unknown Source) at java.lang.ref.Finalizer.runFinalizer(Unknown Source) at java.lang.ref.Finalizer.access0(Unknown Source)

问题出在服务器缓存上。按照以下步骤解决此问题

  1. 在您的 tomcat 的根目录下找到名为 "work" 的目录
  2. 彻底删除
  3. 重启服务器

问题将得到解决。

注意:如果您在 linux 机器上默认安装 tomcat,则必须删除文件夹 /var/cache/tomcat7/Catalina

我想给你几个选择。你可以试试。任何选项都可以满足您的需求。

  1. Restart your tomcat and apache server因为长期使用, 它会保留您的应用程序的旧版本。
  2. 清理您的 tomcat temp 目录和 restart
  3. 如错误所述,

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.

真正原因可能是此时您处于调试模式,没有清除运行ning线程。所以删除你的断点和运行它不调试

  1. 如果您的代码包含任何类型的未正确终止的线程,则可能会发生此类错误。 如果你有init()方法而没有destroy()方法,则可能会出现此类错误。详情可关注link - http://www.javaspecialists.eu/archive/Issue056.html

  2. 如果 webapp has stopped, or is stopping,这意味着 .war 文件或 WEB-INF/web.xml 时间戳已更改,并且 webapp 可能正在重新加载。请检查时间戳是否正确。

  3. 要关闭它,在上下文定义中设置 reloadable="false" 你的应用程序。可能是 tomcat 的 server.xml。 详细解决方案: reloadable Context的tomcat的server.xml设置为false。 例如:

Context path="/expert" docBase="expert" debug="0" reloadable ="false"/>

解决方法很简单,只要把tomcat的server.xml放在reloadable = "true" into false就行了,但是这样做就失去了热部署的优势,而且对于开发不是很方便,干脆改还是不改。这个错误无关紧要。

误差原理:

原因是因为tomcat重启,因为之前的tomcat线程还没有完全关闭,重启tomcat会报这个异常,不过这个不影响正常使用,只是跳变态烦人。用过hibernate,spring或者其他大型组件,当一个WEB应用系统有很多class,

如果您打开 Tomcat reloadable = true,那么只要相关文件发生变化,Tomcat 就会停止网络应用程序并释放内存,然后重新加载网络应用程序。这可能是一个巨大的工程。所以我们总觉得如果只有某个class的重载函数,会大大满足我们的调试器。

UPDATE: For code related issue

首先,我想告诉你,我已经为你提供了tomcat基础的一些解决方案。现在我想给大家一个代码基础的解决方案。你能用这个问题交叉检查你的代码吗?请关注URL.

  1. http://www.coderanch.com/t/660126/Wiki/Illegal-State-Exception

UPDATE: For MySQL related issue

  1. 有 2 个问题。

    • 此 Web 应用程序实例已停止。无法加载 java.net.BindException.

    • 此 Web 应用程序实例已 已停止 already.Could 未加载 com.mysql.jdbc.

这是因为MySQLJDBC驱动放在WEB-INF/lib目录下的应用程序,在重新发布其加载两次,只要能复制到%TOMCAT_HOME%/lib即可解决问题。 我们可以解决这两个异常 MySQL 驱动程序从 WEB-INF/lib 文件夹移动到 %TOMCAT_HOME%/lib.

  1. 我怀疑这可能是在 Web 应用程序重新启动后发生的,它会在短时间内停止运行。然后代码中的某些 finalize() 方法可能试图进行一些清理,为时已晚。我不能说这是否在您的代码或 MySQL 驱动程序中。您绝对应该一次在一个目录中只有一个版本的 jar。你可能想将它升级到 latest(现在是 5.1.38),以防某些可能影响你的问题被修复。(9 号是从@WhiteFang34 复制的)

相关 link 9: tomcat 6.0.24 Exception: Could not load com.mysql.jdbc.SQLError

问题可能是一个简单的 SQL 错误。 tThe

java.lang.IllegalStateException

表示对象或class在未准备好被调用时被调用。堆栈底部的这些错误

at java.lang.ref.Finalizer.runFinalizer(Unknown Source)
at java.lang.ref.Finalizer.access0(Unknown Source)
at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)

看起来他们来自 Java Garbage Collector 试图清理 MySQL Object Pointers 在重新启动期间暂时未被引用。在我看来,您这里的错误只是几个 MySQL 对象指针在 GC 调用它们的 finalize 方法然后暂停应用程序以尝试清理对象时在执行过程中停止。 (导致失败并抛出此异常) 这个错误很可能是无害的,可以通过添加

来修复
JNI_DestroyJavaVM();

您的主线程将在关闭时执行。

我认为这个问题的根本原因是某些东西正在泄漏 JDBC Connection 个对象。

这些对象实际上是 com.mysql.jdbc.ConnectionImpl 的实例...这是 class 和 finalize()。通常,对象终结会清理泄漏的连接。在这种情况下,看起来事件的顺序如下:

  • GC 在 webapp 关闭后运行
  • 发现一个 ConnectionImpl 对象不可访问
  • 对象的 finalize() 方法试图关闭 MySQL 数据库连接...这需要向服务器发送消息
  • 当消息发送由于某种原因失败时,通信级代码尝试通过调用 com.mysql.jdbc.SQLError.createCommunicationsException
  • 创建异常
  • 试图以反射方式创建异常...

最后一步失败,因为它正在尝试为已关闭的网络应用程序使用网络应用程序的 classloader。显然,这是通过旨在帮助程序员诊断未完全关闭的 Web 应用程序的检查来检测的。

最好的解决办法是追踪 Connection 泄漏的来源并修复它。如果 Connection 对象没有泄漏,那么它们将在 webapp 的 classloader 仍处于活动状态时关闭。

或者,您可以简单地关闭检查,如@Skywalker 的回答中所述。