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

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

  • Tomcat 7.0.34
  • JSF 2.2
  • Primefaces 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"

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

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>

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

2 ответа

Решение

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

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

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

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

    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version><!-- 8.0 or 7.0 or 6.0 --></version>
        <scope>provided</scope>
    </dependency>
    

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


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

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

      <dependency>
          <groupId>org.jboss.weld.servlet</groupId>
          <artifactId>weld-servlet-shaded</artifactId>
          <version>3.0.5.Final</version>
      </dependency>
      
    2. Создайте /META-INF/context.xml файл в веб-приложении со следующим содержанием:

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

      Обратите внимание, что этот шаг не является строго необходимым, если вы используете Mojarra 2.2.11 или новее, так как он сможет найти его через ServletContext когда отсутствует в JNDI.

    3. Создать пустой /WEB-INF/beans.xml файл в веб-приложении.

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

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


Не связанные с конкретной проблемой, API-интерфейсы JSP/Servlet Tomcat 7 не соответствуют этим 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.

Другим возможным вариантом является уход beans.xml в вашем развертывании.

Другие вопросы по тегам