在 WebLogic 应用程序运行良好几周后,我突然收到一个异常:
<Oct 25, 2014 9:31:11 PM EDT> <Error> <HTTP> <BEA-101020>
<[ServletContext@60724164[app:whatever3000 module:whatever3000.war path:
spec-version:2.5]] Servlet failed with Exception
java.lang.ExceptionInInitializerError
之后应用程序完全失效,NoClassDefFoundError
直到应用程序服务器重新启动。
完整的堆栈跟踪显示问题的根源是ConcurrentModificationException
在静态初始化程序中。
具体等效/最小化代码如下:
package a;
import b;
public class Whatever {
void doIt()
{
Password p = new Password();
}
}
package b;
public final class Password implements Serializable
{
private static final int PARAM1 = CommonStuff.someStaticMethod();
...
}
import java.util.Properties;
public class CommonStuff
{
private static Properties prp = new Properties();
static {
CommonStuff.load();
}
public static void load()
{
prp.putAll(System.getProperties()); <---FAIL
这是异常的起源:
java.util.ConcurrentModificationException
at java.util.Hashtable$Enumerator.next(Hashtable.java:1017)
at java.util.Hashtable.putAll(Hashtable.java:469)
at b.CommonStuff.load(CommonStuff.java:55)
at b.CommonStuff.<clinit>(CommonStuff.java:77)
at b.Password.<clinit>(Password.java:44)
at a.doIt(Whatever.java:99)
因此,似乎在应用程序运行时的某个时刻,WebLogic 决定从中重新加载类,package b
但是当静态块运行时,它发现Properties
对象已被修改。
我不知道它是被同时调用还是被多次调用。可能该Properties
对象是应用程序第一次加载时创建的原始实例,并且CommonStuff
类的重新加载试图putAll()
再次调用。
如果我这样做会有所帮助:
private static Properties prp = null;
static {
CommonStuff.prp = new Properties();
CommonStuff.load();
}
我不能盲目地尝试,因为它在一家大公司的生产应用程序中。所以我试图了解我哪里出错了,以及如何在半夜重新加载类时对这些变量进行属性初始化。
有任何想法吗?
这可能是 WebLogic ClassLoader 问题吗?