Beim Versuch, auf eine verwaltete Bean in EL wie #{bean.entity.property}
zu verweisen, wird manchmal eine javax.el.PropertyNotFoundException: Target Unreachable
-Ausnahme ausgelöst, normalerweise wenn eine Bean-Eigenschaft festgelegt wird oder wenn eine Bean-Aktion aufgerufen wird.
Es scheint fünf verschiedene Arten von Nachrichten zu geben:
Was meinen sie alle? Wie werden sie verursacht und wie sollten sie gelöst werden?
Dies läuft darauf hinaus, dass die verwaltete Bean-Instanz selbst nicht durch genau diesen Bezeichner (verwalteten Bean-Namen) in EL wie folgt gefunden werden konnte #{bean}
.
Das Erkennen der Ursache kann in drei Schritte unterteilt werden:
ein. Wer verwaltet die Bohne?
b. Wie lautet der (Standard-) Name der verwalteten Bean?
c. Wo ist die Backing Bean Klasse?
Der erste Schritt wäre zu überprüfen, welches Bean-Management-Framework für die Verwaltung der Bean-Instanz zuständig ist. Ist es [~ # ~] jsf [~ # ~] über @ManagedBean
? Oder ist es [~ # ~] cdi [~ # ~] über @Named
? Oder ist es Spring über @Component
? Können Sie sicherstellen, dass Sie nicht mehrere Bean-Management-Framework-spezifische Annotationen auf derselben Backing-Bean-Klasse mischen? Z.B. @Named @Component
Oder @Named @ManagedBean
Oder @ManagedBean @Component
. Das ist falsch. Die Bean muss von höchstens einem Bean Management Framework verwaltet werden und dieses Framework muss ordnungsgemäß konfiguriert sein. Wenn Sie bereits keine Ahnung haben, welche Sie auswählen sollen, gehen Sie zu Backing Beans (@ManagedBean) oder CDI Beans (@Named)? und Spring JSF-Integration: So fügen Sie eine Spring-Komponente/einen Spring-Service ein in JSF verwaltet Bean?
Falls es [~ # ~] jsf [~ # ~] ist, wer die Bean über @ManagedBean
Verwaltet, müssen Sie Folgendes sicherstellen:
Die Root-Deklaration faces-config.xml
Ist mit JSF 2.0 kompatibel. Die XSD-Datei und die version
müssen also mindestens JSF 2.0 oder höher und damit nicht 1.x angeben.
<faces-config
xmlns="http://Java.Sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://Java.Sun.com/xml/ns/javaee http://Java.Sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
Ersetzen Sie für JSF 2.1 einfach 2_0
Und 2.0
Durch 2_1
Bzw. 2.1
.
Wenn Sie mit JSF 2.2 oder höher arbeiten, stellen Sie sicher, dass Sie überall xmlns.jcp.org
- Namespaces anstelle von Java.Sun.com
Verwenden.
<faces-config
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"
version="2.2">
Für JSF 2.3 ersetzen Sie einfach 2_2
Und 2.2
Durch 2_3
Bzw. 2.3
.
Sie haben nicht versehentlich javax.annotation.ManagedBean
anstelle von javax.faces.bean.ManagedBean
importiert. Passen Sie mit IDE autocomplete, Eclipse ist dafür bekannt, dass es das falsche als erstes Element in der Liste automatisch empfiehlt.
@ManagedBean
- Wert nicht durch einen Eintrag im JSF 1.x-Stil <managed-bean>
In faces-config.xml
Für dieselbe Backing-Bean-Klasse zusammen mit einem anderen verwalteten Bean-Namen überschrieben. Dieser hat Vorrang vor @ManagedBean
. Das Registrieren einer verwalteten Bean in faces-config.xml
Ist nicht erforderlich, da JSF 2.0 diese einfach entfernt./META-INF/faces-config.xml
. Siehe auch Wie verweise ich auf JSF-verwaltete Beans, die in einer JAR-Datei enthalten sind?Wenn Sie tatsächlich das jurassic JSF 1.x verwenden und kein Upgrade durchführen können, müssen Sie das Bean über <managed-bean>
In faces-config.xml
Registrieren. anstelle von @ManagedBean
. Vergessen Sie nicht, Ihren Projekterstellungspfad so zu ändern, dass Sie keine JSF 2.x-Bibliotheken mehr haben (damit die Annotation @ManagedBean
Nicht verwirrend erfolgreich kompiliert werden kann).
Falls es [~ # ~] cdi [~ # ~] ist, wer die Bean über @Named
Verwaltet, müssen Sie Folgendes sicherstellen:
CDI 1.0 (Java EE 6) benötigt eine /WEB-INF/beans.xml
- Datei, um CDI in WAR zu aktivieren. Es kann leer sein oder nur den folgenden Inhalt haben:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://Java.Sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://Java.Sun.com/xml/ns/javaee
http://Java.Sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
CDI 1.1 (Java EE 7) ohne beans.xml
Oder eine leere beans.xml
- Datei oder mit der obigen CDI 1.0 kompatiblen beans.xml
Verhält sich wie folgt wie CDI 1.0. Wenn es ein CDI 1.1-kompatibles beans.xml
Mit einem expliziten version="1.1"
Gibt, registriert es standardmäßig nur @Named
Beans mit einen expliziten CDI-Bereich Anmerkung wie @RequestScoped
, @ViewScoped
, @SessionScoped
, @ApplicationScoped
usw. Wenn Sie beabsichtigen, alle Beans als von CDI verwaltete Beans zu registrieren, auch solche ohne expliziten CDI-Geltungsbereich, verwenden Sie die folgende CDI 1.1-kompatible /WEB-INF/beans.xml
Mit bean-discovery-mode="all"
gesetzt (die Standardeinstellung ist bean-discovery-mode="annotated"
).
<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
</beans>
Stellen Sie bei Verwendung von CDI 1.1+ mit bean-discovery-mode="annotated"
(Standardeinstellung) sicher, dass Sie nicht versehentlich einen JSF-Bereich wie javax.faces.bean.RequestScoped
anstelle eines CDI-Bereichs importiert haben. javax.enterprise.context.RequestScoped
. Achtung mit IDE autocomplete.
bean-discovery-mode="annotated"
(Standard) verwenden, müssen Sie Mojarra aufgrund eines Fehlers auf 2.3.3 oder neuer aktualisieren. Falls Sie kein Upgrade durchführen können, müssen Sie entweder bean-discovery-mode="all"
In beans.xml
Setzen oder die JSF 2.3-spezifische Annotation @FacesConfig
Für eine beliebige Klasse in WAR ( im Allgemeinen eine Art Startklasse mit Anwendungsbereich).Wenn Sie von CDI verwaltete Beans für JSF-Ansichten in eine JAR-Datei packen, stellen Sie sicher, dass die JAR-Datei mindestens einen gültigen /META-INF/beans.xml
Aufweist (der leer bleiben kann).
Falls es Spring ist, der die Bean über @Component
Verwaltet, müssen Sie Folgendes sicherstellen:
Spring wird installiert und gemäß seiner Dokumentation integriert. Wichtig ist, dass Sie mindestens Folgendes in web.xml
Haben:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Und das in faces-config.xml
:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
(über alles, was ich in Bezug auf Spring weiß - ich mache Spring nicht - zögern Sie nicht, andere wahrscheinliche Spring-Ursachen zu bearbeiten/zu kommentieren; z. B. Probleme mit der XML-Konfiguration)
Falls es sich um eine Repeater-Komponente handelt, die die (verschachtelte) Bean über ihr Attribut var
verwaltet (z. B. <h:dataTable var="item">
, <ui:repeat var="item">
, <p:tabView var="item">
, Etc) und Sie haben tatsächlich ein "Target Unreachable, Bezeichner 'item' zu null aufgelöst", dann müssen Sie Folgendes sicherstellen:
Auf #{item}
Wird in binding
einer untergeordneten Komponente nicht verwiesen. Dies ist falsch, da das Attribut binding
während der Erstellungszeit der Ansicht und nicht während der Renderzeit der Ansicht ausgeführt wird. Außerdem gibt es physikalisch nur eine Komponente im Komponentenbaum, die bei jeder Iterationsrunde einfach wiederverwendet wird. Mit anderen Worten, Sie sollten tatsächlich binding="#{bean.component}"
Anstelle von binding="#{item.component}"
Verwenden. Aber viel besser ist es, das Komponenten-Bining loszuwerden und den richtigen Ansatz für das Problem zu untersuchen/zu fragen, das Sie auf diese Weise gelöst haben. Siehe auch Wie funktioniert das Attribut 'binding' in JSF? Wann und wie sollte es verwendet werden?
Der zweite Schritt wäre die Überprüfung des registrierten verwalteten Bean-Namens. JSF- und Spring-Verwendungskonventionen sind konform JavaBeans-Spezifikation , während CDI je nach CDI-Impl/-Version Ausnahmen aufweist.
Eine Backing-Bean-Klasse FooBean
wie unten,
@Named
public class FooBean {}
wird in allen Bean-Management-Frameworks einen standardmäßig verwalteten Bean-Namen von #{fooBean}
gemäß JavaBeans-Spezifikation haben.
Eine Backing-Bean-Klasse FOOBean
wie unten,
@Named
public class FOOBean {}
wessen nicht qualifizierter Klassenname mit mindestens zwei Großbuchstaben beginnt, wird in JSF und Spring einen standardmäßig verwalteten Bean-Namen haben, der genau dem nicht qualifizierten Klassennamen #{FOOBean}
entspricht. In CDI ist dies auch in Weld-Versionen der Fall, die vor Juni 2015 veröffentlicht wurden, jedoch nicht in Weld-Versionen, die nach Juni 2015 veröffentlicht wurden (2.2.14/2.3.0.B1/3.0.0.A9), oder in OpenWebBeans aufgrund von ein Versehen in CDI-Spezifikation . In diesen Weld-Versionen und in allen OWB-Versionen wird nur das erste Zeichen in Kleinbuchstaben geschrieben #{fOOBean}
.
Wenn Sie einen verwalteten Bean-Namen foo
wie unten angegeben haben,
@Named("foo")
public class FooBean {}
oder gleichwertig mit @ManagedBean(name="foo")
oder @Component("foo")
, dann wird es nur von #{foo}
und damit nicht von #{fooBean}
.
Der dritte Schritt wäre ein Doppelcheck, wenn sich die Backing-Bean-Klasse an der richtigen Stelle in der erstellten und implementierten WAR-Datei befindet. Stellen Sie sicher, dass Sie das Projekt und den Server vollständig bereinigt, neu erstellt, erneut bereitgestellt und neu gestartet haben, falls Sie gerade mit dem Schreiben von Code beschäftigt waren und ungeduldig F5 im Browser drücken. Wenn dies immer noch vergebens ist, lassen Sie das Build-System eine WAR-Datei erstellen, die Sie dann extrahieren und mit einem Zip-Tool überprüfen. Die kompilierte .class
- Datei der Backing-Bean-Klasse muss sich in ihrer Paketstruktur in /WEB-INF/classes
Befinden. Oder wenn es als Teil eines JAR-Moduls gepackt ist, muss sich die JAR, die die kompilierte .class
- Datei enthält, in /WEB-INF/lib
Befinden und somit nicht z. EAR's /lib
Oder anderswo.
Wenn Sie Eclipse verwenden, stellen Sie sicher, dass sich die Backing-Bean-Klasse in src
und damit notWebContent
befindet, und stellen Sie sicher, dass Project > Automatisch erstellen ist aktiviert. Wenn Sie Maven verwenden, stellen Sie sicher, dass die Backing-Bean-Klasse in src/main/Java
Und damit not in src/main/resources
Oder src/main/webapp
Angegeben ist.
Wenn Sie die Webanwendung als Teil einer EAR mit EJB + WAR (s) packen, müssen Sie sicherstellen, dass sich die Backing-Bean-Klassen im WAR-Modul und somit nicht im EAR-Modul oder im EJB-Modul befinden. Die Business-Schicht (EJB) muss frei von WAR-Artefakten (Web-Schicht) sein, damit die Business-Schicht über mehrere verschiedene Web-Schichten (JSF, JAX-RS, JSP/Servlet usw.) hinweg wiederverwendbar ist.
Dies läuft darauf hinaus, dass die verschachtelt Eigenschaft entity
wie in #{bean.entity.property}
null
zurückgegeben wird. Dies wird normalerweise nur angezeigt, wenn JSF set den Wert für property
über eine Eingabekomponente wie unten festlegen muss, während #{bean.entity}
Tatsächlich null
.
<h:inputText value="#{bean.entity.property}" />
Sie müssen sicherstellen, dass Sie die Modellentität zuvor in einer @PostConstruct
- oder <f:viewAction>
- Methode oder, falls Sie mit einer add()
- Aktionsmethode arbeiten, vorbereitet haben CRUD-Listen und/oder -Dialoge in derselben Ansicht.
@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();
}
// ...
}
In Bezug auf die Bedeutung von @PostConstruct
; Wenn Sie dies in einem regulären Konstruktor tun, schlägt dies fehl, wenn Sie ein Bean-Management-Framework verwenden, das Proxies verwendet, z. B. CDI. Verwenden Sie immer @PostConstruct
, Um die Initialisierung der verwalteten Bean-Instanz einzubinden (und verwenden Sie @PreDestroy
, Um die Zerstörung der verwalteten Bean-Instanz einzubinden). Außerdem hätten Sie in einem Konstruktor noch keinen Zugriff auf injizierte Abhängigkeiten, siehe auch NullPointerException beim Versuch, auf die @Inject-Bean im Konstruktor zuzugreifen .
Wenn entityId
über <f:viewParam>
Bereitgestellt wird, müssen Sie <f:viewAction>
Anstelle von @PostConstruct
Verwenden. Siehe auch Wann wird f: viewAction/preRenderView im Vergleich zu PostConstruct verwendet?
Sie müssen auch sicherstellen, dass Sie das Nicht-Modell null
während der Postbacks beibehalten, falls Sie es nur in einer add()
-Aktionsmethode erstellen. Am einfachsten wäre es, die Bean in den Sichtbereich zu setzen. Siehe auch Wie wähle ich den richtigen Bean-Umfang aus?
Dies hat tatsächlich die gleiche Ursache wie # 2, nur die (ältere) EL-Implementierung, die verwendet wird, ist etwas fehlerhaft bei der Beibehaltung des Eigenschaftsnamens, der in der Ausnahmemeldung angezeigt werden soll, die letztendlich fälschlicherweise als 'null' angezeigt wird. Dies erschwert das Debuggen und Reparieren nur dann, wenn Sie einige verschachtelte Eigenschaften wie z. B. #{bean.entity.subentity.subsubentity.property}
Haben.
Die Lösung ist immer noch dieselbe: Stellen Sie sicher, dass die betreffende verschachtelte Entität nicht auf allen Ebenen null
ist.
Dies hat auch die gleiche Ursache wie # 2, nur die verwendete (ältere) EL-Implementierung ist bei der Formulierung der Ausnahmemeldung fehlerhaft. Dies wird nur angezeigt, wenn Sie die geschweifte Klammer []
In EL wie in #{bean.collection[index]}
Verwenden, wobei #{bean.collection}
Selbst nicht null ist, das Element am angegebenen Index jedoch nicht vorhanden ist . Eine solche Nachricht muss dann interpretiert werden als:
Das nicht erreichbare Ziel 'collection [0]' hat null zurückgegeben
Die Lösung entspricht auch der von Nummer 2: Stellen Sie sicher, dass das Sammlungsobjekt verfügbar ist.
Dies hat eigentlich die gleiche Ursache wie # 4, nur die (ältere) EL-Implementierung, die verwendet wird, ist etwas fehlerhaft, um den in der Ausnahmemeldung anzuzeigenden Iterationsindex beizubehalten, der letztendlich fälschlicherweise als 'BracketSuffix' angezeigt wird, was wirklich das Zeichen ]
. Dies erschwert das Debuggen und Reparieren nur dann, wenn sich mehrere Elemente in der Sammlung befinden.
javax.el.PropertyNotFoundException
:Für diejenigen, die noch feststecken ...
Bei der Verwendung von NetBeans 8.1 und GlassFish 4.1 mit CDI hatte ich dieses Problem aus irgendeinem Grund nur lokal, nicht auf dem Remote-Server. Was hat der Trick gemacht:
-> Verwenden von javaee-web-api 7.0 anstelle der von NetBeans bereitgestellten Standard-Pom-Version (javaee-web-api 6.0).
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
<type>jar</type>
</dependency>
-> Laden Sie diese Datei javaee-web-api-7.0.jar als lib auf den Server hoch (Ordner lib im Ordner domain1) und starten Sie den Server neu.
Ich entschied mich dazu, meine Feststellung zu diesem Fehler zu teilen, nachdem ich ihn selbst gelöst hatte.
Zunächst einmal sollten BalusC-Lösungen ernst genommen werden. In Netbeans ist jedoch ein weiteres Problem zu beachten, vor allem wenn Sie ein Enterprise Application Project (EAR) mit Maven erstellen.
Netbeans generiert eine Eltern-POM-Datei , ein EAR-Projekt , ein EJB-Projekt und ein WAR-Projekt . Alles andere in meinem Projekt war in Ordnung, und ich hätte fast angenommen, dass das Problem wahrscheinlich ein Fehler in GlassFish 4.0 ist (ich musste es installieren und in Netbeans einbinden), da GlassFish 4.1 einen Weld-CDI-Fehler hat, der das eingebettete GlassFish 4.1 in macht Netbeans 8.0.2 außer durch einen Patch unbrauchbar.
Lösung:
Um das "Ziel nicht erreichbar" aufzulösen, wurde der Bezeichner 'bean' in null aufgelöst. " Error-
I Klicken Sie mit der rechten Maustaste auf das übergeordnete POM-Projekt, und wählen Sie Properties aus. Ein Projekteigenschaften-Dialog wird angezeigt. Klicken Sie auf "Quellen". Sie werden überrascht sein, wenn " Quelle/Binärformat " auf 1,5 und " Encoding " auf Windows 1250 eingestellt ist Ändern Sie die " Quelle/Binärformat "bis 1,6 0r 1,7, je nachdem, was Sie bevorzugen, um Ihr Projekt CDI-kompatibel zu machen, und" Encoding "bis UTF-8.
Führen Sie dasselbe für alle anderen Teilprojekte (EAR, EJB, WAR) aus, wenn sie nicht bereits kompartierbar sind. Führen Sie Ihr Projekt aus, und Sie erhalten diesen Fehler nicht mehr.
Ich hoffe, das hilft jemandem, der einen ähnlichen Fehler hat.
Ich beschloss, meine Lösung mitzuteilen, denn obwohl viele Antworten hilfreich waren, hatte ich immer noch dieses Problem. In meinem Fall verwende ich für mein neues Projekt JSF 2.3, jdk10, jee8, cdi 2.0. Ich habe meine App auf wildfly 12 ausgeführt und den Server mit dem Parameter standalone.sh -Dee8.preview.mode = true gestartet, wie auf der Wildfly-Website empfohlen . Das Problem mit "Bean auf Null aufgelöst" verschwand nach dem Download von wildfly 13. Wenn genau derselbe Krieg in wildfly 13 hochgeladen wurde, funktionierte alles.
Ich verwende Wildfly 10 für Javaee-Container. Ich hatte ein Problem mit "Ziel unerreichbar, Entität hat null zurückgegeben". Danke für Anregungen von BalusC aber die mein Problem aus den Lösungen erklärt. Versehentliches Verwenden von "import com.Sun.istack.logging.Logger;" statt "import org.jboss.logging.Logger;" verursacht CDI implementiert JSF EL . Hoffe, es hilft, die Lösung zu verbessern.
In meinem Fall bestand das Problem darin, dass ich einen Konstruktor eingefügt hatte, der Parameter übernahm, aber keinen leeren Konstruktor mit der Inject-Annotation.
@Inject public VisitorBean() {}
Ich habe es gerade ohne Konstruktor getestet und das scheint auch zu funktionieren.
Für 1. topic (Target Unreachable, Bezeichner 'bean' in null aufgelöst);
Ich habe wertvolle Antworten auf den @BalusC und die anderen Sharer überprüft, aber ich überschreite dieses Problem in meinem Szenario. Nachdem ich ein neues XML mit einem anderen Namen und eine Bean-Klasse mit einem anderen Namen erstellt habe, habe ich die Codes Schritt für Schritt in die neue Bean-Klasse und die neue XML-Datei geschrieben (nicht kopiert und eingefügt).
Was Nr. 2 betrifft, so wurde es in meinem Fall magisch, nachdem er ersetzt wurde
<body>
tag mit
<h:body>
Nachdem ich mehrere (einfachere, um ehrlich zu sein) JSF-Projekte gemacht hatte, konnte ich mich nicht daran erinnern, irgendetwas anders gemacht zu haben, als ich es aufgesetzt hatte, und ich bekam diese Art Fehler zum ersten Mal. Ich habe eine sehr einfache Anmeldeseite (Benutzername, Passwort, Benutzer Bean ...) erstellt und alles wie gewohnt eingerichtet. Der einzige Unterschied, den ich entdeckt habe, sind die oben genannten Tags. Vielleicht findet jemand das nützlich.
Ich hatte das gleiche Problem. Die Lösung erwies sich als viel einfacher. Es scheint, dass eine Datentabelle die Methode in Form eines Getters haben will, dh getSomeMethod (), nicht nur someMethod (). In meinem Fall in der Datentabelle rief ich findResults an. Ich habe die Methode in meinem Backing Bean in getFindResults () geändert und es hat funktioniert.
Ein commandButton funktionierte find ohne den get, der dazu dient, es nur verwirrender zu machen.
In meinem Fall habe ich einen Zauberfehler in @Named ("beanName") begangen, es sollte "beanName" sein, aber ich schrieb beispielsweise "beanNam".