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 @ComponentLub @Named @ManagedBeanlub @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.xmlDeklaracja korzeń jest kompatybilny z JSF 2.0. Zatem plik XSD i plik versionmuszą 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_0i 2.0przez 2_1i 2.1odpowiednio.
Jeśli korzystasz z JSF 2.2 lub nowszego, upewnij się, że używasz xmlns.jcp.orgprzestrzeni nazw zamiast java.sun.comwszystkich 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_2i 2.2przez 2_3i 2.3odpowiednio.
Nie zaimportowałeś przypadkowo javax.annotation.ManagedBeanzamiast 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
@ManagedBeanstylu 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@ManagedBeanfaces-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.xmlzamiast @ManagedBean. Nie zapomnij o poprawieniu ścieżki budowania projektu jako takiej, że nie masz już bibliotek JSF 2.x (aby @ManagedBeanadnotacja 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.xmlpliku, 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.xmllub pustego beans.xmlpliku lub z powyższym kompatybilnym z CDI 1.0 beans.xmlbędzie zachowywać się tak samo jak CDI 1.0. Kiedy pojawia się CDI 1.1 zgodny beans.xmlz wyraźne version="1.1", to będzie domyślnie zarejestrować tylko @Namedfasolę 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.xmlz 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.RequestScopedzamiast 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ą @FacesConfigadnotację 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 varatrybutu (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 bindingatrybutu żadnego komponentu podrzędnego. Jest to niepoprawne, ponieważ bindingatrybut 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.
FooBeanKlasy 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.
FOOBeanKlasy 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, foojak 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 .classplik 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 .classplik musi znajdować się w, /WEB-INF/liba więc nie np. EAR /liblub gdzie indziej.
Jeśli używasz Eclipse, upewnij się, że klasa zapasowego komponentu bean jest włączona, srca 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/javaa zatem nie znajduje się w src/main/resourceslub 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ść entityjest #{bean.entity.property}zwracana null. Zwykle ujawnia to tylko wtedy, gdy JSF musi ustawić wartość za propertypoś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 @PostConstructlub <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 @PostConstructdo przechwytywania podczas inicjowania zarządzanego komponentu bean (i @PreDestroydo 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 entityIdjest 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 nullniemodel 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 nullna 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: