2015-07-02 5 views
4

Я переношу приложение, работающее на устаревшем AS (с большим количеством устаревшего материала внутри). Исходным состоянием было Java 1.7, JBoss 5.1GA, Hibernate 3, SEAM 2.2.2, jBPM 3.9 и некоторые устаревшие графические интерфейсы.Wildfly 8 SEAM2 redirect - javax.faces.context.PartialViewContextFactory

Мне удалось развернуть его на Java 1.8, Wildfly 8.2 с Hibernate 4.3.7, SEAM 2.3.1 и RichFaces 4.5.6. Поскольку SEAM 2.3 способен на JSF2, я также повысил JSF до 2,2 (реализация Mojarra 2.2.8, которая поставляется с Wildfly). Из-за использования SEAM мне пришлось сбросить CDI (WELD) с сервера приложений (прокомментировал WELD в standalone-full.xml). Также переписал jBPM, чтобы он работал с новым Hibernate.

Приложение, похоже, работает правильно, все добирается до конца (без ошибок). Когда я обращаюсь к веб-интерфейсу, страница входа в систему загружается просто отлично. Ввожу данные входа в систему, а затем - после успешного входа в систему - приходит редирект, который вызывается из глубин приложения через фасад, как это:

import org.jboss.seam.faces.Redirect; 
class C { 
    public static void showPage(String page) { 
     Redirect redirect = Redirect.instance(); 
     redirect.setViewId(page);  
     redirect.execute(); 
    } 
} 

Called Таким образом, генерируется исключение и прекращает обработку веб-страниц , Исключение:

SEVERE [javax.faces] (default task-8) Unable to obtain InjectionProvider from init time FacesContext. Does this container implement the Mojarra Injection SPI? 
SEVERE [javax.faces] (default task-8) Application was not properly initialized at startup, could not find Factory: javax.faces.context.PartialViewContextFactory. Attempting to find backup. 
... 
Caused by: org.jboss.seam.faces.RedirectException: Could not find backup for factory javax.faces.context.PartialViewContextFactory. 
    at org.jboss.seam.faces.FacesManager.redirect(FacesManager.java:237) [jboss-seam.jar:2.3.1.Final] 
    at org.jboss.seam.faces.FacesManager.redirect(FacesManager.java:190) [jboss-seam.jar:2.3.1.Final] 
    at org.jboss.seam.faces.Redirect.execute(Redirect.java:154) [jboss-seam.jar:2.3.1.Final] 

Однако есть и другие переадресовывает - все указанные в явном виде в pages.xml - которые работают отлично.

Нет противоречащих друг другу библиотек (например, распространенная проблема MyFaces против Mojarra), есть только Mojarra. Также исключены эти ошибки:

https://issues.jboss.org/browse/WFLY-2594

https://java.net/jira/browse/JAVASERVERFACES-3189

Кто-нибудь знает, как решить эту проблему? Обратите внимание, что выброс SEAM, к сожалению, не вариант здесь.

Я отправлю дополнительную информацию (конфигурация, дополнительная информация, ...) по запросу.

UPDATE: Я отлажены немного больше - добавить некоторые протоколирования непосредственно в FacesManager Seam в. Каротаж выглядит следующим образом:

private void redirect(String viewId, FacesContext context, String url) 
    { 
     url = Pages.instance().encodeScheme(viewId, context, url); 
     if (log.isDebugEnabled()) 
     { 
     log.debug("redirecting to: " + url); 
     } 
     ExternalContext externalContext = context.getExternalContext(); 
     controllingRedirect = true; 
     try 
     { 
     log.debug("Trying to get context..."); 
     log.debug("Contexts.getEventContext(): "+Contexts.getEventContext()); 
     Contexts.getEventContext().set(REDIRECT_FROM_MANAGER, ""); 
     log.debug("REDIRECT_FROM_MANAGER set"); 
     log.debug("externalContext: "+externalContext); 
     externalContext.redirect(externalContext.encodeActionURL(url)); 
     } 
     catch (IOException ioe) 
     { 
     throw new RedirectException(ioe); 
     } 
     catch (IllegalStateException ise) 
     { 
      log.debug("Caught illegal state exception."); 
     throw new RedirectException(ise.getMessage()); 
     } 
     finally 
     { 
     Contexts.getEventContext().remove(REDIRECT_FROM_MANAGER); 
     controllingRedirect = false; 
     } 
     context.responseComplete(); 
    } 

Logging выход непосредственно перед исключением происходит:

DEBUG [org.jboss.seam.faces.FacesManager] (default task-5) redirecting to: /idm/user/personal/personal.seam?cid=2 
DEBUG [org.jboss.seam.faces.FacesManager] (default task-5) Trying to get context... 
DEBUG [org.jboss.seam.faces.FacesManager] (default task-5) Contexts.getEventContext(): BasicContext(EVENT) 
DEBUG [org.jboss.seam.faces.FacesManager] (default task-5) REDIRECT_FROM_MANAGER set 
DEBUG [org.jboss.seam.faces.FacesManager] (default task-5) externalContext: org.richfaces.co[email protected]1dcafb6 
DEBUG [org.jboss.seam.faces.FacesManager] (default task-5) Caught illegal state exception. 

UPDATE 2:

Итак, я возился с отладочных сообщений в SEAM и (так далеко) обнаружил это:

DEBUG [org.jboss.seam.faces.FacesManager] (default task-14) viewId: /adminOrUser/home.xhtml 
DEBUG [org.jboss.seam.faces.FacesManager] (default task-14) parameters: {} 
DEBUG [org.jboss.seam.faces.FacesManager] (default task-14) includeConversationId: true 
DEBUG [org.jboss.seam.faces.FacesManager] (default task-14) includePageParams: true 
DEBUG [org.jboss.seam.faces.FacesManager] (default task-14) FacesContext.getCurrentInstance: [email protected] 
DEBUG [org.jboss.seam.faces.FacesManager] (default task-14) context.getApplication: [email protected] 
DEBUG [org.jboss.seam.faces.FacesManager] (default task-14) context.getApplication.getViewHandler: org.[email protected]151c033 
DEBUG [org.jboss.seam.faces.FacesManager] (default task-14) context.getApplication.getViewHandler.getRedirectURL: /idm/adminOrUser/home.seam 

Интересует ting часть org.jboss.as.jsf.injection.weld.WildFlyConversationAwareViewHandler которая как-то меня пугает. Почему существует класс, который может принадлежать WELD, даже когда я его отключил? У меня не было возможности исследовать дальше, но моя теория заключается в том, что я как-то передал WELD в развертывание косвенно, а затем приварил, а затем вызвал проблемы (конфликты?), Потому что приложение должно полагаться на SEAM.

UPDATE 3:

Понятие WELD связанного с вопросом, вероятно, правильно. В качестве реализации JSF Wildfly использует Mojarra (2.2.8), интегрированный в AS, как jsf-impl-2.2.8-jbossorg-1.jar. Глядя в modules/system/layers/base/com/sun/jsf-impl/main/module.xml в AS существуют WELD зависимостей:

<dependencies> 
    ... 
    <module name="org.jboss.weld.core"/> 
    <module name="org.jboss.weld.spi"/> 
</dependencies> 

Так что либо WELD все еще попадает в развертывание, как зависимость или реализации JSF зависит от чего-то, в данный момент выключен.

Когда я включаю шов на я получаю следующее сообщение об ошибке:

ERROR [org.jboss.seam.exception.Exceptions] (default task-4) handled and logged exception: org.jboss.weld.context.NonexistentConversationException: WELD-000321: No conversation found to restore for id 2 
    at org.jboss.weld.context.AbstractConversationContext.initialize(AbstractConversationContext.java:260) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05] 
    at org.jboss.weld.context.http.LazyHttpConversationContextImpl.initialize(LazyHttpConversationContextImpl.java:68) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05] 
    at org.jboss.weld.context.http.LazyHttpConversationContextImpl.checkContextInitialized(LazyHttpConversationContextImpl.java:96) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05] 
    at org.jboss.weld.context.AbstractConversationContext.getCurrentConversation(AbstractConversationContext.java:460) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05] 
    at org.jboss.weld.jsf.ConversationAwareViewHandler.getActionURL(ConversationAwareViewHandler.java:111) [weld-core-jsf-2.2.6.Final.jar:2014-10-03 10:05] 
    at javax.faces.application.ViewHandlerWrapper.getActionURL(ViewHandlerWrapper.java:189) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] 
    at com.sun.faces.application.view.MultiViewHandler.getRedirectURL(MultiViewHandler.java:468) [jsf-impl-2.2.8-jbossorg-1.jar:] 
    at javax.faces.application.ViewHandlerWrapper.getRedirectURL(ViewHandlerWrapper.java:250) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] 
    at org.jboss.seam.jsf.SeamViewHandler.getRedirectURL(SeamViewHandler.java:133) [jboss-seam.jar:2.3.1.Final] 
    at javax.faces.application.ViewHandlerWrapper.getRedirectURL(ViewHandlerWrapper.java:250) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] 
    at javax.faces.application.ViewHandlerWrapper.getRedirectURL(ViewHandlerWrapper.java:250) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] 
    at org.jboss.weld.jsf.ConversationAwareViewHandler.getRedirectURL(ConversationAwareViewHandler.java:142) [weld-core-jsf-2.2.6.Final.jar:2014-10-03 10:05] 
    at javax.faces.application.ViewHandlerWrapper.getRedirectURL(ViewHandlerWrapper.java:250) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8] 
    at org.jboss.seam.faces.FacesManager.redirect(FacesManager.java:182) [jboss-seam.jar:2.3.1.Final] 

Это означает разговор с идентификатором = 2 не найден в WELD-управляемом контексте. Это неудивительно, потому что cid генерируется SEAM, и WELD вообще не знает об этом.

Существует короткий документ о создании JSF работы с WELD: http://docs.jboss.org/weld/reference/latest/en-US/html/ri-spi.html#_jsf

Вторая возможность заключается в том, чтобы оставить WELD выключен и изменить реализацию JSF так jsf-impl-2.2.8-jbossorg-1.jar не будет использоваться: https://developer.jboss.org/wiki/StepsToAddAnyNewJSFImplementationOrVersionToWildFly(Update: это ., кажется, не работают)

Также интересно/связанное чтение к теме можно найти здесь: JSF 1.2 on Wildfly 8 Final - weld-core-jsf is still referencing JSF 2.2 API

ответ

0

@jarda_mlejnek выяснили, что происходит. Проблема была в рамках jBPM.

Вещь, все заводы (ContextFactory, ApplicationFactory, PartialViewContextFactory, ...) были правильно инициализированы во время развертывания приложения - и были на месте, даже когда мы перемещались в графическом интерфейсе. Проблема возникла, когда мы обратились к веб-странице, которая начала новый процесс jBPM (некоторые части графического интерфейса написаны именно так, особенно многоэтапные).

Для определения местонахождения заводов Mojarra использует класс FactoryFinder, который отслеживает текущие фабрики, путем поиска хэш-карты с загрузчиком классов в качестве ключа. Когда процесс jBPM запустился, он изменил загрузчик классов Faces, который видел его (org.jbpm.instantiation.ProcessClassLoader), который, в свою очередь, повторно инициализировал Mojarra - и для этого загрузчика классов не было создано никаких заводов. С точки зрения Мохарры все заводы исчезли. Возможно, это какой-то странный случай JAVASERVERFACES-3189, но, поскольку наш сценарий является чем-то очень нестандартным, мы не сообщали об этом.

Мы решили это, исправляя Mojarra так, чтобы перерегистрация фабрик, запущенных из jBPM, ничего не делала, и приложение работало с заводами, которые были созданы во время развертывания.