¿Cómo instalar y usar CDI en Tomcat?

Resuelto Rogério Arantes asked hace 11 años • 2 respuestas

Estoy creando mi primer proyecto Java EE 7, pero tengo problemas. Agradezco cualquier ayuda.

  • Tomcat 7.0.34
  • JSF 2.2
  • Caras principales 3.5
  • javaee-api-7.0.jar

Cuando se inicia la aplicación, el registro de Tomcat muestra el siguiente mensaje:

"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"

cuando hago clic en el botón que llama al bean administrado, aparece el error:

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

ÍndiceMB

@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
}

índice.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>

caras-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>

Estos temas no me han ayudado:

  • Java EE 6 @javax.annotation.ManagedBean frente a @javax.inject.Named frente a @javax.faces.MangedBean
  • Identificador de destino inalcanzable resuelto como nulo
  • Destino inalcanzable, identificador resuelto como nulo
  • javax.el.PropertyNotFoundException: Objetivo inalcanzable, identificador 'inicio de sesión' resuelto como nulo Spring + JSF
  • http://www.andrejkoelewijn.com/blog/2010/03/05/jee-cdi-tip-target-unreachable-identifier-resolved-to-null/
Rogério Arantes avatar Sep 25 '13 10:09 Rogério Arantes
Aceptado

Tomcat, al ser un contenedor JSP/Servlet básico, no admite CDI de fábrica. No es correcto soltarlo jakartaee-api.jaro javaee-api.jarsimplemente /WEB-INF/libingresarlo para compilar el código. El JEE API JAR contiene únicamente las clases API, no la implementación concreta. Deshazte de todo el JAR. Puede causar muchos otros problemas de portabilidad como los que se describen en esta respuesta: ¿ Cómo importo la API javax.servlet/jakarta.servlet en mi proyecto Eclipse? En realidad, debería instalar la implementación concreta junto con la API específica.

Tienes 2 opciones:

  1. Deje Tomcat y opte por un verdadero contenedor Jakarta EE. Mientras usa Tomcat, simplemente pase a TomEE . Es realmente simple: descargue el archivo zip del perfil web de TomEE , extráigalo e intégrelo en Eclipse exactamente de la misma manera que lo hizo con Tomcat. No olvide eliminar el archivo JAR de Jakarta EE de la aplicación web y modificar la propiedad Targeted Runtime en las propiedades del proyecto de Tomcat a TomEE para que las dependencias de Jakarta EE se resuelvan correctamente. Consulte también ¿Qué es exactamente Java EE?

    No se necesitan JAR ni configuración adicionales. Incluso puede eliminar las bibliotecas JSF/JSTL/CDI/BV/JPA/EJB/JTA/JSONPJAX-RS/etc/etc instaladas manualmente desde su aplicación web. TomEE, como verdadero contenedor EE de Yakarta, ya los ofrece todos listos para usar. En caso de que esté utilizando Maven, la siguiente coordenada es suficiente.

     <dependency>
         <groupId>jakarta.platform</groupId>
         <artifactId>jakarta.jakartaee-web-api</artifactId>
         <version><!-- e.g. 10.0.0 or 9.1.0 --></version>
         <scope>provided</scope>
     </dependency>
    

    Tenga en cuenta la importancia providedy su significado como en "el tiempo de ejecución de destino ya proporciona esto de forma predeterminada". Consulte también ¿Cómo configurar correctamente las bibliotecas Jakarta EE en Maven pom.xml para Tomcat? para pom.xmlejemplos detallados de Tomcat y contenedores JEE normales.


  2. Si desea seguir con Tomcat, debe instalar manualmente una implementación CDI real a través de la aplicación web. Las instrucciones siguientes asumen Tomcat 10+. Weld es una de las implementaciones CDI disponibles. En la guía de instalación de Weld puede encontrar instrucciones sobre cómo integrarlo en Tomcat. Para mayor exhaustividad y referencia futura, estos son los pasos:

    1. Para Tomcat 10.1.x, elimine la weld-servlet-shaded.jarversión 5.x en el archivo /WEB-INF/lib. En caso de que estés usando Maven, usa esta coordenada:

       <dependency>
           <groupId>org.jboss.weld.servlet</groupId>
           <artifactId>weld-servlet-shaded</artifactId>
           <version>5.1.0.Final</version>
       </dependency>
      

      Para Tomcat 10.x, utilice weld-servlet-shaded.jarla versión 4.x en su lugar:

       <dependency>
           <groupId>org.jboss.weld.servlet</groupId>
           <artifactId>weld-servlet-shaded</artifactId>
           <version>4.0.3.Final</version>
       </dependency>
      
    2. Opcionalmente, cree un /META-INF/context.xmlarchivo en la aplicación web con el siguiente contenido:

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

      Este paso solo es necesario cuando la biblioteca dependiente de CDI intenta encontrarla manualmente en JNDI. Este paso no es necesario cuando utilizas, por ejemplo, Jakarta Faces / JSF versión 2.3 o posterior.

    3. Cree un /WEB-INF/beans.xmlarchivo en la aplicación web para activar la activación de CDI. Se puede mantener vacío.

    Eso es todo.

    En caso de que prefiera OpenWebBeans por encima de Weld como implementación de CDI, o necesite instalar CDI en Tomcat 9.x o anterior, diríjase a este blog para obtener instrucciones detalladas de instalación de Maven: ¿ Cómo instalar CDI en Tomcat?

BalusC avatar Sep 25 '2013 11:09 BalusC