Как установить и использовать CDI на Tomcat?

Я создаю свой первый проект Java EE 7, но у меня проблемы. Цените любую помощь.

  • Tomcat 7.0.34
  • JSF 2.2
  • Основные шрифты 3.5
  • JavaEE-апи-7.0.jar

Когда приложение запускается, журнал Tomcat показывает следующее сообщение:

"validateJarFile (C:\...\build\web\WEB-INF\lib\javaee-api-7.0.jar)-jar not loaded. See Servlet 2.3 Spec, section 9.7.2. Offending class: javax/servlet/Servlet .class"

когда я нажимаю кнопку, которая вызывает управляемый bean, я получаю сообщение об ошибке:

Advertência: /index.xhtml @18,66 value="#{indexMB.user}": Target Unreachable, identifier 'indexMB' resolved to null
javax.el.PropertyNotFoundException: /index.xhtml @18,66 value="#{indexMB.user}": Target Unreachable, identifier 'indexMB' resolved to null

IndexMB

@Named("indexMB")
@RequestScoped
public class IndexMB {

private String password;
private String user;

public String loginTest(){
    return (this.user.equals("admin") ? "adminPage" : "inOutPage");
}

// getters and setters
}

index.xhtml

<html ...>

<f:loadBundle basename="i18n" var="bundle" />
<h:head>
    <title>#{bundle['index_title']}</title>
</h:head>
<h:body>
    #{bundle['index_appname']}
    <br />
    <h:form id="frmIndex">
        <p:panelGrid columns="2">
            <p:outputLabel for="user" value="#{bundle['lblUser']}" />
            <p:inputText id="user" value="#{indexMB.user}" />

            <p:outputLabel for="password" value="#{bundle['lblPassword']}" />
            <p:password id="password" value="#{indexMB.password}" />
        </p:panelGrid>
        <p:commandButton action="#{indexMB.loginTest}" value="#{bundle['btn_login']}" />
    </h:form> 
</h:body>

лица-config.xml

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">

<application>
    <locale-config>
        <default-locale>pt_BR</default-locale>
        <supported-locale>en</supported-locale>
        <supported-locale>fr</supported-locale>
    </locale-config>
</application>

Эти темы мне не помогли:

Ответ 1

Tomcat как контейнер barebone JSP/Servlet не поддерживает CDI из коробки. Как именно вы установили CDI? Вы действительно потеряли javaee-api-7.0.jar в /WEB-INF/lib, чтобы получить код для компиляции? О, пожалуйста, нет, это не правильный путь. Java JE API JAR содержит только классы API, а не конкретную реализацию. Избавьтесь от всего JAR. Это может вызвать многие другие проблемы с переносимостью, такие как описанные в этом ответе: Как импортировать API javax.servlet в проект Eclipse? На самом деле вы должны установить конкретную реализацию вместе с конкретным API.

У вас есть 2 варианта:

  • Бросьте Tomcat и идите в настоящий контейнер Java EE. Когда вы используете Tomcat, просто перейдите к TomEE. Это действительно просто, скачать zip файл веб-профиля TomEE, извлечь его и интегрировать в Eclipse точно так же, как и для Tomcat. Не забудьте удалить файл Java EE JAR из webapp и изменить свойство Targeted Runtime в свойствах проекта из Tomcat в TomEE, чтобы соответствующие зависимости Java EE были разрешены.

    Никаких дополнительных JAR или конфигурации не требуется. Вы даже можете удалить JSF JAR из своего webapp. TomEE как настоящий Java EE-контейнер уже предоставляет, среди прочего, JSF и CDI. Если вы используете Maven, достаточная координата ниже.

    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version><!-- 7.0 (TomEE 7.x) or 6.0 (TomEE 1.x) --></version>
        <scope>provided</scope>
    </dependency>
    

    Обратите внимание на важность provided, и его значение, как и в "целевой среде выполнения, уже предоставляет это из окна". См. Также нашу страницу вики JSF.


  • Установите настоящую реализацию CDI на Tomcat. Weld - одна из доступных реализаций CDI. В руководстве по установке Weld вы можете найти инструкции по его интеграции в Tomcat. Для полноты и будущей ссылки, вот шаги:

    • Отбросьте weld-servlet.jar в webapp /WEB-INF/lib. Если вы используете Maven, используйте эту координату:

      <dependency>
          <groupId>org.jboss.weld.servlet</groupId>
          <artifactId>weld-servlet</artifactId>
          <version>2.3.4.Final</version>
      </dependency>
      
    • Создайте файл /META-INF/context.xml в webapp со следующим содержимым:

      <Context>
          <Resource name="BeanManager" 
              auth="Container"
              type="javax.enterprise.inject.spi.BeanManager"
              factory="org.jboss.weld.resources.ManagerObjectFactory"/>
      </Context>
      
    • Создайте пустой файл /WEB-INF/beans.xml в webapp.

    Это (обратите внимание: в более старых версиях Weld Servlet вам необходимо явно зарегистрировать менеджер CDI bean и прослушиватель Weld в web.xml тоже, но это ненужно с текущими версиями).

    Если вы предпочитаете OpenWebBeans выше Weld в качестве реализации CDI, отправляйтесь в этот блог для подробных инструкций по установке Maven: Как установить CDI в Tomcat?


Несвязанный к конкретной проблеме, API-интерфейсы JSP/Servlet Tomcat 7 do не соответствуют этим API-интерфейсам Java EE 7, вместо этого он соответствует Java EE 6 (Servlet 3.0/JSP 2.2). Если вам нужен эквивалент Tomcat Java EE 7 (Servlet 3.1/JSP 2.3), вы должны смотреть на Tomcat 8. См. Также Маска версии Apache Tomcat.

Ответ 2

Другой возможный вариант - оставить beans.xml в вашем развертывании.