Identificar y resolver javax.el.PropertyNotFoundException: destino inalcanzable

Al intentar hacer referencia a un bean administrado en EL como #{bean.entity.property} tan #{bean.entity.property} , a veces se javax.el.PropertyNotFoundException: Target Unreachable una javax.el.PropertyNotFoundException: Target Unreachable , generalmente cuando se va a establecer una propiedad de bean, o cuando una acción bean debe ser invocado

Parece que hay cinco tipos diferentes de mensajes:

  1. Destino inalcanzable, identificador ‘bean’ resuelto a nulo
  2. Destino inalcanzable, ‘entidad’ devuelta nula
  3. Destino inalcanzable, ‘nulo’ devuelto nulo
  4. Destino inalcanzable, ” 0 ” devuelto nulo
  5. Destino inalcanzable, ‘BracketSuffix’ devolvió nulo

a que se refieren ellos? ¿Cómo son causados ​​y cómo deben ser resueltos?

1. Destino inalcanzable, identificador ‘bean’ resuelto a nulo

Esto se reduce a que la instancia de bean administrado en sí misma no pudo ser encontrada exactamente por ese identificador (nombre de bean administrado) en EL como #{bean} .

La identificación de la causa se puede dividir en tres pasos:

a. ¿Quién está administrando el frijol?
segundo. ¿Cuál es el nombre de bean administrado (predeterminado)?
do. ¿Dónde está la clase de bean de respaldo?

1a. ¿Quién está administrando el frijol?

El primer paso sería verificar qué marco de gestión de frijoles es responsable de gestionar la instancia de frijol. ¿Es JSF a través de @ManagedBean ? ¿O es CDI a través de @Named ? ¿O es Spring vía @Component ? ¿Puedes asegurarte de que no estás mezclando anotaciones específicas del marco de administración de frijoles en la misma clase de bean de respaldo? Ej @Named @Component , o @Named @ManagedBean , o @ManagedBean @Component . Esto está mal. El bean debe ser administrado como máximo por un marco de gestión de beans y ese framework debe estar configurado correctamente. Si ya no tiene idea de qué elegir, diríjase a Backing beans (@ManagedBean) o CDI Beans (@Named)? y Spring JSF integration: ¿cómo inyectar un componente / servicio Spring en un bean gestionado JSF?

En caso de que JSF administre el bean vía @ManagedBean , entonces debe asegurarse de lo siguiente:

  • La statement de la raíz faces-config.xml es compatible con JSF 2.0. Por lo tanto, el archivo XSD y la version deben al menos especificar JSF 2.0 o superior y, por lo tanto, no 1.x.

      

    Para JSF 2.1, simplemente reemplace 2_0 y 2.0 por 2_1 y 2.1 respectivamente.

    Si tienes JSF 2.2 o superior, asegúrate de utilizar xmlns.jcp.org nombres xmlns.jcp.org lugar de java.sun.com en todos los lugares.

      

    Para JSF 2.3, simplemente reemplace 2_2 y 2.2 por 2_3 y 2.3 respectivamente.

  • No importó accidentalmente javax.annotation.ManagedBean lugar de javax.faces.bean.ManagedBean . Tenga cuidado con el autocompletado IDE, se sabe que Eclipse auto sugiere el incorrecto como primer elemento de la lista.

  • No @ManagedBean por una entrada JSF estilo 1.x en faces-config.xml en la misma clase de bean de respaldo junto con un nombre de bean administrado diferente. Este tendrá prioridad sobre @ManagedBean . El registro de un bean administrado en faces-config.xml no es necesario ya que JSF 2.0 solo lo elimina.
  • Su classpath en tiempo de ejecución está limpio y libre de duplicados en JAR relacionados con API JSF. Asegúrese de no mezclar múltiples implementaciones JSF (Mojarra y MyFaces). Asegúrese de no proporcionar otro archivo JAR JSF o incluso Java EE API a lo largo de la aplicación web cuando el contenedor de destino ya empaqueta la API JSF. Consulte también la sección “Instalación de JSF” de nuestra página wiki de JSF para obtener instrucciones de instalación de JSF. En caso de que pretenda actualizar JSF empaquetado desde el WAR en lugar de en el contenedor, asegúrese de haber indicado al contenedor de destino que utilice JSF API / impl incluido en WAR.
  • Si está empaquetando beans administrados JSF en un JAR, entonces asegúrese de que el JAR tenga al menos un /META-INF/faces-config.xml compatible con JSF 2.0. Consulte también ¿Cómo hacer referencia a los beans administrados JSF que se proporcionan en un archivo JAR?
  • Si realmente está utilizando JSF jurásico 1.x, y no puede actualizar, entonces necesita registrar el bean a través de en faces-config.xml lugar de @ManagedBean . No olvide corregir la ruta de comstackción de su proyecto de tal manera que ya no tenga bibliotecas JSF 2.x (para que la anotación @ManagedBean no se compile de manera confusa y satisfactoria).


En caso de que CDI esté administrando el bean a través de @Named , entonces debe asegurarse de lo siguiente:

  • CDI 1.0 (Java EE 6) requiere un archivo /WEB-INF/beans.xml para habilitar CDI en WAR. Puede estar vacío o puede tener solo el siguiente contenido:

        
  • CDI 1.1 (Java EE 7) sin beans.xml , o un archivo beans.xml vacío, o con el CDI 1.0 compatible beans.xml se comportará igual que CDI 1.0. Cuando hay un beans.xml compatible con CDI 1.1 con una version="1.1" explícita version="1.1" , de manera predeterminada solo registrará beans @Named con una anotación de scope CDI explícita como @RequestScoped , @ViewScoped , @SessionScoped , @ApplicationScoped , etc. En caso de que pretenda registrar todos los beans como beans administrados por CDI, incluso aquellos sin un ámbito de CDI explícito, use el siguiente CDI 1.1 compatible /WEB-INF/beans.xml con bean-discovery-mode="all" establecido (el valor predeterminado es bean-discovery-mode="annotated" ).

        
  • Al usar CDI 1.1+ con bean-discovery-mode="annotated" (predeterminado), asegúrese de no haber importado accidentalmente un ámbito JSF como javax.faces.bean.RequestScoped lugar de un scope CDI javax.enterprise.context.RequestScoped . Cuidado con el autocompletado IDE.

  • Al usar Mojarra 2.3.0-2.3.2 y CDI 1.1+ con bean-discovery-mode="annotated" (predeterminado), entonces necesita actualizar Mojarra a 2.3.3 o posterior debido a un error . En caso de que no pueda actualizar, entonces necesita establecer bean-discovery-mode="all" en beans.xml , o poner la anotación @FacesConfig específica de JSF 2.3 en una clase arbitraria en WAR (generalmente algún tipo de una clase de inicio con ámbito de aplicación).
  • Los contenedores que no son Java EE como Tomcat y Jetty no incluyen el paquete CDI. Necesita instalarlo manualmente. Es un poco más trabajo que solo agregar los JAR de la biblioteca. Para Tomcat, asegúrese de seguir las instrucciones en esta respuesta: ¿Cómo instalar y usar CDI en Tomcat?
  • Su classpath en tiempo de ejecución está limpio y libre de duplicados en CDI API relacionados con JAR. Asegúrese de no mezclar múltiples implementaciones de CDI (Weld, OpenWebBeans, etc.). Asegúrese de no proporcionar otro CDI o incluso el archivo JAR de Java EE API a lo largo de la aplicación web cuando el contenedor de destino ya empaqueta la API de CDI.
  • Si está empaquetando beans administrados CDI para vistas JSF en un JAR, entonces asegúrese de que el JAR tenga al menos un /META-INF/beans.xml válido (que se puede mantener vacío).


En caso de que sea Spring quién administre el bean a través de @Component , entonces debe asegurarse de lo siguiente:

  • Spring se está instalando e integrando según su documentación . Importantemente, necesita al menos tener esto en web.xml :

      org.springframework.web.context.ContextLoaderListener  

    Y esto en faces-config.xml :

      org.springframework.web.jsf.el.SpringBeanFacesELResolver  
  • (arriba es todo lo que sé con respecto a Spring – I do not do Spring – no dude en editar / comentar con otras causas probables relacionadas con Spring, por ejemplo, algún problema relacionado con la configuración de XML)


En caso de que sea un componente repetidor quien administra el bean (nested) a través de su atributo var (ej. , , , etc.) y en realidad recibió un “elemento inalcanzable, identificador” elemento “resuelto a nulo”, entonces necesita asegurarse de lo siguiente:

  • El #{item} no se referencia en el atributo de vinculación de ningún componente secundario. Esto es incorrecto ya binding atributo de binding ejecuta durante el tiempo de comstackción de la vista, no durante el tiempo de visualización de representación. Además, físicamente hay solo un componente en el árbol de componentes que simplemente se reutiliza durante cada ronda de iteración. En otras palabras, en realidad debería usar binding="#{bean.component}" lugar de binding="#{item.component}" . Pero mucho mejor es deshacerse de los componentes para intercalar e investigar e investigar el enfoque adecuado para el problema que pensaste resolver de esta forma. Ver también ¿Cómo funciona el atributo ‘vinculante’ en JSF? ¿Cuándo y cómo se debe usar?


1b. ¿Cuál es el nombre de bean administrado (predeterminado)?

El segundo paso sería verificar el nombre del frijol administrado registrado. Las convenciones de uso de JSF y Spring cumplen la especificación JavaBeans, mientras que CDI tiene excepciones que dependen de CDI impl / versión.

  • Una clase de bean de respaldo FooBean como a continuación,

     @Named public class FooBean {} 

    en todos los marcos de administración de #{fooBean} , tendrá un nombre de bean administrado por defecto de #{fooBean} , según la especificación JavaBeans.

  • Una clase de bean de respaldo FOOBean como a continuación,

     @Named public class FOOBean {} 

    cuyo nombre de clase no calificado comienza con al menos dos mayúsculas en JSF y Spring tienen un nombre de #{FOOBean} administrado por defecto del nombre de clase no calificado #{FOOBean} , también concuerdan con la especificación de JavaBeans. En CDI, este es también el caso en las versiones de Weld publicadas antes de junio de 2015, pero no en las versiones de Weld publicadas después de junio de 2015 (2.2.14 / 2.3.0.B1 / 3.0.0.A9) ni en OpenWebBeans debido a un descuido en Especificación CDI En esas versiones de Weld y en todas las versiones de OWB solo es con el primer carácter en minúscula #{fOOBean} .

  • Si ha especificado explícitamente un nombre de bean administrado como el siguiente,

     @Named("foo") public class FooBean {} 

    o equivalentemente con @ManagedBean(name="foo") o @Component("foo") , entonces solo estará disponible por #{foo} y por lo tanto no por #{fooBean} .


1c. ¿Dónde está la clase de bean de respaldo?

El tercer paso sería doble comprobación si la clase de bean de respaldo está en el lugar correcto en el archivo WAR creado y desplegado. Asegúrese de haber realizado correctamente una limpieza completa, reconstruir, volver a implementar y reiniciar el proyecto y el servidor en caso de que estuviera realmente ocupado escribiendo código y presionando con impaciencia F5 en el navegador. Si aún es en vano, permita que el sistema de comstackción produzca un archivo WAR, que luego extrae e inspecciona con una herramienta ZIP. El archivo comstackdo .class de la clase de bean de respaldo debe residir en su estructura de paquete en /WEB-INF/classes . O bien, cuando se empaqueta como parte de un módulo JAR, el JAR que contiene el archivo .class comstackdo debe residir en /WEB-INF/lib y, por lo tanto, no en EAR /lib ni en ningún otro lugar.

Si está utilizando Eclipse, asegúrese de que la clase de bean de respaldo esté en src y, por lo tanto, no en WebContent , y asegúrese de que Proyecto> Crear automáticamente esté habilitado. Si está utilizando Maven, asegúrese de que la clase de bean de respaldo esté en src/main/java y, por lo tanto, no en src/main/resources o src/main/webapp .

Si está empaquetando la aplicación web como parte de un EAR con EJB + WAR (s), entonces necesita asegurarse de que las clases de bean de respaldo estén en el módulo WAR y, por lo tanto, no en el módulo EAR ni en el módulo EJB. El nivel de negocio (EJB) debe estar libre de artefactos relacionados con el nivel web (WAR), de modo que el nivel del negocio sea reutilizable en varios niveles web diferentes (JSF, JAX-RS, JSP / Servlet, etc.).


2. Destino inalcanzable, ‘entidad’ devuelta nula

Esto se reduce a que la entity propiedad anidada como en #{bean.entity.property} devolvió null . Esto generalmente solo se expone cuando JSF necesita establecer el valor de la property través de un componente de entrada como el siguiente, mientras que el #{bean.entity} realidad devuelve null .

  

@PostConstruct asegurarse de haber preparado la entidad modelo de antemano en un @PostConstruct , o , o quizás un método de acción add() en caso de que esté trabajando con listas CRUD y / o cuadros de diálogo en la misma vista. .

 @Named @ViewScoped public class Bean { private Entity entity; // +getter (setter is not necessary). @Inject private EntityService entityService; @PostConstruct public void init() { // In case you're updating an existing entity. entity = entityService.getById(entityId); // Or in case you want to create a new entity. entity = new Entity(); } // ... } 

En cuanto a la importancia de @PostConstruct ; Hacer esto en un constructor normal fallaría en caso de que esté usando un marco de administración de beans que use proxys , como CDI. Siempre use @PostConstruct para enganchar la inicialización de la instancia de bean administrada (y use @PreDestroy para enganchar la destrucción de la instancia administrada de bean). Además, en un constructor no tendrías acceso a ninguna dependencia inyectada aún, mira también NullPointerException mientras intentas acceder a @Inject bean en el constructor .

En caso de que entityId se suministre a través de , necesitaría usar lugar de @PostConstruct . Consulte también Cuándo usar f: viewAction / preRenderView versus PostConstruct?

También debe asegurarse de conservar el modelo no null durante las devoluciones en caso de que lo esté creando solo en un método de acción add() . Lo más fácil sería poner el bean en el scope de la vista. Consulte también ¿Cómo elegir el scope del frijol correcto?


3. Destino inalcanzable, ‘nulo’ devuelto nulo

Esto tiene la misma causa que el n. ° 2, solo la implementación de EL (más antigua) que se usa tiene algún error para preservar el nombre de la propiedad que se mostrará en el mensaje de excepción, que finalmente se expuso incorrectamente como ‘nulo’. Esto solo hace que la depuración y la corrección sean un poco más difíciles cuando tiene algunas propiedades anidadas como #{bean.entity.subentity.subsubentity.property} .

La solución sigue siendo la misma: asegúrese de que la entidad anidada en cuestión no sea null , en todos los niveles.


4. Destino inalcanzable, ” 0 ” devuelto nulo

Esto también tiene la misma causa que el n. ° 2, solo la implementación de EL (más antigua) que se utiliza tiene errores al formular el mensaje de excepción. Esto se expone solo cuando usa la notación de #{bean.collection[index]} [] en EL como en #{bean.collection[index]} donde el #{bean.collection} sí mismo no es nulo, pero el ítem en el índice especificado no existe. Tal mensaje debe interpretarse entonces como:

Destino inalcanzable, ‘colección [0]’ devuelta nula

La solución también es igual a la # 2: asegúrese de que el artículo de colección esté disponible.


5. Destino inalcanzable, ‘BracketSuffix’ devolvió nulo

Esto tiene la misma causa que el # 4, solo la implementación de EL (más antigua) que se usa tiene algún error al conservar el índice de iteración para mostrar en el mensaje de excepción, que finalmente se expone incorrectamente como ‘BracketSuffix’, que es realmente el carácter ] . Esto solo hace que la depuración y la reparación sean un poco más difíciles cuando tienes varios elementos en la colección.


Otras posibles causas de javax.el.PropertyNotFoundException :

  • javax.el.ELException: Error al leer ‘foo’ en el tipo com.example.Bean
  • javax.el.ELException: no se pudo encontrar la propiedad actionMethod en la clase com.example.Bean
  • javax.el.PropertyNotFoundException: la propiedad ‘foo’ no se encuentra en el tipo com.example.Bean
  • javax.el.PropertyNotFoundException: la propiedad ‘foo’ no es legible en el tipo java.lang.Boolean
  • javax.el.PropertyNotFoundException: Propiedad no encontrada en el tipo org.hibernate.collection.internal.PersistentSet
  • El código Facelets Outcommented todavía invoca expresiones EL como # {bean.action ()} y causa javax.el.PropertyNotFoundException en # {bean.action}

Para aquellos que todavía están atrapados …

Usando NetBeans 8.1 y GlassFish 4.1 con CDI, por alguna razón tuve este problema solo localmente, no en el servidor remoto. ¿Qué hizo el truco?

-> usando javaee-web-api 7.0 en lugar de la versión predeterminada de pom proporcionada por NetBeans, que es javaee-web-api 6.0, entonces:

  javax javaee-web-api 7.0 provided jar  

-> cargue este javaee-web-api-7.0.jar como lib en el servidor (carpeta lib en la carpeta domain1) y reinicie el servidor.

Decidí compartir mi descubrimiento sobre este error después de resolverlo yo mismo.

En primer lugar, las soluciones de BalusC deben tomarse en serio, pero luego hay otro problema probable en Netbeans para tener en cuenta especialmente cuando se construye un Proyecto de Aplicación Empresarial (EAR) utilizando Maven.

Netbeans genera, un archivo POM padre , un proyecto EAR , un proyecto EJB y un proyecto WAR . Todo lo demás en mi proyecto estaba bien, y casi asumí que el problema es un error en GlassFish 4.0 (tuve que instalarlo y conectarlo a Netbeans) porque GlassFish 4.1 tiene un error Weld CDI que hace que GlassFish 4.1 incrustado en Netbeans 8.0. 2 inutilizable excepto a través de un parche.

Solución:

Para resolver el error “Destino inalcanzable, identificador ‘bean’ resuelto a nulo”

Haga clic con el botón derecho en el proyecto principal de POM y seleccione Propiedades . Aparecerá un cuadro de diálogo de propiedades del proyecto, haga clic en “Fuentes”, se sorprenderá al ver el ” Formato fuente / binario ” configurado en 1.5 y ” Codificación ” establecido en Windows 1250. Cambie el ” Formato fuente / binario ” a 1.6 0r 1.7, lo que usted prefiere hacer que su proyecto CDI sea compatible, y ” Codificación ” a UTF-8.

Haga lo mismo para todos los otros subproyectos (EAR, EJB, WAR) si aún no son compartibles. Ejecute su proyecto y no obtendrá ese error nuevamente.

Espero que esto ayude a alguien que tenga un error similar.

En mi caso, cometí un error de hechizo en @Named (“beanName”), se suponía que era “beanName”, pero escribí “beanNam”, por ejemplo.

Estoy usando wildfly 10 para el contenedor javaee. Experimenté el problema “Objetivo inalcanzable, ‘entidad’ devuelta nula ‘. Gracias por las sugerencias de BalusC, pero mi problema con las soluciones explicadas. Usar accidentalmente “import com.sun.istack.logging.Logger;” en lugar de “importar org.jboss.logging.Logger”; causado CDI implementado JSF EL. Espero que ayude a mejorar la solución.

Yo tuve el mismo problema. La solución resultó ser mucho más simple. Parece que una tabla de datos quiere el método en forma de getter, es decir, getSomeMethod (), no solo someMethod (). En mi caso, en la tabla de datos estaba llamando a findResults. Cambié el método en mi bean de respaldo a getFindResults () y funcionó.

Un CommandButton funcionó find sin el get, lo que sirvió para hacerlo aún más confuso.

Decidí compartir mi solución, porque aunque muchas respuestas proporcionadas aquí fueron útiles, todavía tenía este problema. En mi caso, estoy usando JSF 2.3, jdk10, jee8, cdi 2.0 para mi nuevo proyecto y ejecuté mi aplicación en wildfly 12, iniciando el servidor con el parámetro standalone.sh -Dee8.preview.mode = true como se recomienda en el sitio web de wildfly . El problema con “bean resuelto a nulo” desapareció después de descargar wildfly 13. Cargar exactamente la misma guerra a wildfly 13 hizo que todo funcionara.

Trabajar con JSF en el estilo antiguo Debe definir el bean administrado en el archivo beans-config.xml (ubicado en la carpeta WEB-INF) y hacer una referencia a él en el archivo web.xml , de esta manera:

beans-config.xml

  "the name by wich your backing bean will be referenced" "your backing bean fully qualified class name" session  

(He intentado usar otros ámbitos, pero …)

web.xml

  javax.faces.CONFIG_FILES "/WEB-INF/beans-config.xml  

Otra pista: estaba usando JSF y agregué dependencias mvn: com.sun.faces jsf-api 2.2.11

   com.sun.faces jsf-impl 2.2.11  

Luego, traté de cambiar a Primefaces y agregar la dependencia de Primefaces:

  org.primefaces primefaces 6.0  

Cambié mi xhtml de h: a p :, agregando xmlns: p = “http://primefaces.org/ui a la plantilla. Solo con JSF, el proyecto se estaba ejecutando bien, y se alcanzó el beans managed. Cuando agregué Primefaces Obtenía el objeto inalcanzable (javax.el.propertynotfoundexception). El problema era que JSF estaba generando ManagedBean, no Primefaces, y estaba pidiendo Primefaces para el objeto. Tuve que eliminar jsf-impl de mi .pom, limpiar y instale el proyecto. Todo salió bien desde este punto. Espero que eso ayude.

EL interpreta $ {bean.propretyName} como se describe – el propertyName se convierte en getPropertyName () suponiendo que está utilizando métodos explícitos o implícitos para generar getter / setters

Puede anular este comportamiento identificando explícitamente el nombre como una función: $ {bean.methodName ()} Esto llama al método de la función Nombre () directamente sin modificación.

No siempre es cierto que sus accesadores se llaman “obtener …”.