2016-09-01 5 views
2

Мы недавно перешли на Tomcat 8.5.4 (с 8.5.3) и Omnifaces 2.4 (из 2.3), и мы также изменили некоторые вещи в нашем веб-приложении. С тех пор наш веб-приложение не запускается больше, за исключением следующего в журналах:Исправление проблем с инициализацией OmniFaces BeanManager при запуске Tomcat

Exception sending context initialized event to listener instance of class org.omnifaces.ApplicationListener 

java.lang.ExceptionInInitializerError 
at org.omnifaces.ApplicationListener.checkCDIAvailable(ApplicationListener.java:77) 
at org.omnifaces.ApplicationListener.contextInitialized(ApplicationListener.java:61) 
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4716) 
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5178) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152) 
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403) 
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) 
at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
at java.lang.Thread.run(Thread.java:745) 

Caused by: java.lang.IllegalStateException: CDI BeanManager instance is not available in JNDI. 
at org.omnifaces.config.BeanManager.<init>(BeanManager.java:100) 
at org.omnifaces.config.BeanManager.<clinit>(BeanManager.java:49) 
... 11 more 

Caused by: java.lang.IllegalStateException: javax.naming.NamingException: WELD-001300: Unable to locate BeanManager 
at org.omnifaces.util.JNDI.lookup(JNDI.java:95) 
at org.omnifaces.config.BeanManager.<init>(BeanManager.java:96) 
... 12 more 

Caused by: javax.naming.NamingException: WELD-001300: Unable to locate BeanManager 
at org.jboss.weld.resources.ManagerObjectFactory.getObjectInstance(ManagerObjectFactory.java:62) 
at org.apache.naming.factory.FactoryBase.getObjectInstance(FactoryBase.java:94) 
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321) 
at org.apache.naming.NamingContext.lookup(NamingContext.java:840) 
at org.apache.naming.NamingContext.lookup(NamingContext.java:160) 
at org.apache.naming.NamingContext.lookup(NamingContext.java:828) 
at org.apache.naming.NamingContext.lookup(NamingContext.java:160) 
at org.apache.naming.NamingContext.lookup(NamingContext.java:828) 
at org.apache.naming.NamingContext.lookup(NamingContext.java:174) 
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:163) 
at javax.naming.InitialContext.lookup(InitialContext.java:417) 
at org.omnifaces.util.JNDI.lookup(JNDI.java:90) 
... 13 more 

Exception sending context initialized event to listener instance of class com.sun.faces.config.ConfigureListener 

java.lang.RuntimeException: java.lang.NoClassDefFoundError: Could not initialize class org.omnifaces.config.BeanManager 
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:292) 
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4714) 
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5178) 
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152) 
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403) 
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) 
at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
at java.lang.Thread.run(Thread.java:745) 

Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.omnifaces.config.BeanManager 
at org.omnifaces.util.Beans.getManager(Beans.java:88) 
at org.omnifaces.util.Beans.getReference(Beans.java:113) 
at org.omnifaces.application.OmniApplication.<init>(OmniApplication.java:70) 
at org.omnifaces.application.OmniApplicationFactory.createOmniApplication(OmniApplicationFactory.java:89) 
at org.omnifaces.application.OmniApplicationFactory.getApplication(OmniApplicationFactory.java:54) 
at com.sun.faces.application.InjectionApplicationFactory.getApplication(InjectionApplicationFactory.java:93) 
at com.sun.faces.config.InitFacesContext.getApplication(InitFacesContext.java:142) 
at com.sun.faces.lifecycle.ClientWindowFactoryImpl.<init>(ClientWindowFactoryImpl.java:62) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
at java.lang.Class.newInstance(Class.java:442) 
at javax.faces.FactoryFinderInstance.getImplGivenPreviousImpl(FactoryFinderInstance.java:405) 
at javax.faces.FactoryFinderInstance.getImplementationInstance(FactoryFinderInstance.java:251) 
at javax.faces.FactoryFinderInstance.getFactory(FactoryFinderInstance.java:543) 
at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:283) 
at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:328) 
at com.sun.faces.config.processor.FactoryConfigProcessor.process(FactoryConfigProcessor.java:236) 
at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:439) 
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:227) 

Наша конфигурация:

  • Tomcat 8.5.4
  • CDI Weld 2.3.5. Окончательный
  • JSF 2.2.13
  • Omnifaces 2,4
  • Primefaces 6,0
  • Пустой beans.xml файл в WEB-INF
  • BeanManager запись ресурса в контексте нашего корневого веб-приложения
  • Tomcat запускается наш Java код (встроенный использования).

Запись ресурса BeanManager:

<Resource name="BeanManager" 
      auth="Container" 
      type="javax.enterprise.inject.spi.BeanManager" 
      factory="org.jboss.weld.resources.ManagerObjectFactory"/> 

Мы переехали обратно в Tomcat 8.5.3 и omnifaces 2.3 и пробовал различные комбинации компонентов версии (8.5.3 с 2,4, 8,5 .4 с 2.3 и т. Д.), Чтобы определить основную причину проблемы, но безрезультатно.

Наконец, мы подозреваем проблему гоночного состояния между инициализацией всех этих компонентов (Tomcat, Weld, Onmnifaces, ...).

В последнем случае я удалил запись ресурса BeanManager из XML-файла контекста.

Удалены из контекста:

<Resource name="BeanManager" 
      auth="Container" 
      type="javax.enterprise.inject.spi.BeanManager" 
      factory="org.jboss.weld.resources.ManagerObjectFactory"/> 

И это устранило проблему.

Я имел взгляд к журналам изменения в Tomcat 8.5.4, и я мог бы найти это изменение:

Не пытайтесь запустить веб-ресурсов во время фазы инициализации веб-приложения, так как веб-приложение не является полностью настроен в этой точке, и веб-ресурсы могут быть неправильно настроены. (markt)

Я не знаю, была ли эта фаза инициализации этого веб-приложения в журнале изменений Tomcat связана с проблемой, которую мы имели. Причина, по которой удаление ресурса BeanManager из контекста устраняет проблему, остается неясной.

Любая идея?

+0

Я могу объяснить необходимость (un) в OmniFaces 2.4, но можете ли вы попробовать OmniFaces 2.5-SNAPSHOT? Практически значительная часть инициализации CDI была переработана/улучшена в этой версии: https://github.com/omnifaces/omnifaces/issues/281, и она отлично работает для меня. – BalusC

+0

С версией моментальных снимков omnifaces-2.5, построенной 31 августа, наше веб-приложение правильно запускается, независимо от того, добавлена ​​ли запись или нет в веб-контексте. Тем не менее, мне хотелось бы узнать причину, по которой нам пришлось удалить запись с версией 2.4: –

+0

Хорошо, можете ли вы указать основную причину исключения? – BalusC

ответ

4

javax.naming.NamingException: WELD-001300: Невозможно найти BeanManager

В основном это означает, что определение ресурса BeanManager JNDI (как определено в context.xml) найдено, но что конкретный экземпляр BeanManager за JNDI ресурс еще не создан.

Это действительно соответствует described change в Tomcat 8.5.4.

Не пытайтесь запустить веб-ресурсы во время фазы инициализации веб-приложения, так как веб-приложение не настроено в данный момент, и веб-ресурсы могут быть неправильно настроены. (markt)

Я не могу рассказать о причинах Mark Thomas для этого решения, и за ним также нет ссылки на проблему. Я предполагаю, что он пытался избежать путаного поведения, вызванного прерывисто ломающимися развертываниями, вызванными потенциальными проблемами порядка инициализации. Это, наверное, хорошо, но я думаю, что Марк фактически упустил возможность определить порядок инициализации через <ordering> элемент в web.xml и web-fragment.xml файлах. Я действительно помню, что Tomcat никогда не уважал это как порядок наведения @WebListener - номинированных или программно созданных экземпляров (он, однако, делает это как <listener> объявленных экземпляров). Возможно, Марк должен лучше зафиксировать эту часть вместо того, чтобы полностью отключить JNDI на этапе инициализации.

Что касается изменения OmniFaces 2.4, то согласно issue 243 эта версия добавила резервную копию атрибута контекста сервлета, специфичного для Weld. Это будет использоваться, если ресурс JNDI не существует, а Weld используется как реализация CDI. А именно, Weld внутренне хранит экземпляр BeanManager как атрибут контекста сервлета, поэтому OmniFaces может просто захватить его без необходимости использования JNDI. Это означает, что context.xml больше не требуется. В Tomcat 8.5.4 вы также должны удалить context.xml, так как OmniFaces 2.4 все еще пытается проверить ресурс JNDI, который в конечном итоге вызовет исключение, потому что случай BeanManager неожиданно недоступен вследствие изменения Tomcat 8.5.4.

В OmniFaces 2.5 инициализация CDI была переработана и улучшена согласно issue 281, которая описывает миграцию CDI 1.0 на 1.1. OmniFaces больше не использует JNDI для проверки BeanManager. OmniFaces теперь будет использовать API-интерфейс CDI 1.1 CDI.

BeanManager beanManager = CDI.current().getBeanManager(); 

Это работает независимо от конфигурации/инициализации JNDI.

OmniFaces 2.5 еще не окончательный, но 2.5-RC1 доступен в центральном квартале Maven по состоянию на вчера.

+1

Все больше причин «просто» использовать контейнеры JEE и не пытаться включить все в простой контейнер сервлетов. – Kukeltje

+0

Спасибо, BalusC за ваш анализ. Я буду использовать Omnifaces 2.4 (это отличное дополнение к JSF) и удалить ресурс из контекста. Я согласен с вами в Kukeltje, но иногда нам приходится поддерживать старый код или обновлять некоторые части обычного контейнера JEE :) –

+0

Добро пожаловать. – BalusC

Смежные вопросы