1. Cible inaccessible, identificateur «bean» résolu à null
Cela revient à dire que l'instance de bean géré elle-même n'a pas pu être trouvée exactement par cet identifiant (nom de bean géré) dans EL comme ça #{bean}
.
L'identification de la cause peut être décomposée en trois étapes:
une. Qui gère le haricot?
b. Quel est le nom du bean géré (par défaut)?
c. Où est la classe de backing bean?
1a. Qui gère le haricot?
La première étape serait de vérifier quel cadre de gestion de bean est responsable de la gestion de l'instance de bean. Est-ce JSF via @ManagedBean
? Ou est-ce CDI via @Named
? Ou est-ce le printemps via @Component
? Pouvez-vous vous assurer que vous ne mélangez pas plusieurs annotations spécifiques au framework de gestion de bean sur la même classe de bean de support? Par exemple @Named @Component
, ou @Named @ManagedBean
, ou @ManagedBean @Component
. C'est faux. Le bean doit être géré par au plus un framework de gestion de bean et ce framework doit être correctement configuré. Si vous ne savez déjà pas lequel choisir, dirigez-vous vers Backing beans (@ManagedBean) ou CDI Beans (@Named)? et intégration Spring JSF: comment injecter un composant / service Spring dans un bean géré JSF?
Dans le cas où c'est JSF qui gère le bean via @ManagedBean
, vous devez vous assurer de ce qui suit:
La faces-config.xml
déclaration racine est compatible avec JSF 2.0. Ainsi, le fichier XSD et le version
doivent au moins spécifier JSF 2.0 ou supérieur et donc pas 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">
Pour JSF 2.1, remplacez simplement 2_0
et 2.0
par 2_1
et 2.1
respectivement.
Si vous êtes sur JSF 2.2 ou supérieur, assurez-vous que vous utilisez des xmlns.jcp.org
espaces de noms au lieu de java.sun.com
partout.
<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">
Pour JSF 2.3, remplacez simplement 2_2
et 2.2
par 2_3
et 2.3
respectivement.
Vous n'avez pas importé accidentellement à la javax.annotation.ManagedBean
place de javax.faces.bean.ManagedBean
. Attention à la saisie semi-automatique de l'IDE, Eclipse est connu pour suggérer automatiquement le mauvais en tant que premier élément de la liste.
- Vous n'avez pas remplacé le
@ManagedBean
par une <managed-bean>
entrée de style JSF 1.x dans faces-config.xml
la même classe de bean de support avec un nom de bean géré différent. Celui-ci aura préséance sur @ManagedBean
. L'enregistrement d'un bean géré dans faces-config.xml
n'est pas nécessaire depuis JSF 2.0, il suffit de le supprimer.
- Votre chemin de classe d'exécution est propre et exempt de doublons dans les fichiers JAR liés à l'API JSF. Assurez-vous de ne pas mélanger plusieurs implémentations JSF (Mojarra et MyFaces). Assurez-vous de ne pas fournir un autre fichier JAR JSF ou même Java EE API le long de l'application Web lorsque le conteneur cible regroupe déjà l'API JSF. Voir aussi la section «Installation de JSF» de notre page wiki JSF pour les instructions d'installation de JSF. Dans le cas où vous avez l'intention de mettre à niveau JSF groupé avec le conteneur à partir du WAR au lieu du conteneur lui-même, assurez-vous que vous avez demandé au conteneur cible d'utiliser l'API JSF / impl.
- Si vous empaquetez des beans gérés JSF dans un JAR, assurez-vous que le JAR a au moins une compatibilité JSF 2.0
/META-INF/faces-config.xml
. Voir aussi Comment référencer les beans gérés JSF qui sont fournis dans un fichier JAR?
Si vous utilisez réellement le jurassic JSF 1.x et que vous ne pouvez pas mettre à niveau, vous devez enregistrer le bean via <managed-bean>
au faces-config.xml
lieu de @ManagedBean
. N'oubliez pas de corriger le chemin de construction de votre projet de manière à ne plus avoir de bibliothèques JSF 2.x (afin que l' @ManagedBean
annotation ne soit pas compilée avec succès).
Dans le cas où c'est CDI qui gère le bean via @Named
, vous devez vous assurer de ce qui suit:
CDI 1.0 (Java EE 6) nécessite un /WEB-INF/beans.xml
fichier pour activer CDI dans WAR. Il peut être vide ou contenir uniquement le contenu suivant:
<?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) sans aucun beans.xml
, ou un beans.xml
fichier vide , ou avec la compatibilité CDI 1.0 ci-dessus beans.xml
se comportera de la même manière que CDI 1.0. Quand il y a un CDI 1.1 compatible beans.xml
avec un explicite version="1.1"
, il sera par défaut uniquement enregistrer les @Named
haricots avec une annotation portée explicite de CDI tels que @RequestScoped
, @ViewScoped
, @SessionScoped
, @ApplicationScoped
, etc. Si vous avez l' intention d'enregistrer tous les haricots comme CDI a réussi les haricots, même sans explicite Portée CDI, utilisez le CDI 1.1 ci-dessous compatible /WEB-INF/beans.xml
avec bean-discovery-mode="all"
set (la valeur par défaut est 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>
Lorsque vous utilisez CDI 1.1+ avec bean-discovery-mode="annotated"
(par défaut), assurez-vous que vous n'avez pas importé accidentellement une portée JSF telle que la javax.faces.bean.RequestScoped
place d'une portée CDI javax.enterprise.context.RequestScoped
. Attention à la saisie semi-automatique IDE.
- Lorsque vous utilisez Mojarra 2.3.0-2.3.2 et CDI 1.1+ avec
bean-discovery-mode="annotated"
(par défaut), vous devez mettre à niveau Mojarra vers 2.3.3 ou plus récent en raison d'un bogue . Si vous ne pouvez pas mettre à niveau, vous devez soit ensemble bean-discovery-mode="all"
dans beans.xml
, ou de mettre le JSF 2.3 spécifique @FacesConfig
annotation sur une classe arbitraire dans la guerre ( en général une sorte d'une application scope classe démarrage).
- Les conteneurs non-Java EE tels que Tomcat et Jetty ne sont pas livrés avec CDI. Vous devez l'installer manuellement. C'est un peu plus de travail que d'ajouter simplement le (s) JAR (s) de la bibliothèque. Pour Tomcat, assurez-vous de suivre les instructions de cette réponse: Comment installer et utiliser CDI sur Tomcat?
- Votre chemin de classe d'exécution est propre et exempt de doublons dans les fichiers JAR liés à l'API CDI. Assurez-vous de ne pas mélanger plusieurs implémentations CDI (Weld, OpenWebBeans, etc.). Assurez-vous de ne pas fournir un autre fichier CDI ou même un fichier JAR API Java EE avec l'application Web lorsque le conteneur cible regroupe déjà l'API CDI.
Si vous empaquetez des beans gérés par CDI pour des vues JSF dans un JAR, assurez-vous que le JAR a au moins un fichier valide /META-INF/beans.xml
(qui peut être laissé vide).
Si c'est Spring qui gère le bean via @Component
, vous devez vous assurer des éléments suivants:
Spring est en cours d'installation et d'intégration conformément à sa documentation . Surtout, vous devez au moins avoir ceci dans web.xml
:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Et ceci dans faces-config.xml
:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
(ci-dessus est tout ce que je sais en ce qui concerne Spring - je ne fais pas Spring - n'hésitez pas à modifier / commenter d'autres causes probables liées à Spring; par exemple, des problèmes liés à la configuration XML)
Dans le cas où il est un composant répéteur qui gère les ressources (imbriqués) bean via son var
attribut (par exemple <h:dataTable var="item">
, <ui:repeat var="item">
, <p:tabView var="item">
, etc.) et vous avez réellement obtenu une « cible Inaccessible, identifiant « item » résolu null », alors vous devez vous assurer de ce qui suit :
Le #{item}
n'est référencé dans l' binding
attribut d'aucun composant enfant. Ceci est incorrect car l' binding
attribut s'exécute pendant la génération de la vue, et non pendant le rendu de la vue. De plus, il n'y a physiquement qu'un seul composant dans l'arborescence des composants qui est simplement réutilisé à chaque tour d'itération. En d'autres termes, vous devriez en fait utiliser à la binding="#{bean.component}"
place de binding="#{item.component}"
. Mais il est préférable de se débarrasser complètement de la combinaison des composants et de rechercher / demander la bonne approche pour le problème que vous pensiez résoudre de cette manière. Voir aussi Comment l'attribut 'binding' fonctionne-t-il dans JSF? Quand et comment doit-il être utilisé?
1b. Quel est le nom du bean géré (par défaut)?
La deuxième étape consisterait à vérifier le nom du bean géré enregistré. JSF et Spring utilisent les conventions conformes à la spécification JavaBeans tandis que CDI a des exceptions en fonction de l'impl / version de CDI.
Une FooBean
classe de backing bean comme ci-dessous,
@Named
public class FooBean {}
aura dans tous les frameworks de gestion de bean un nom de bean géré par défaut #{fooBean}
, selon la spécification JavaBeans.
Une FOOBean
classe de backing bean comme ci-dessous,
@Named
public class FOOBean {}
dont le nom de classe non qualifié commence par au moins deux majuscules aura dans JSF et Spring un nom de bean géré par défaut exactement le nom de classe non qualifié #{FOOBean}
, également conforme à la spécification JavaBeans. En CDI, c'est également le cas dans les versions Weld publiées avant juin 2015, mais pas dans les versions Weld publiées après juin 2015 (2.2.14 / 2.3.0.B1 / 3.0.0.A9) ni dans OpenWebBeans en raison d' un Spéc . CDI . Dans ces versions de Weld et dans toutes les versions OWB, c'est uniquement avec le premier caractère en minuscule #{fOOBean}
.
Si vous avez explicitement spécifié un nom de bean géré foo
comme ci-dessous,
@Named("foo")
public class FooBean {}
ou de manière équivalente avec @ManagedBean(name="foo")
ou @Component("foo")
, alors il ne sera disponible que par #{foo}
et donc pas par #{fooBean}
.
1c. Où est la classe de backing bean?
La troisième étape consisterait à vérifier si la classe du bean de support est au bon endroit dans le fichier WAR construit et déployé. Assurez-vous que vous avez correctement effectué un nettoyage complet, une reconstruction, un redéploiement et un redémarrage du projet et du serveur au cas où vous seriez réellement occupé à écrire du code et à appuyer avec impatience sur F5 dans le navigateur. Si toujours en vain, laissez le système de construction produire un fichier WAR, que vous extrayez et inspectez ensuite avec un outil ZIP. Le .class
fichier compilé de la classe du bean de sauvegarde doit résider dans sa structure de package dans /WEB-INF/classes
. Ou, lorsqu'il est empaqueté dans le cadre d'un module JAR, le JAR contenant le .class
fichier compilé doit résider dans /WEB-INF/lib
et donc pas par exemple EAR /lib
ou ailleurs.
Si vous utilisez Eclipse, assurez-vous que la classe de bean de support est dans src
et donc pas WebContent
, et assurez-vous que Projet> Construire automatiquement est activé. Si vous utilisez Maven, assurez-vous que la classe de backing bean est dans src/main/java
et donc pas dans src/main/resources
ou src/main/webapp
.
Si vous empaquetez l'application Web dans le cadre d'un EAR avec EJB + WAR (s), vous devez vous assurer que les classes de backing bean sont dans le module WAR et donc pas dans le module EAR ni dans le module EJB. Le niveau métier (EJB) doit être exempt d'artefacts liés au niveau Web (WAR), afin que le niveau métier soit réutilisable sur plusieurs niveaux Web différents (JSF, JAX-RS, JSP / Servlet, etc.).
2. Cible inaccessible, "entité" a renvoyé la valeur null
Cela revient à ce que la imbriquée propriété entity
comme dans #{bean.entity.property}
retour null
. Cela n'expose généralement que lorsque JSF doit définir la valeur de property
via un composant d'entrée comme ci-dessous, alors que le #{bean.entity}
fichier est effectivement retourné null
.
<h:inputText value="#{bean.entity.property}" />
Vous devez vous assurer que vous avez préparé l'entité de modèle au préalable dans une @PostConstruct
, ou une <f:viewAction>
méthode, ou peut-être une add()
méthode d'action au cas où vous travaillez avec des listes CRUD et / ou des boîtes de dialogue sur la même vue.
@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();
}
// ...
}
Quant à l'importance de @PostConstruct
; faire cela dans un constructeur normal échouerait si vous utilisez un cadre de gestion de bean qui utilise des proxies , tels que CDI. Toujours utiliser @PostConstruct
pour accrocher l'initialisation d'instance de bean géré (et utiliser @PreDestroy
pour accrocher la destruction d'instance de bean géré). De plus, dans un constructeur, vous n'auriez pas encore accès à des dépendances injectées, voir aussi NullPointerException en essayant d'accéder au bean @Inject dans le constructeur .
Si le entityId
est fourni via <f:viewParam>
, vous devez utiliser à la <f:viewAction>
place de @PostConstruct
. Voir aussi Quand utiliser f: viewAction / preRenderView par rapport à PostConstruct?
Vous devez également vous assurer de conserver le non- null
modèle pendant les publications au cas où vous le créeriez uniquement dans une add()
méthode d'action. Le plus simple serait de placer le bean dans l'étendue de la vue. Voir aussi Comment choisir la bonne portée de haricot?
3. Cible inaccessible, 'null' a renvoyé null
Cela a en fait la même cause que # 2, seule l'implémentation EL (plus ancienne) utilisée est quelque peu boguée en préservant le nom de la propriété à afficher dans le message d'exception, qui est finalement incorrectement exposé comme «null». Cela ne rend le débogage et la correction un peu plus difficiles que lorsque vous avez assez de propriétés imbriquées comme ça #{bean.entity.subentity.subsubentity.property}
.
La solution est toujours la même: assurez-vous que l'entité imbriquée en question ne l'est pas null
, à tous les niveaux.
4. Cible inaccessible, «0» a renvoyé null
Cela a également la même cause que # 2, seule l'implémentation EL (plus ancienne) utilisée est boguée dans la formulation du message d'exception. Cela expose uniquement lorsque vous utilisez la notation entre accolades []
dans EL comme dans #{bean.collection[index]}
lequel le #{bean.collection}
lui-même est non nul, mais l'élément à l'index spécifié n'existe pas. Un tel message doit alors être interprété comme:
Cible inaccessible, 'collection [0]' a renvoyé null
La solution est également la même que la n ° 2: assurez-vous que l'élément de collection est disponible.
5. Cible inaccessible, "BracketSuffix" a renvoyé null
Cela a en fait la même cause que le n ° 4, seule l'implémentation EL (plus ancienne) utilisée est quelque peu boguée dans la préservation de l'index d'itération à afficher dans le message d'exception, qui est finalement incorrectement exposé en tant que `` BracketSuffix '' qui est vraiment le caractère ]
. Cela ne rend le débogage et la correction un peu plus difficiles que lorsque vous avez plusieurs éléments dans la collection.
Autres causes possibles de javax.el.PropertyNotFoundException
: