1. Alvo inacessível, identificador 'bean' resolvido como nulo
Isso se resume a que a própria instância do bean gerenciado não pôde ser encontrada exatamente por esse identificador (nome do bean gerenciado) no EL dessa forma #{bean}
.
A identificação da causa pode ser dividida em três etapas:
uma. Quem está gerenciando o feijão?
b. Qual é o nome do bean gerenciado (padrão)?
c. Onde está a classe de backing bean?
1a. Quem está gerenciando o feijão?
O primeiro passo seria verificar qual estrutura de gerenciamento de bean é responsável por gerenciar a instância do bean. É JSF via @ManagedBean
? Ou é via CDI@Named
? Ou é Primavera via @Component
? Você pode ter certeza de que não está misturando várias anotações específicas da estrutura de gerenciamento de bean na mesma classe de bean de backup? Por exemplo @Named @Component
, ou @Named @ManagedBean
, ou @ManagedBean @Component
. Isto está errado. O bean deve ser gerenciado por no máximo uma estrutura de gerenciamento de beans e essa estrutura deve ser configurada corretamente. Se você já não tem idéia de qual escolher, vá para Backing beans (@ManagedBean) ou CDI Beans (@Named)? e integração Spring JSF: como injetar um componente / serviço Spring no bean gerenciado JSF?
Caso seja o JSF quem está gerenciando o bean via @ManagedBean
, será necessário garantir o seguinte:
A faces-config.xml
declaração raiz é compatível com o JSF 2.0. Portanto, o arquivo XSD e o version
deve especificar pelo menos JSF 2.0 ou superior e, portanto, não 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">
Para o JSF 2.1, basta substituir 2_0
e 2.0
por 2_1
e 2.1
respectivamente.
Se você estiver no JSF 2.2 ou superior, verifique se está usando xmlns.jcp.org
espaços para nome em vez de java.sun.com
em todo lugar.
<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">
Para o JSF 2.3, basta substituir 2_2
e 2.2
por 2_3
e 2.3
respectivamente.
Você não importou acidentalmente em javax.annotation.ManagedBean
vez de javax.faces.bean.ManagedBean
. Cuidado com o preenchimento automático do IDE, o Eclipse é conhecido por sugerir automaticamente o errado como o primeiro item da lista.
- Você não substituiu a entrada de
@ManagedBean
estilo JSF 1.x <managed-bean>
na faces-config.xml
mesma classe de bean de backup, juntamente com um nome de bean gerenciado diferente. Este terá precedência @ManagedBean
. O registro de um bean gerenciado faces-config.xml
não é necessário desde o JSF 2.0, basta removê-lo.
- Seu caminho de classe de tempo de execução está limpo e livre de duplicatas nos JARs relacionados à API JSF. Certifique-se de não misturar várias implementações JSF (Mojarra e MyFaces). Certifique-se de não fornecer outro arquivo JAR da API JSF ou Java EE ao longo do aplicativo da web quando o contêiner de destino já empacota a API JSF imediatamente. Consulte também a seção "Instalando o JSF" da nossa página wiki do JSF para obter instruções de instalação do JSF. Caso você pretenda atualizar o JSF empacotado em contêiner a partir do WAR em vez de no contêiner propriamente dito, certifique-se de ter instruído o contêiner de destino a usar a API / impl JSF empacotado em pacote empacotado por WAR.
- Se você estiver empacotando beans gerenciados por JSF em um JAR, verifique se o JAR possui pelo menos um compatível com JSF 2.0
/META-INF/faces-config.xml
. Consulte também Como referenciar beans gerenciados JSF que são fornecidos em um arquivo JAR?
Se você estiver realmente usando o JSF 1.x jurássico e não puder atualizar, precisará registrar o bean via <managed-bean>
in em faces-config.xml
vez de @ManagedBean
. Não se esqueça de corrigir o caminho de construção do projeto para que você não tenha mais bibliotecas JSF 2.x (para que a @ManagedBean
anotação não seja compilada com êxito de maneira confusa).
Caso seja o CDI que está gerenciando o bean via @Named
, você precisa se certificar do seguinte:
O CDI 1.0 (Java EE 6) requer um /WEB-INF/beans.xml
arquivo para ativar o CDI no WAR. Pode estar vazio ou pode ter apenas o seguinte conteúdo:
<?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>
O CDI 1.1 (Java EE 7) sem nenhum arquivo beans.xml
vazio beans.xml
ou com o CDI 1.0 acima compatível beans.xml
se comportará da mesma maneira que o CDI 1.0. Quando há um CDI 1.1 compatível beans.xml
com um explícita version="1.1"
, então ele vai por padrão, somente registar @Named
feijão com uma anotação âmbito CDI explícita, como @RequestScoped
, @ViewScoped
, @SessionScoped
, @ApplicationScoped
, etc. No caso de você pretende registrar todos os grãos como CDI managed beans, mesmo aqueles sem uma explícita Escopo CDI, use o CDI 1.1 abaixo compatível /WEB-INF/beans.xml
com o bean-discovery-mode="all"
conjunto (o padrão é 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>
Ao usar o CDI 1.1+ com bean-discovery-mode="annotated"
(padrão), verifique se você não importou acidentalmente um escopo JSF, como em javax.faces.bean.RequestScoped
vez de um escopo CDI javax.enterprise.context.RequestScoped
. Cuidado com o preenchimento automático do IDE.
- Ao usar o Mojarra 2.3.0-2.3.2 e o CDI 1.1+ com
bean-discovery-mode="annotated"
(padrão), é necessário atualizar o Mojarra para o 2.3.3 ou mais recente devido a um erro . No caso de você não pode atualizar, então você precisa, quer para set bean-discovery-mode="all"
em beans.xml
, ou para colocar o específica JSF 2.3 @FacesConfig
anotação em uma classe arbitrária no WAR (geralmente algum tipo de uma aplicação com escopo classe de inicialização).
- Contêineres não Java EE como Tomcat e Jetty não são fornecidos com o CDI incluído. Você precisa instalá-lo manualmente. É um pouco mais trabalhoso do que adicionar JAR da (s) biblioteca (s). Para o Tomcat, siga as instruções nesta resposta: Como instalar e usar o CDI no Tomcat?
- Seu caminho de classe de tempo de execução está limpo e livre de duplicatas nos JARs relacionados à API CDI. Certifique-se de não misturar várias implementações de CDI (Weld, OpenWebBeans, etc). Certifique-se de não fornecer outro arquivo CDI ou JAR da API Java EE ao longo do aplicativo da web quando o contêiner de destino já empacota a API da CDI imediatamente.
Se você estiver empacotando beans gerenciados CDI para visualizações JSF em um JAR, verifique se o JAR possui pelo menos um válido /META-INF/beans.xml
(que pode ser mantido vazio).
Caso seja o Spring quem está gerenciando o bean @Component
, precisará garantir o seguinte:
O Spring está sendo instalado e integrado conforme sua documentação . Importante, você precisa pelo menos ter isso em web.xml
:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
E isso em faces-config.xml
:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
(acima é tudo o que sei em relação ao Spring - eu não faço o Spring - fique à vontade para editar / comentar com outras prováveis causas relacionadas ao Spring; por exemplo, alguns problemas relacionados à configuração XML)
No caso, é um componente repetidor que está gerenciando o feijão (aninhados), através do seu var
atributo (por exemplo <h:dataTable var="item">
, <ui:repeat var="item">
, <p:tabView var="item">
, etc) e você realmente tem uma "Target inacessível, identificador 'item' resolveu nulo", então você precisa certificar-se da seguinte :
O #{item}
não é referenciado na binding
atribuição de qualquer componente filho. Isso está incorreto, pois o binding
atributo é executado durante o tempo de criação da exibição, não durante o tempo de renderização da exibição. Além disso, existe fisicamente apenas um componente na árvore de componentes que é simplesmente reutilizado durante cada rodada de iteração. Em outras palavras, você realmente deve estar usando em binding="#{bean.component}"
vez de binding="#{item.component}"
. Mas o melhor é livrar-se completamente da vinculação de componentes e investigar / solicitar a abordagem adequada para o problema que você pensou que resolveria dessa maneira. Consulte também Como o atributo 'binding' funciona no JSF? Quando e como deve ser usado?
1b. Qual é o nome do bean gerenciado (padrão)?
A segunda etapa seria verificar o nome do bean gerenciado registrado. As convenções de uso JSF e Spring estão em conformidade com a especificação JavaBeans, enquanto o CDI possui exceções, dependendo do CDI impl / version.
Uma FooBean
classe de backing bean como abaixo,
@Named
public class FooBean {}
em todas as estruturas de gerenciamento de bean terá um nome de bean gerenciado padrão #{fooBean}
, conforme especificação do JavaBeans.
Uma FOOBean
classe de backing bean como abaixo,
@Named
public class FOOBean {}
cujo nome de classe não qualificado comece com pelo menos duas maiúsculas no JSF e Spring terá um nome de bean gerenciado padrão exatamente do nome de classe não qualificado #{FOOBean}
, também está de acordo com a especificação do JavaBeans. No CDI, esse também é o caso nas versões do Weld lançadas antes de junho de 2015, mas não nas versões do Weld lançadas após junho de 2015 (2.2.14 / 2.3.0.B1 / 3.0.0.A9) nem no OpenWebBeans devido a uma supervisão no CDI spec . Nessas versões do Weld e em todas as versões do OWB, é apenas com o primeiro caractere em minúsculas #{fOOBean}
.
Se você especificou explicitamente um nome de bean gerenciado foo
como abaixo,
@Named("foo")
public class FooBean {}
ou equivalentemente com @ManagedBean(name="foo")
ou @Component("foo")
, então ele estará disponível apenas por #{foo}
e, portanto, não por #{fooBean}
.
1c. Onde está a classe de backing bean?
A terceira etapa seria verificar novamente se a classe de backing bean estiver no lugar certo no arquivo WAR construído e implementado. Verifique se você executou corretamente uma limpeza completa, reconstrução, reimplantação e reinicialização do projeto e do servidor, caso você estivesse realmente ocupado escrevendo código e pressionando impacientemente F5 no navegador. Se ainda for em vão, deixe o sistema de compilação produzir um arquivo WAR, que você extrai e inspeciona com uma ferramenta ZIP. O .class
arquivo compilado da classe de backing bean deve residir em sua estrutura de pacote em /WEB-INF/classes
. Ou, quando empacotado como parte de um módulo JAR, o JAR que contém o .class
arquivo compilado deve residir /WEB-INF/lib
e, portanto, não, por exemplo, EARs /lib
ou em outro local.
Se você estiver usando o Eclipse, verifique se a classe de backing bean está dentro src
e, portanto , não WebContent
, e verifique se Projeto> Construir Automaticamente está ativado. Se você estiver usando o Maven, verifique se a classe de backing bean está dentro src/main/java
e, portanto, não está em src/main/resources
ou src/main/webapp
.
Se você estiver empacotando o aplicativo da Web como parte de um EAR com EJB + WAR (s), precisará certificar-se de que as classes de bean de backup estejam no módulo WAR e, portanto, não no módulo EAR nem no módulo EJB. A camada de negócios (EJB) deve estar livre de qualquer artefato relacionado à camada da web (WAR), para que a camada de negócios seja reutilizável entre várias camadas da web diferentes (JSF, JAX-RS, JSP / Servlet, etc.).
2. Destino Inacessível, 'entidade' retornada nula
Isso se resume à propriedade aninhadaentity
como #{bean.entity.property}
retornada null
. Isso geralmente expõe apenas quando o JSF precisa definir o valor por property
meio de um componente de entrada como abaixo, enquanto o #{bean.entity}
realmente retornou null
.
<h:inputText value="#{bean.entity.property}" />
Você precisa ter certeza de que você preparou a entidade modelo de antemão em um @PostConstruct
, ou <f:viewAction>
método, ou talvez um add()
método de ação no caso de você está trabalhando com listas de CRUD e / ou caixas de diálogo no mesmo ponto de 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();
}
// ...
}
Quanto à importância de @PostConstruct
; fazer isso em um construtor regular falharia caso você estivesse usando uma estrutura de gerenciamento de bean que usa proxies , como CDI. Sempre use @PostConstruct
para ligar a inicialização da instância do bean gerenciado (e use @PreDestroy
para ligar a destruição da instância do bean gerenciado). Além disso, em um construtor você ainda não teria acesso a nenhuma dependência injetada, consulte também NullPointerException ao tentar acessar o bean @Inject no construtor .
Caso o entityId
item seja fornecido via <f:viewParam>
, você precisará usá-lo em <f:viewAction>
vez de @PostConstruct
. Consulte também Quando usar f: viewAction / preRenderView versus PostConstruct?
Você também precisa garantir a preservação do não null
modelo durante as postagens, caso esteja criando apenas em um add()
método de ação. O mais fácil seria colocar o bean no escopo da visualização. Consulte também Como escolher o escopo do bean certo?
3. Destino inacessível, 'nulo' retornado nulo
Na verdade, isso tem a mesma causa que o número 2, apenas a implementação de EL (mais antiga) usada é um pouco problemática ao preservar o nome da propriedade a ser exibido na mensagem de exceção, que acabou sendo exposta incorretamente como 'nula'. Isso apenas torna a depuração e a correção um pouco mais difíceis quando você tem algumas propriedades aninhadas como essa #{bean.entity.subentity.subsubentity.property}
.
A solução ainda é a mesma: verifique se a entidade aninhada em questão não é null
, em todos os níveis.
4. Destino inacessível, '' 0 '' retornado nulo
Isso também tem a mesma causa do item 2, apenas a implementação de EL (mais antiga) usada está com erros na formulação da mensagem de exceção. Isso é exposto apenas quando você usa a notação de colchete []
no EL, como em #{bean.collection[index]}
que o #{bean.collection}
próprio é não nulo, mas o item no índice especificado não existe. Essa mensagem deve ser interpretada como:
Destino inacessível, 'coleção [0]' retornada nula
A solução também é a mesma # 2: verifique se o item de coleção está disponível.
5. Destino inacessível, 'BracketSuffix' retornado nulo
Na verdade, isso tem a mesma causa do item 4, apenas a implementação EL (mais antiga) usada é um pouco problemática na preservação do índice de iteração a ser exibido na mensagem de exceção, que acabou sendo exposta incorretamente como 'BracketSuffix', que é realmente o personagem ]
. Isso só torna a depuração e a correção um pouco mais difíceis quando você tem vários itens na coleção.
Outras causas possíveis de javax.el.PropertyNotFoundException
: