Приложение Java Spring, работающее на одной системе, умирающее на почти идентичной
Вступление
Я использую стороннее приложение Java Spring на RHEL, которое отказывается работать на машинах, клонированных из определенного шаблона RHEL 6.5. Он просто умирает при запуске с поддельным исключением (см. Ниже).
Версии рассматриваемого программного обеспечения:
RHEL 6.5
Tomcat 7.0.41 (rolled our own, almost vanilla)
Spring 3.1.4.RELEASE (shipped with application)
java version "1.7.0_65"
OpenJDK Runtime Environment (rhel-2.5.1.2.el6_5-x86_64 u65-b17)
OpenJDK 64-Bit Server VM (build 24.65-b04, mixed mode)
SELinux Status: Permissive
Я изменил имена классов, чтобы защитить невинных, я очень сомневаюсь, что реальное программное обеспечение имеет большое значение.
Копирование tomcat и каталога экземпляра из сломанной коробки на мой рабочий стол Linux, как есть, и просто запуск его работает.
Несмотря на то, что описываемая мной установка считается тестовой средой, у меня возникла эта проблема на нашем компьютере, которую я должен был установить с DVD, чтобы проблема исчезла. Упомянутая установка является той, с которой я столкнулся с проблемой во время разработки модуля кукол, и сумел сохранить и воспроизвести эту проблему в.
Настроить
БД, используемые приложением, хранятся локально (h2) и устанавливаются в Tomcat server.xml
,
2 шаблона RHEL 6.5, оба настроены для бродяги.
- Сломанный шаблон: минимальная установка прямо с DVD. Шаги ручной настройки, предпринятые для настройки шаблона для автоподписей марионеток, и шаги по проверке контрольного списка шаблонов.
- Рабочий шаблон: минимальная настройка Kickstart с DVD, настройка Vagrant/VirtualBox через скрипты Shells (делается с
packer
)
1 коробка из каждого шаблона настраивается через vagrant
, оба применяют один и тот же каталог кукол от нашего мастера кукол.
проблема
Приложение умирает при запуске в сломанном шаблоне с этим исключением:
[17.09.2014 19:34:00,290] ERROR ContextLoader ( 318) | Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'soaFormFolderService' defined in file [/var/www/apps/content/tomcat/afs-forms/webapps/formserver/WEB-INF/classes/com/aforms2web/afs/formserver/service/
SoaFormFolderService.class]: Instantiation of bean failed; nested exception is java.lang.ExceptionInInitializerError
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:943)
[...]
Caused by: java.lang.ExceptionInInitializerError
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:990)
... 26 more
Caused by: java.lang.NullPointerException
at com.corp.Application.getMessageSource(Application.java:234)
at com.corp.FooService.<clinit>(FooService.java:23)
... 33 more
Рассматриваемый код выглядит так:
com.corp.FooService
@Service
public class FooService
{
protected static MessageSource messageSource = Application.getInstance().getMessageSource();
com.corp.Application
public class Application
{
private static Application instance = null;
public static Application getInstance()
{
if (instance == null) {
instance = new Application();
}
return instance;
}
[...]
public MessageSource getMessageSource()
{
return ((MessageSource)this.applicationContext.getBean("messageSource", MessageSource.class));
}
Работает безотказно во второй коробке.
Что может вызвать это?
Статус расследования
разный стиль yum list installed
выход:
--- pkgs.broken
+++ pkgs
-b43-openfwwf.noarch-5.2-4.el6
-dkms.noarch-2.2.0.3-25.el6
-efibootmgr.x86_64-0.5.4-11.el6
+gcc-c++.x86_64-4.4.7-4.el6
-kernel-devel.x86_64-2.6.32-431.23.3.el6
+kernel-devel.x86_64-2.6.32-431.el6
-kernel.x86_64-2.6.32-431.23.3.el6
+libstdc++-devel.x86_64-4.4.7-4.el6
-puppet.noarch-3.7.0-1.el6
+puppet.noarch-3.7.1-1.el6
Я сравнил системы с rsync (из рабочей):
rsync \
--checksum -ani \
--exclude log \
--exclude /vagrant \
--exclude /root \
--exclude /proc \
--exclude /sys \
--exclude /selinux \
--exclude /dev \
--exclude /lib/modules \
--exclude /usr/src \
--exclude /boot \
--delete / \
root@broken:/ \
| grep -ve "^." \
| grep -vEie "puppet|vbox|virtualbox|var/lib/yum|/var/run|sss|var/lib/rpm|logs"
Смотрите результаты здесь: http://paste.ubuntu.com/8367930/
Я не могу понять, какие из появившихся изменений могут повлиять на приложение Java Spring.
редактировать: взгляд на добавленный код.
1 ответ
Вы перепутали статический контекст и контекст времени выполнения: метод getMessageSource вызывается во время этой инициализации статических переменных. Но после этого инициализируется applicationContext. Вот почему вы получаете NPE — applicationContext еще не инициализирован.