1. Cel nieosiągalny, identyfikator „ziarno” rozwiązany na zero
Sprowadza się to do tego, że sama instancja zarządzanego komponentu bean nie mogła zostać znaleziona na podstawie dokładnie tego identyfikatora (nazwy zarządzanego komponentu bean) w EL #{bean}
.
Identyfikację przyczyny można podzielić na trzy etapy:
za. Kto zarządza fasolą?
b. Jaka jest (domyślna) nazwa zarządzanego komponentu bean?
do. Gdzie jest klasa fasoli?
1a. Kto zarządza fasolą?
Pierwszym krokiem byłoby sprawdzenie, które ramy zarządzania fasolą są odpowiedzialne za zarządzanie instancją fasoli. Czy to JSF przez @ManagedBean
? Czy jest to CDI przez @Named
? A może to wiosna przez @Component
? Czy możesz upewnić się, że nie mieszasz wielu adnotacji specyficznych dla platformy zarządzania bean w tej samej klasie fasoli zapasowej? Np. @Named @Component
Lub @Named @ManagedBean
lub @ManagedBean @Component
. To jest źle. Fasola musi być zarządzana przez co najwyżej jedną strukturę zarządzania fasolą i ta struktura musi być odpowiednio skonfigurowana. Jeśli nie masz już pojęcia, który wybrać, przejdź do Backing beans (@ManagedBean) lub CDI Beans (@Named)? i integracja Spring JSF: jak wprowadzić komponent / usługę Spring do komponentu bean zarządzanego przez JSF?
W przypadku, gdy jest to JSF, który zarządza fasolą za pośrednictwem @ManagedBean
, musisz upewnić się, że:
faces-config.xml
Deklaracja korzeń jest kompatybilny z JSF 2.0. Zatem plik XSD i plik version
muszą przynajmniej określać JSF 2.0 lub nowszy, a więc nie 1.x.
<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">
Dla JSF 2.1, wystarczy wymienić 2_0
i 2.0
przez 2_1
i 2.1
odpowiednio.
Jeśli korzystasz z JSF 2.2 lub nowszego, upewnij się, że używasz xmlns.jcp.org
przestrzeni nazw zamiast java.sun.com
wszystkich miejsc.
<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">
Dla JSF 2.3, wystarczy wymienić 2_2
i 2.2
przez 2_3
i 2.3
odpowiednio.
Nie zaimportowałeś przypadkowo javax.annotation.ManagedBean
zamiast javax.faces.bean.ManagedBean
. Uważaj na autouzupełnianie IDE, wiadomo, że Eclipse automatycznie sugeruje niewłaściwy element jako pierwszy element na liście.
- Nie przesłaniałeś wpisu w
@ManagedBean
stylu JSF 1.xw tej samej klasie zapasowego komponentu bean wraz z inną nazwą zarządzanego komponentu bean. Ten będzie miał pierwszeństwo przed . Rejestracja zarządzanego komponentu bean nie jest konieczna od czasu JSF 2.0, wystarczy ją usunąć.<managed-bean>
faces-config.xml
@ManagedBean
faces-config.xml
- Ścieżka klas środowiska wykonawczego jest czysta i wolna od duplikatów w plikach JAR związanych z interfejsem JSF API. Upewnij się, że nie mieszasz wielu implementacji JSF (Mojarra i MyFaces). Upewnij się, że nie udostępniasz innego pliku JAR JSF lub nawet Java EE API wraz z aplikacją internetową, gdy kontener docelowy zawiera już JSF API po wyjęciu z pudełka. Zobacz także sekcję „Instalowanie JSF” naszej strony wiki JSF, aby uzyskać instrukcje dotyczące instalacji JSF. W przypadku, gdy zamierzasz zaktualizować JSF w pakiecie z WAR zamiast w samym kontenerze, upewnij się, że poinstruowałeś kontener docelowy, aby używał JSF API / impl z pakietem WAR.
- Jeśli pakujesz fasolę zarządzaną przez JSF w JAR, upewnij się, że JAR ma co najmniej kompatybilny z JSF 2.0
/META-INF/faces-config.xml
. Zobacz także Jak odwoływać się do komponentów bean zarządzanych przez JSF, które są dostarczane w pliku JAR?
Jeśli faktycznie używając jurajskiego JSF 1.x, i nie można uaktualnić, potem musisz się zarejestrować poprzez fasoli <managed-bean>
w faces-config.xml
zamiast @ManagedBean
. Nie zapomnij o poprawieniu ścieżki budowania projektu jako takiej, że nie masz już bibliotek JSF 2.x (aby @ManagedBean
adnotacja nie była myląco pomyślna).
W przypadku, gdy to CDI zarządza fasolą przez @Named
, musisz upewnić się, że:
CDI 1.0 (Java EE 6) wymaga /WEB-INF/beans.xml
pliku, aby włączyć CDI w WAR. Może być pusty lub zawierać tylko następującą zawartość:
<?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) bez żadnego beans.xml
lub pustego beans.xml
pliku lub z powyższym kompatybilnym z CDI 1.0 beans.xml
będzie zachowywać się tak samo jak CDI 1.0. Kiedy pojawia się CDI 1.1 zgodny beans.xml
z wyraźne version="1.1"
, to będzie domyślnie zarejestrować tylko @Named
fasolę z wyraźnym CDI zakres adnotacji, takich jak @RequestScoped
, @ViewScoped
, @SessionScoped
, @ApplicationScoped
, itd. W przypadku, gdy zamierza zarejestrować wszystkie fasole jak CDI udało fasolę, nawet bez wyraźnego Zakres CDI, użyj poniższego CDI 1.1 kompatybilnego /WEB-INF/beans.xml
z bean-discovery-mode="all"
zestawem (domyślnie 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>
Używając CDI 1.1+ z bean-discovery-mode="annotated"
(domyślnie), upewnij się, że przypadkowo nie zaimportowałeś zakresu JSF, takiego jak javax.faces.bean.RequestScoped
zamiast zakresu CDI javax.enterprise.context.RequestScoped
. Uważaj na autouzupełnianie IDE.
- Używając Mojarra 2.3.0-2.3.2 i CDI 1.1+ z
bean-discovery-mode="annotated"
(domyślnie), musisz zaktualizować Mojarra do wersji 2.3.3 lub nowszej z powodu błędu . W przypadku, gdy nie można uaktualnić, to trzeba albo do zestawu bean-discovery-mode="all"
w beans.xml
, lub umieścić JSF 2.3 specyficzną @FacesConfig
adnotację na dowolnej klasy w czasie wojny (ogólnie jakaś aplikacji scoped klasę startową).
- Kontenery EE inne niż Java, takie jak Tomcat i Jetty, nie są dostarczane z pakietem CDI. Musisz go zainstalować ręcznie. To trochę więcej pracy niż tylko dodanie biblioteki JAR (ów). W przypadku Tomcat upewnij się, że postępujesz zgodnie z instrukcjami zawartymi w tej odpowiedzi: Jak zainstalować i używać CDI na Tomcat?
- Ścieżka klas środowiska wykonawczego jest czysta i wolna od duplikatów w plikach JAR związanych z interfejsem CDI API. Upewnij się, że nie mieszasz wielu implementacji CDI (Weld, OpenWebBeans itp.). Upewnij się, że nie udostępniasz innego pliku JAR CDI ani nawet pliku JAR interfejsu API Java EE wraz z aplikacją internetową, gdy kontener docelowy zawiera już interfejs API CDI po wyjęciu z pudełka.
Jeśli pakujesz fasolę zarządzaną przez CDI dla widoków JSF w JAR, upewnij się, że JAR ma co najmniej ważny /META-INF/beans.xml
(który można pozostawić pusty).
Jeśli to Spring zarządza fasolą za pośrednictwem @Component
, musisz upewnić się, że:
Spring jest instalowany i integrowany zgodnie z dokumentacją . Co ważne, musisz to mieć przynajmniej w web.xml
:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
A to w faces-config.xml
:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
(powyżej jest wszystko, co wiem w odniesieniu do Springa - nie robię Spring - nie krępuj się edytować / komentować z innymi prawdopodobnymi przyczynami związanymi ze Springiem; np. niektóre problemy związane z konfiguracją XML)
W przypadku, gdy jest to komponent repeater kto zarządzania (zagnieżdżone) fasolkę za pośrednictwem var
atrybutu (np <h:dataTable var="item">
, <ui:repeat var="item">
, <p:tabView var="item">
itp) i rzeczywiście dostał „docelowy jest nieosiągalny, identyfikator«pozycja»postanowił null”, to trzeba się upewnić, z następujących :
Nie #{item}
ma odniesienia do binding
atrybutu żadnego komponentu podrzędnego. Jest to niepoprawne, ponieważ binding
atrybut działa w czasie tworzenia widoku, a nie podczas renderowania widoku. Co więcej, fizycznie jest tylko jeden komponent w drzewie komponentów, który jest po prostu ponownie używany podczas każdej rundy iteracji. Innymi słowy, powinieneś używać binding="#{bean.component}"
zamiast binding="#{item.component}"
. Ale znacznie lepiej jest całkowicie pozbyć się wiązania komponentów do fasoli i zbadać / zapytać o właściwe podejście do problemu, który miałeś rozwiązać w ten sposób. Zobacz także Jak działa atrybut „binding” w JSF? Kiedy i jak należy go używać?
1b. Jaka jest (domyślna) nazwa zarządzanego komponentu bean?
Drugim krokiem byłoby sprawdzenie nazwy zarejestrowanej zarządzanej fasoli. Konwencje użycia JSF i Spring są zgodne ze specyfikacją JavaBeans, podczas gdy CDI ma wyjątki w zależności od wersji / impl / wersji CDI.
FooBean
Klasy podłoże fasoli jak niżej
@Named
public class FooBean {}
będzie we wszystkich strukturach zarządzania fasolami mieć domyślną nazwę zarządzanego komponentu bean #{fooBean}
, zgodnie ze specyfikacją JavaBeans.
FOOBean
Klasy podłoże fasoli jak niżej
@Named
public class FOOBean {}
których niekwalifikowana nazwa klasy zaczyna się od co najmniej dwóch wielkich liter, będzie w JSF i Spring miała domyślną nazwę zarządzanego komponentu bean o dokładnie takiej samej nazwie jak niekwalifikowana klasa #{FOOBean}
, a także będzie zgodna ze specyfikacją JavaBeans. W CDI dotyczy to również wersji Weld wydanych przed czerwcem 2015 r., Ale nie w wersjach Weld wydanych po czerwcu 2015 r. (2.2.14 / 2.3.0.B1 / 3.0.0.A9) ani w OpenWebBeans z powodu przeoczenia CDI spec . W tych wersjach Weld i we wszystkich wersjach OWB występuje tylko pierwsza mała litera #{fOOBean}
.
Jeśli jawnie określisz nazwę zarządzanego ziarna, foo
jak poniżej,
@Named("foo")
public class FooBean {}
lub równoważnie z @ManagedBean(name="foo")
lub @Component("foo")
, będzie dostępna tylko przez, #{foo}
a więc nie przez #{fooBean}
.
1c. Gdzie jest klasa fasoli?
Trzecim krokiem byłoby dwukrotne sprawdzenie, czy klasa zapasowego komponentu bean znajduje się we właściwym miejscu w zbudowanym i wdrożonym pliku WAR. Upewnij się, że poprawnie wykonałeś pełne czyszczenie, przebudowę, ponowne wdrożenie i ponowne uruchomienie projektu i serwera na wypadek, gdybyś był zajęty pisaniem kodu i niecierpliwym naciśnięciem klawisza F5 w przeglądarce. Jeśli nadal jest to na próżno, pozwól systemowi kompilacji utworzyć plik WAR, który następnie wyodrębnisz i sprawdzisz za pomocą narzędzia ZIP. Skompilowany .class
plik klasy zapasowego komponentu bean musi znajdować się w swojej strukturze pakietu w /WEB-INF/classes
. Lub, gdy jest spakowany jako część modułu JAR, JAR zawierający skompilowany .class
plik musi znajdować się w, /WEB-INF/lib
a więc nie np. EAR /lib
lub gdzie indziej.
Jeśli używasz Eclipse, upewnij się, że klasa zapasowego komponentu bean jest włączona, src
a zatem nie WebContent
, i upewnij się, że włączona jest opcja Projekt> Buduj automatycznie . Jeśli używasz Mavena, upewnij się, że klasa fasoli bazowej jest włączona, src/main/java
a zatem nie znajduje się w src/main/resources
lub src/main/webapp
.
Jeśli pakujesz aplikację internetową jako część EAR z EJB + WAR (y), musisz upewnić się, że klasy fasoli bazowej znajdują się w module WAR, a zatem nie w module EAR ani EJB. Warstwa biznesowa (EJB) musi być wolna od artefaktów związanych z warstwą WWW (WAR), tak aby warstwa biznesowa mogła być ponownie wykorzystywana na wielu różnych warstwach WWW (JSF, JAX-RS, JSP / Servlet itp.).
2. Cel nieosiągalny, „jednostka” zwróciła wartość null
Sprowadza się to do tego, że zagnieżdżona właściwość entity
jest #{bean.entity.property}
zwracana null
. Zwykle ujawnia to tylko wtedy, gdy JSF musi ustawić wartość za property
pośrednictwem komponentu wejściowego, takiego jak poniżej, podczas gdy #{bean.entity}
faktycznie zwracana null
.
<h:inputText value="#{bean.entity.property}" />
Musisz upewnić się, że jednostka modelu została wcześniej przygotowana w metodzie @PostConstruct
lub <f:viewAction>
, a może w add()
metodzie akcji w przypadku pracy z listami CRUD i / lub oknami dialogowymi w tym samym widoku.
@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();
}
// ...
}
Jeśli chodzi o znaczenie @PostConstruct
; zrobienie tego w zwykłym konstruktorze zakończy się niepowodzeniem w przypadku korzystania z platformy zarządzania bean, która używa serwerów proxy , takich jak CDI. Zawsze używaj @PostConstruct
do przechwytywania podczas inicjowania zarządzanego komponentu bean (i @PreDestroy
do przechwytywania podczas niszczenia zarządzanego komponentu bean). Ponadto w konstruktorze nie miałbyś jeszcze dostępu do żadnych wstrzykniętych zależności, zobacz także NullPointerException podczas próby uzyskania dostępu do komponentu bean @Inject w konstruktorze .
W przypadku, gdy entityId
jest dostarczany przez <f:viewParam>
, musisz użyć <f:viewAction>
zamiast @PostConstruct
. Zobacz także Kiedy używać f: viewAction / preRenderView a PostConstruct?
Musisz również upewnić się, że zachowujesz null
niemodel podczas ogłaszania zwrotnego, na wypadek gdyby tworzyłeś go tylko w add()
metodzie akcji. Najłatwiej byłoby umieścić fasolę w polu widzenia. Zobacz też Jak wybrać odpowiednią lunetę do fasoli?
3. Cel nieosiągalny, „null” zwrócił wartość null
Ma to faktycznie tę samą przyczynę, co # 2, tylko używana (starsza) implementacja EL jest nieco błędna w zachowaniu nazwy właściwości do wyświetlenia w komunikacie o wyjątku, który ostatecznie jest niepoprawnie ujawniony jako „null”. To tylko utrudnia debugowanie i naprawianie, gdy masz kilka zagnieżdżonych właściwości, takich jak ta #{bean.entity.subentity.subsubentity.property}
.
Rozwiązanie jest nadal takie samo: upewnij się, że dany element zagnieżdżony nie jest null
na wszystkich poziomach.
4. Cel nieosiągalny, „0” zwrócił wartość null
Ma to również tę samą przyczynę co # 2, tylko używana (starsza) implementacja EL jest błędna w formułowaniu komunikatu wyjątku. To uwidacznia tylko wtedy, gdy używasz notacji nawiasów klamrowych []
w EL, tak jak w #{bean.collection[index]}
przypadku, gdy #{bean.collection}
sam jest różny od null, ale element o określonym indeksie nie istnieje. Taką wiadomość należy wówczas interpretować jako:
Element docelowy nieosiągalny, „kolekcja [0]” zwróciła wartość null
Rozwiązanie jest również takie samo jak w # 2: upewnij się, że przedmiot kolekcji jest dostępny.
5. Target Unreachable, „BracketSuffix” zwrócił wartość null
Ma to faktycznie tę samą przyczynę, co # 4, tylko używana (starsza) implementacja EL jest nieco błędna w zachowaniu indeksu iteracji, który ma być wyświetlany w komunikacie o wyjątku, który ostatecznie jest nieprawidłowo ujawniany jako „BracketSuffix”, który jest w rzeczywistości znakiem ]
. To tylko utrudnia debugowanie i naprawianie, gdy w kolekcji znajduje się wiele elementów.
Inne możliwe przyczyny javax.el.PropertyNotFoundException
: