Class 定义随时间从 jvm 中消失(NoClassDefFound)
Class definition disapear from jvm over time (NoClassDefFound)
我们这里有一个非常奇怪的问题。
jvm:尝试了 1.7.0_55-b13 和 1.7.0_75-b13
tomcat : 7.0.56
os : Ubuntu 12.04.5 LTS(64 位)(3.5.0-23-通用)
将 tomcat 与使用 spring 构建的大型应用程序结合使用。
在我们的一个生产环境中,我们有时 "NoClassDefFound" 总是具有相同的堆栈跟踪。
它只会在一段时间后发生,并且可以通过特定的工作流程进行测试。但是,标记为 "not found" 的 class 在那里(在 WEB-INF/lib 的一个 jar 中)并且在问题出现和异常开始抛出之前被多次使用:提到的特定工作流程以上可以在白天多次成功执行。不知何故,工作流停止工作并开始抛出 NoClassDefFound 异常。
似乎 class 被加载,使用,然后超时,从 jvm 中消失。
jvm 使用以下参数运行:
-XX:+UseConcMarkSweepGC
-Xmx6900m
-Xms2000m
-XX:MaxPermSize=900m
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:NewRatio=1
-XX:TargetSurvivorRatio=75
-XX:SurvivorRatio=8
-XX:+AggressiveOpts
-XX:ReservedCodeCacheSize=256m
-Djava.util.logging.config.file=/var/lib/tomcat7/conf/logging.properties
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.awt.headless=true
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=2037
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=10.71.1.112
-Dcom.sun.management.jmxremote.password.file=/etc/tomcat7/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=/etc/tomcat7/jmxremote.access
-Djava.net.preferIPv4Stack=true
-Djava.endorsed.dirs=/usr/share/tomcat7/endorsed
-classpath /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar
-Dcatalina.base=/var/lib/tomcat7 -Dcatalina.home=/usr/share/tomcat7
-Djava.io.tmpdir=/tmp/tomcat7-tomcat7-tmp org.apache.catalina.startup.Bootstrap start
有人知道类似的问题吗?
我纠正了问题,这里我 post 解决方案。也许它会在某个时候以某种方式帮助某人 :)
问题不是我们一开始想的:Class 定义并没有从 class 加载程序中消失,而是一开始没有初始化(启动)。
这是导致错误的工作流程:当 tomcat 上次停止时,它将其会话序列化为一个文件(根据默认会话存储机制)。
再次启动应用程序时,tomcat 未能重新加载其会话,因为在初始化 class 以反序列化其实例时出现 "ExceptionInInitializerError"。
然后,对 class 的所有后续调用(未正确初始化)产生了我们在问题中看到的堆栈跟踪 (NoClassDefFound)。
ExceptionInInitializerError 的原因是序列化的 class 试图静态调用 spring 上下文(当时未初始化的上下文,然后产生了导致 ExceptionInInitializer 的 NullPointerException)。
我们这里有一个非常奇怪的问题。
jvm:尝试了 1.7.0_55-b13 和 1.7.0_75-b13
tomcat : 7.0.56
os : Ubuntu 12.04.5 LTS(64 位)(3.5.0-23-通用)
将 tomcat 与使用 spring 构建的大型应用程序结合使用。
在我们的一个生产环境中,我们有时 "NoClassDefFound" 总是具有相同的堆栈跟踪。
它只会在一段时间后发生,并且可以通过特定的工作流程进行测试。但是,标记为 "not found" 的 class 在那里(在 WEB-INF/lib 的一个 jar 中)并且在问题出现和异常开始抛出之前被多次使用:提到的特定工作流程以上可以在白天多次成功执行。不知何故,工作流停止工作并开始抛出 NoClassDefFound 异常。
似乎 class 被加载,使用,然后超时,从 jvm 中消失。
jvm 使用以下参数运行:
-XX:+UseConcMarkSweepGC
-Xmx6900m
-Xms2000m
-XX:MaxPermSize=900m
-XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled
-XX:NewRatio=1
-XX:TargetSurvivorRatio=75
-XX:SurvivorRatio=8
-XX:+AggressiveOpts
-XX:ReservedCodeCacheSize=256m
-Djava.util.logging.config.file=/var/lib/tomcat7/conf/logging.properties
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.awt.headless=true
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=2037
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=10.71.1.112
-Dcom.sun.management.jmxremote.password.file=/etc/tomcat7/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=/etc/tomcat7/jmxremote.access
-Djava.net.preferIPv4Stack=true
-Djava.endorsed.dirs=/usr/share/tomcat7/endorsed
-classpath /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar
-Dcatalina.base=/var/lib/tomcat7 -Dcatalina.home=/usr/share/tomcat7
-Djava.io.tmpdir=/tmp/tomcat7-tomcat7-tmp org.apache.catalina.startup.Bootstrap start
有人知道类似的问题吗?
我纠正了问题,这里我 post 解决方案。也许它会在某个时候以某种方式帮助某人 :)
问题不是我们一开始想的:Class 定义并没有从 class 加载程序中消失,而是一开始没有初始化(启动)。
这是导致错误的工作流程:当 tomcat 上次停止时,它将其会话序列化为一个文件(根据默认会话存储机制)。
再次启动应用程序时,tomcat 未能重新加载其会话,因为在初始化 class 以反序列化其实例时出现 "ExceptionInInitializerError"。
然后,对 class 的所有后续调用(未正确初始化)产生了我们在问题中看到的堆栈跟踪 (NoClassDefFound)。
ExceptionInInitializerError 的原因是序列化的 class 试图静态调用 spring 上下文(当时未初始化的上下文,然后产生了导致 ExceptionInInitializer 的 NullPointerException)。