После того, как приложение 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?