Может ли MyFaces + CDI использоваться в WebLogic 12c?

Я пытаюсь запустить эту установку на пару дней, но все равно не повезло. Здесь тестовое приложение, которое я использовал:

@Named
@RequestScoped
public class Test {

    private String test = "test";
    public String getTest() { return test; }
    public void setTest(String test) { this.test = test; }
}

И на странице jsf:

<h:outputText value="#{test.test}"/>

Запуск этого примера без MyFaces отлично работает (делает "тест" таким, как он должен), но когда я развертываю MyFaces в WAR файле и делаю необходимую конфигурацию в weblogic.xml, CDI, похоже, перестает работать (или, по крайней мере, интеграция bewteen JSF и CDI), и ничего не отображается в выходном html. Однако MyFaces выглядит нормально.

Моя основная конфигурация такова:

  • WebLogic Server 12c (12.1.1.0), исправления должны быть обновлены, так как я только что загрузил версию для разработки вчера, чтобы быть уверенным
  • MyFaces-2.1.10, развернутый в WEB-INF/libs
  • Beans.xml находится на месте
  • org.apache.myfaces.webapp.StartupServletContextListener зарегистрирован в web.xml
  • WebLogic настроен на использование MyFaces с помощью weblogic.xml

Содержимое Weblogic.xml:

<prefer-application-packages>
    <package-name>javax.faces.*</package-name>
    <package-name>com.sun.faces.*</package-name>
    <package-name>com.bea.faces.*</package-name>
</prefer-application-packages>
<prefer-application-resources>
    <resource-name>javax.faces.*</resource-name>
    <resource-name>com.sun.faces.*</resource-name>
    <resource-name>com.bea.faces.*</resource-name>
    <resource-name>META-INF/services/javax.servlet.ServletContainerInitializer</resource-name>
    <resource-name>META-INF/services/com.sun.faces.spi.FacesConfigResourceProvider</resource-name>
</prefer-application-resources>

Что я узнал до сих пор:

  • WL12c оснащен Weld 1.1.3 как реализация CDI.
  • Я где-то читал (не могу вспомнить, где), что всякий раз, когда вы решаете переключить реализацию JSF, вы отвечаете за интеграцию JSF/CDI самостоятельно. Это правда (надежная надежда не)?

Вещи, которые я пробовал до сих пор:

  • Добавить MyFaces CODI в микс, надеясь, что он каким-то образом склеит Weld и MyFaces вместе, но это не так.
  • Заменить Weld OpenWebBeans как реализацию CDI. Сначала это работало, но позже появилось множество интересных ClassCastExceptions в некотором внутреннем пакете sun.reflection. Это решение, которое я бы скорее избежал.
  • Вручную вызовите Weld, используя различные параметры в web.xml и faces-config.xml. Это похоже на то, что Weld происходит в том, что он наводняет журнал всеми видами сообщений об ошибках. В какой-то степени они могут быть "исправлены" путем обновления weblogic до новой версии Weld, но каждый раз, когда я это делаю, я сталкиваюсь с следующей ошибкой. Опять же, я бы предпочел также избежать этого маршрута.

Неужели это трудно использовать MyFaces на WL12c, сохраняя поддержку CDI, или я просто не вижу очевидного? Спасибо за любую помощь.

Ответ 1

Я боюсь, что это невозможно. Здесь должен быть код сварного клея. Этот крошечный маленький слой интеграции, который является частью библиотек развертывания wls для jsf, недоступен для myfaces....

Ответ 2

В вашем примере довольно много вещей, которые не ясны. Например. с каким пакетом @RequestScoped? Это javax.enterprise.context.RequestScoped(должен работать) или javax.faces.bean.RequestScoped(не будет работать)? Если вы используете только CDI beans (и не файл javax.faces.bean), то единственный способ, которым контейнер JSF и контейнер CDI объединяются друг с другом, - это, на самом деле, язык унифицированных выражений javax.el.ELResolver. И это должно работать из коробки.

org.apache.myfaces.webapp.StartupServletContextListener действительно не требуется imo. Все, что вам нужно - установить FacesServlet.

Проблематичным моментом может быть то, что JSF EG заставил использовать ServletContainerInitializer [1] для слепо активировать JSF impl, даже если приложение не использует JSF вообще. Это сложно обойти, поскольку спецификация сервлета-3.0 определяет, как автоматически активировать эти функции, но нет способа отключить их снова.

[1] http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html

Ответ 3

Просто интересно, пытались ли вы включить сервлет серва в вашем приложении?

Причина, по которой я спросил, объясняется этим утверждением:

Я где-то читал (не могу вспомнить, где), что всякий раз, когда вы решаете переключить реализацию JSF, вы несете ответственность за интеграцию JSF/CDI самостоятельно

Это довольно точно. Контейнер - это тот, который объединяет все комбинированное расслоение JSF impl и CDI impl. Если вы замените его своим собственным JSF impl, вы обходите то, что дает вам контейнер. Если вы еще этого не сделали, я настоятельно рекомендую вам попробовать включить Weld Servlet в вашем приложении, чтобы узнать, загружается ли CDI с пользовательским JSF-импровизацией.