Identificazione e risoluzione di javax.el.PropertyNotFoundException: target irraggiungibile

Quando si tenta di fare riferimento a un bean gestito in EL come in questo modo #{bean.entity.property} , a volte javax.el.PropertyNotFoundException: Target Unreachable viene generata un’eccezione javax.el.PropertyNotFoundException: Target Unreachable , in genere quando viene impostata una proprietà bean o quando un’azione bean deve essere invocato.

Sembrano esserci cinque diversi tipi di messaggi:

  1. Target Unreachable, identificatore ‘bean’ risolto in null
  2. Target Unreachable, ‘entity’ ha restituito null
  3. Target Unreachable, ‘null’ restituito null
  4. Target Unreachable, ” 0 ” restituito null
  5. Target irraggiungibile, ‘BracketSuffix’ ha restituito null

Che cosa vogliono dire? Come sono causati e come dovrebbero essere risolti?

1. Target Unreachable, identificatore ‘bean’ risolto a null

Questo si riduce a ciò che l’istanza bean gestita non può essere trovata esattamente da quell’identificatore (nome bean gestito) in EL come in questo modo #{bean} .

Identificare la causa può essere suddiviso in tre passaggi:

un. Chi gestisce il fagiolo?
b. Qual è il nome del bean gestito (predefinito)?
c. Dov’è la class dei bean di supporto?

1 bis. Chi gestisce il fagiolo?

Il primo passo sarebbe verificare quale framework di gestione dei bean è responsabile della gestione dell’istanza del bean. È JSF tramite @ManagedBean ? O è CDI via @Named ? O è spring tramite @Component ? Puoi assicurarti di non mischiare annotazioni specifiche per framework di gestione di bean multipli sulla stessa class di bean backing? Ad esempio @Named @Component o @Named @ManagedBean o @ManagedBean @Component . Questo è sbagliato. Il bean deve essere gestito dalla maggior parte di un framework di gestione dei bean e tale framework deve essere configurato correttamente. Se non hai ancora idea di quale scegliere, vai su Backing beans (@ManagedBean) o CDI Beans (@Named)? e Spring JSF integration: come iniettare un componente / servizio Spring nel bean gestito JSF?

Nel caso in cui sia JSF a gestire il bean tramite @ManagedBean , è necessario accertarsi di quanto segue:

  • La dichiarazione radice faces-config.xml è compatibile con JSF 2.0. Quindi il file XSD e la version devono almeno specificare JSF 2.0 o superiore e quindi non 1.x.

      

    Per JSF 2.1, basta sostituire 2_0 e 2.0 con 2_1 e 2.1 .

    Se utilizzi JSF 2.2 o versioni successive, assicurati di utilizzare xmlns.jcp.org spazi dei nomi xmlns.jcp.org anziché java.sun.com in qualsiasi posizione.

      

    Per JSF 2.3, basta sostituire 2_2 e 2.2 di 2_3 e 2.3 rispettivamente.

  • Non hai importato accidentalmente javax.annotation.ManagedBean anziché javax.faces.bean.ManagedBean . Attenzione con il completamento automatico IDE, è noto che Eclipse esegue automaticamente l’errore come primo elemento nell’elenco.

  • Non è stato eseguito l’override di @ManagedBean da una voce JSF 1.x in faces-config.xml sulla stessa class di bean di supporto insieme a un nome di bean gestito diverso. Questo avrà la precedenza su @ManagedBean . La registrazione di un bean gestito in faces-config.xml non è necessaria dal momento che JSF 2.0, è sufficiente rimuoverlo.
  • Il classpath di runtime è pulito e privo di duplicati nei JAR relativi all’API JSF. Assicurati di non mischiare più implementazioni JSF (Mojarra e MyFaces). Assicurati di non fornire un altro file JAR JSF o Java EE API lungo la webapp quando il contenitore di destinazione già raggruppa l’API JSF fuori dalla scatola. Vedi anche la sezione “Installazione JSF” della nostra pagina wiki JSF per le istruzioni di installazione di JSF. Nel caso in cui si intenda aggiornare JSF con contenitore in bundle dal WAR on invece che nel container stesso, assicurarsi di aver istruito il contenitore di destinazione per l’uso di API / impl JSF in bundle WAR.
  • Se impacchettate i bean JSF in un JAR, assicuratevi che JAR abbia almeno un JSF 2.0 compatibile / /META-INF/faces-config.xml . Vedi anche Come fare riferimento ai bean gestiti JSF che sono forniti in un file JAR?
  • Se si sta utilizzando il Jass 1.x giurassico e non è ansible eseguire l’aggiornamento, è necessario registrare il bean tramite in faces-config.xml anziché in @ManagedBean . Non dimenticare di aggiustare il percorso di costruzione del progetto in modo tale da non avere più librerie JSF 2.x (in modo che l’annotazione @ManagedBean non possa essere compilata in modo confuso).


Nel caso in cui sia il CDI a gestire il bean tramite @Named , è necessario accertarsi di quanto segue:

  • CDI 1.0 (Java EE 6) richiede un file /WEB-INF/beans.xml per abilitare il CDI in WAR. Può essere vuoto o può avere solo il seguente contenuto:

        
  • CDI 1.1 (Java EE 7) senza beans.xml , o un file beans.xml vuoto, o con il beans.xml compatibile con CDI 1.0 sopra, si comportano come CDI 1.0. Quando è presente un bean.xml compatibile con CDI 1.1 con una version="1.1" esplicita version="1.1" , per impostazione predefinita registrerà solo i bean @Named con un’annotazione esplicita dell’ambito CDI come @RequestScoped , @ViewScoped , @SessionScoped , @ApplicationScoped , ecc. Nel caso in cui si intendano registrare tutti i bean come bean gestiti CDI, anche quelli senza un ambito CDI esplicito, utilizzare il sotto compatibile CDI 1.1 /WEB-INF/beans.xml con bean-discovery-mode="all" set (il valore predefinito è bean-discovery-mode="annotated" ).

        
  • Quando si utilizza CDI 1.1+ con bean-discovery-mode="annotated" (predefinito), assicurarsi di non aver importato accidentalmente un ambito JSF come javax.faces.bean.RequestScoped invece di un ambito CDI javax.enterprise.context.RequestScoped . Attenzione con il completamento automatico IDE.

  • Quando si utilizza Mojarra 2.3.0-2.3.2 e CDI 1.1+ con bean-discovery-mode="annotated" (predefinito), è necessario aggiornare Mojarra alla 2.3.3 o più recente a causa di un bug . Nel caso in cui non sia ansible eseguire l’aggiornamento, è necessario impostare bean-discovery-mode="all" in beans.xml o inserire l’annotazione @FacesConfig specifica di JSF 2.3 su una class arbitraria in WAR (generalmente una sorta di una class di avvio con ambito applicazione).
  • I contenitori EE non Java come Tomcat e Jetty non vengono spediti con CDI in bundle. Devi installarlo manualmente. È un po ‘più di lavoro che aggiungere la libreria JAR (s). Per Tomcat, assicurati di seguire le istruzioni in questa risposta: Come installare e utilizzare CDI su Tomcat?
  • Il classpath di runtime è pulito e privo di duplicati nei JAR relativi all’API CDI. Assicurati di non mischiare più implementazioni CDI (Weld, OpenWebBeans, ecc.). Accertati di non fornire un altro file JAR CDI o Java EE Java lungo webapp quando il contenitore di destinazione include già l’API CDI fuori dalla scatola.
  • Se impacchettate i bean gestiti da CDI per le viste JSF in un JAR, assicuratevi che il JAR abbia almeno un /META-INF/beans.xml valido (che può essere mantenuto vuoto).


Nel caso in cui sia Spring a gestire il bean tramite @Component , è necessario accertarsi di quanto segue:

  • La spring viene installata e integrata come da documentazione . È importante notare che è necessario averlo almeno in web.xml :

      org.springframework.web.context.ContextLoaderListener  

    E questo in faces-config.xml :

      org.springframework.web.jsf.el.SpringBeanFacesELResolver  
  • (qui sopra tutto ciò che so per quanto riguarda Spring – non lo faccio Spring – sentiti libero di modificare / commentare con altre probabili cause correlate a Spring, ad esempio alcuni problemi relativi alla configurazione XML)


Nel caso in cui si di un componente ripetitore che gestisce il bean (nidificato) tramite l’attributo var (ad esempio , , , ecc. e in effetti hai ottenuto un “object irraggiungibile, identificatore” risolto su null “, quindi devi accertarti di quanto segue:

  • #{item} Item #{item} non è referenziato nell’attributo di attributo di alcun componente figlio. Questo non è corretto poiché binding attributo di binding viene eseguito durante il tempo di creazione della vista, non durante il tempo di rendering della vista. Inoltre, vi è fisicamente solo un componente nell’albero dei componenti che viene semplicemente riutilizzato durante ogni iterazione. In altre parole, dovresti effettivamente utilizzare binding="#{bean.component}" invece di binding="#{item.component}" . Ma molto meglio è sbarazzarsi del componente che si lega al fagiolo e indagare / chiedere l’approccio corretto per il problema che si pensava di risolvere in questo modo. Vedi anche Come funziona l’attributo ‘binding’ in JSF? Quando e come dovrebbe essere usato?


1b. Qual è il nome del bean gestito (predefinito)?

Il secondo passo sarebbe il controllo del nome del bean gestito registrato. Le convenzioni di utilizzo JSF e Spring conformano le specifiche JavaBeans mentre CDI ha eccezioni dipendenti dalla impl / versione CDI.

  • Una class di bean backing FooBean come sotto,

     @Named public class FooBean {} 

    in tutti i framework di gestione dei bean avrà un nome di bean gestito predefinito di #{fooBean} , come specificato dalla specifica JavaBeans.

  • Una class di bean backing FOOBean come sotto,

     @Named public class FOOBean {} 

    il cui nome di class non qualificato inizia con almeno due maiuscole in JSF e Spring hanno un nome di bean gestito predefinito di esattamente il nome di class non qualificato #{FOOBean} , conformano anche la specificazione di JavaBeans. In CDI, questo è anche il caso nelle versioni di Weld rilasciate prima di giugno 2015, ma non nelle versioni di Weld rilasciate dopo giugno 2015 (2.2.14 / 2.3.0.B1 / 3.0.0.A9) né in OpenWebBeans a causa di una svista in Spec . CDI In quelle versioni di saldatura e in tutte le versioni di OWB è solo con il primo carattere in maiuscolo #{fOOBean} .

  • Se hai specificato esplicitamente un nome bean gestito foo come di seguito,

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

    o equivalentemente con @ManagedBean(name="foo") o @Component("foo") , quindi sarà disponibile solo da #{foo} e quindi non da #{fooBean} .


1 quater. Dov’è la class dei bean di supporto?

Il terzo passo sarebbe il doppio controllo se la class del bean backing si trova nel posto giusto nel file WAR generato e distribuito. Assicurati di aver eseguito correttamente una pulizia completa, ricostruisci, ridistribuisci e riavvia il progetto e il server nel caso in cui eri effettivamente impegnato a scrivere codice e a premere impazientemente F5 nel browser. Se ancora invano, lascia che il sistema di generazione produca un file WAR, che poi estrai e controlli con uno strumento ZIP. Il file .class compilato della class bean backing deve risiedere nella sua struttura del pacchetto in /WEB-INF/classs . Oppure, quando è impacchettato come parte di un modulo JAR, il JAR contenente il file .class compilato deve risiedere in /WEB-INF/lib e quindi non ad es. EAR /lib o altrove.

Se utilizzi Eclipse, assicurati che la class del bean backing sia in src e quindi non in WebContent e assicurati che Project> Build Automatically sia abilitato. Se stai usando Maven, assicurati che la class del bean backing sia in src/main/java e quindi non in src/main/resources o src/main/webapp .

Se impacchettate l’applicazione web come parte di un EAR con EJB + WAR (s), allora dovete assicurarvi che le classi dei bean backing siano nel modulo WAR e quindi non nel modulo EAR né nel modulo EJB. Il livello aziendale (EJB) deve essere privo di qualsiasi artefatto correlato al livello Web (WAR), in modo che il livello aziendale sia riutilizzabile su più livelli Web diversi (JSF, JAX-RS, JSP / Servlet, ecc.).


2. Target Unreachable, ‘entity’ restituito null

Questo si riduce a questo l’ entity proprietà nidificata come in #{bean.entity.property} restituito null . Questo di solito si espone solo quando JSF ha bisogno di impostare il valore per la property tramite un componente di input come sotto, mentre il #{bean.entity} restituisce effettivamente null .

  

Devi assicurarti di aver preparato in anticipo l’ quadro del modello in un @PostConstruct , o , o forse un metodo di azione add() nel caso tu stia lavorando con elenchi e / o windows di dialogo CRUD sulla stessa 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(); } // ... } 

Per quanto riguarda l’importanza di @PostConstruct ; fare questo in un costruttore normale fallirebbe nel caso in cui si stia utilizzando un framework di gestione dei bean che utilizza proxy , come CDI. Usa sempre @PostConstruct per agganciare l’inizializzazione dell’istanza bean gestita (e usa @PreDestroy per @PreDestroy distruzione dell’istanza bean gestita). Inoltre, in un costruttore non avresti ancora accesso ad alcuna dipendenza iniettata, vedi anche NullPointerException mentre provi ad accedere al bean @Inject nel costruttore .

Nel caso in cui entityId sia fornito tramite , è necessario utilizzare anziché @PostConstruct . Vedi anche Quando usare f: viewAction / preRenderView contro PostConstruct?

È inoltre necessario assicurarsi di conservare il modello non null durante i postback nel caso in cui lo si crei solo con un metodo di azione add() . La cosa più semplice sarebbe mettere il bean nell’ottica della vista. Vedi anche Come scegliere l’ambito del bean giusto?


3. Target Unreachable, ‘null’ restituito null

Questo ha in realtà la stessa causa del # 2, solo l’implementazione EL (più vecchia) utilizzata è un po ‘buggata nel preservare il nome della proprietà da visualizzare nel messaggio di eccezione, che alla fine viene erroneamente esposto come’ null ‘. Questo rende solo il debug e il fixing un po ‘più difficile quando hai alcune proprietà nidificate come la #{bean.entity.subentity.subsubentity.property} .

La soluzione è sempre la stessa: assicurati che l’ quadro nidificata in questione non sia null , a tutti i livelli.


4. Target Unreachable, ” 0 ” restituito null

Questo ha anche la stessa causa del # 2, solo l’implementazione EL (più vecchia) che si sta usando è buggata nel formulare il messaggio di eccezione. Questo espone solo quando si utilizza la notazione brace [] in EL come in #{bean.collection[index]} dove il #{bean.collection} stesso non è nullo, ma l’elemento nell’indice specificato non esiste. Tale messaggio deve quindi essere interpretato come:

Target Unreachable, ‘collection [0]’ restituito null

La soluzione è anche la seconda: assicurati che l’elemento della collezione sia disponibile.


5. Target Unreachable, ‘BracketSuffix’ ha restituito null

Questo ha in realtà la stessa causa del # 4, solo l’implementazione (più vecchia) EL utilizzata è un po ‘buggata nel preservare l’indice di iterazione da visualizzare nel messaggio di eccezione, che alla fine è erroneamente esposto come “BracketSuffix” che è realmente il personaggio ] . Questo rende solo il debug e il fissaggio un po ‘più difficile quando hai più elementi nella collezione.


Altre possibili cause di javax.el.PropertyNotFoundException :

  • javax.el.ELException: errore nella lettura di ‘foo’ sul tipo com.example.Bean
  • javax.el.ELException: imansible trovare la proprietà actionMethod nella class com.example.Bean
  • javax.el.PropertyNotFoundException: proprietà ‘foo’ non trovata sul tipo com.example.Bean
  • javax.el.PropertyNotFoundException: proprietà ‘foo’ non leggibile sul tipo java.lang.Boolean
  • javax.el.PropertyNotFoundException: proprietà non trovata sul tipo org.hibernate.collection.internal.PersistentSet
  • Il codice di Facelets sconnesso richiama ancora espressioni EL come # {bean.action ()} e causa javax.el.PropertyNotFoundException su # {bean.action}

Per quelli che sono ancora bloccati …

Utilizzando NetBeans 8.1 e GlassFish 4.1 con CDI, per qualche motivo ho riscontrato questo problema solo localmente, non sul server remoto. Che cosa ha fatto il trucco:

-> utilizzando javaee-web-api 7.0 invece della versione pom predefinita fornita da NetBeans, che è javaee-web-api 6.0, quindi:

  javax javaee-web-api 7.0 provided jar  

-> carica questo javaee-web-api-7.0.jar come lib sul server (cartella lib nella cartella domain1) e riavvia il server.

Ho deciso di condividere la mia scoperta su questo errore dopo averlo risolto da solo.

Prima di tutto, le soluzioni BalusC dovrebbero essere prese sul serio, ma c’è un altro problema probabile in Netbeans da tenere presente soprattutto quando si costruisce un EAR (Enterprise Application Project) usando Maven.

Netbeans genera, un file POM padre , un progetto EAR , un progetto EJB e un progetto WAR . Tutto il resto del mio progetto andava bene, e ho quasi pensato che il problema fosse un bug probabilmente in GlassFish 4.0 (dovevo installarlo e collegarlo a Netbeans) perché GlassFish 4.1 ha un bug di CDI di saldatura che rende GlassFish 4.1 incorporato in Netbeans 8.0. 2 inutilizzabile tranne attraverso una patch.

Soluzione:

Per risolvere il problema “Target irraggiungibile, identificatore ‘bean’ risolto in null “-

I Fare clic con il tasto destro del mouse sul progetto padre POM e selezionare Proprietà . Viene visualizzata una finestra di dialogo Proprietà del progetto, fai clic su “Sorgenti”, sarai sorpreso di vedere il ” Formato sorgente / binario ” impostato su 1.5 e ” Codifica ” impostato su Windows 1250. Modificare ” Formato origine / binario ” su 1.6 0r 1.7, qualunque sia preferisci rendere il tuo progetto compatibile con CDI e ” Codifica ” in UTF-8.

Fai lo stesso per tutti gli altri sottoprogetti (EAR, EJB, WAR) se non sono già comparabili. Esegui il tuo progetto e non riceverai più quell’errore.

Spero che questo aiuti qualcuno là fuori che ha un errore simile.

Nel mio caso, ho commesso un errore ortografico in @Named (“beanName”), si supponeva che fosse “beanName”, ma ho scritto “beanNam”, ad esempio.

Sto usando wildfly 10 per il contenitore javaee. Ho riscontrato un problema di “Obiettivo irraggiungibile”, quadro “restituita nulla”. Grazie per i suggerimenti di BalusC ma il mio problema per le soluzioni è stato spiegato. Uso accidentalmente “import com.sun.istack.logging.Logger;” invece di “import org.jboss.logging.Logger;” ha causato l’implementazione di CD JSF EL. Spero che aiuti a migliorare la soluzione.

Ho avuto lo stesso problema. La soluzione si è rivelata molto più semplice. Sembra che un datatable desideri il metodo sotto forma di getter, cioè getSomeMethod (), non solo someMethod (). Nel mio caso nel datatable stavo chiamando findResults. Ho cambiato il metodo nel mio backing bean per getFindResults () e ha funzionato.

Un comando command ha funzionato find senza l’get che è servito a renderlo solo più confuso.

Ho deciso di condividere la mia soluzione, perché anche se molte risposte fornite qui sono state utili, ho ancora avuto questo problema. Nel mio caso, sto utilizzando JSF 2.3, jdk10, jee8, cdi 2.0 per il mio nuovo progetto e ho eseguito la mia app su wildfly 12, avviando il server con parametro standalone.sh -Dee8.preview.mode = true come consigliato sul sito Web di wildfly . Il problema con “bean resolved to null” è scomparso dopo aver scaricato wildfly 13. Caricare esattamente la stessa guerra in wildfly 13 ha reso tutto funzionante.

Lavorare con JSF nel vecchio stile È necessario definire il bean gestito nel file beans-config.xml (che si trova nella cartella WEB-INF) e fare riferimento ad esso nel file web.xml , in questo modo:

fagioli-config.xml

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

(Ho provato ad usare altri ambiti, ma …)

web.xml

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

Un altro indizio: stavo usando JSF e ho aggiunto le dipendenze di mvn: com.sun.faces jsf-api 2.2.11

   com.sun.faces jsf-impl 2.2.11  

Quindi, ho provato a passare a Primefaces e ad aggiungere una dipendenza primefaces:

  org.primefaces primefaces 6.0  

Ho cambiato il mio xhtml da h: a p :, aggiungendo xmlns: p = “http://primefaces.org/ui al modello Solo con JSF il proyect era in esecuzione ok e il managedbean è stato raggiunto ok Quando aggiungo Primefaces Stavo ottenendo l’object irraggiungibile (javax.el.propertynotfoundexception) .Il problema era che JSF stava generando il ManagedBean, non Primefaces, e stavo chiedendo le primefaces per l’object.Ho dovuto eliminare jsf-impl dal mio .pom, pulito e installa il proyect. Tutto è andato bene da questo punto. Spero che questo aiuti.

EL interpreta $ {bean.propretyName} come descritto – il propertyName diventa getPropertyName () sul presupposto che stai usando metodi espliciti o impliciti per generare getter / setter

È ansible sovrascrivere questo comportamento identificando esplicitamente il nome come funzione: $ {bean.methodName ()} Ciò chiama direttamente il metodo function Name () senza modifiche.

Non è sempre vero che i tuoi accessors sono chiamati “get …”.