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 の問題でしょうか?