Ao tentar fazer referência a um bean gerenciado no EL dessa maneira #{bean.entity.property}
, algumas vezes uma javax.el.PropertyNotFoundException: Target Unreachable
exceção está sendo lançada, geralmente quando uma propriedade de bean deve ser configurada ou quando uma ação de bean deve ser invocada.
Parece haver cinco tipos diferentes de mensagens:
- Alvo inacessível, identificador 'bean' resolvido como nulo
- Destino inacessível, 'entidade' retornada nula
- Destino inacessível, 'nulo' retornado nulo
- Destino inacessível, '' 0 '' retornado nulo
- Destino inacessível, 'BracketSuffix' retornado nulo
O que todos eles significam? Como eles são causados e como devem ser resolvidos?
Class [ Lorg/mxchange/jfinancials/model/receipt/FinancialAdminReceiptSessionBeanRemote; ] not found. Error while loading [ cl ass org.mxchange.jfinancials.beans.financial.model.receipt.FinancialAdminReceiptWebRequestBean ]]]
E esse bean (FinancialAdminReceiptWebRequestBean
) não pôde ser encontrado e resolvido comnull
certeza. Outro erro comum é não reiniciar o servidor de aplicativos após, por exemplo, renomear ou mover classes / interfaces (ou esquecerclean
).Respostas:
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 oversion
deve especificar pelo menos JSF 2.0 ou superior e, portanto, não 1.x.Para o JSF 2.1, basta substituir
2_0
e2.0
por2_1
e2.1
respectivamente.Se você estiver no JSF 2.2 ou superior, verifique se está usando
xmlns.jcp.org
espaços para nome em vez dejava.sun.com
em todo lugar.Para o JSF 2.3, basta substituir
2_2
e2.2
por2_3
e2.3
respectivamente.Você não importou acidentalmente em
javax.annotation.ManagedBean
vez dejavax.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.@ManagedBean
estilo JSF 1.x<managed-bean>
nafaces-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 gerenciadofaces-config.xml
não é necessário desde o JSF 2.0, basta removê-lo./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 emfaces-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:O CDI 1.1 (Java EE 7) sem nenhum arquivo
beans.xml
vaziobeans.xml
ou com o CDI 1.0 acima compatívelbeans.xml
se comportará da mesma maneira que o CDI 1.0. Quando há um CDI 1.1 compatívelbeans.xml
com um explícitaversion="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 obean-discovery-mode="all"
conjunto (o padrão ébean-discovery-mode="annotated"
).Ao usar o CDI 1.1+ com
bean-discovery-mode="annotated"
(padrão), verifique se você não importou acidentalmente um escopo JSF, como emjavax.faces.bean.RequestScoped
vez de um escopo CDIjavax.enterprise.context.RequestScoped
. Cuidado com o preenchimento automático do IDE.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 setbean-discovery-mode="all"
embeans.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).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
:E isso em
faces-config.xml
:(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 nabinding
atribuição de qualquer componente filho. Isso está incorreto, pois obinding
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 embinding="#{bean.component}"
vez debinding="#{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,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,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,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ãoWebContent
, e verifique se Projeto> Construir Automaticamente está ativado. Se você estiver usando o Maven, verifique se a classe de backing bean está dentrosrc/main/java
e, portanto, não está emsrc/main/resources
ousrc/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 aninhada
entity
como#{bean.entity.property}
retornadanull
. Isso geralmente expõe apenas quando o JSF precisa definir o valor porproperty
meio de um componente de entrada como abaixo, enquanto o#{bean.entity}
realmente retornounull
.Você precisa ter certeza de que você preparou a entidade modelo de antemão em um
@PostConstruct
, ou<f:viewAction>
método, ou talvez umadd()
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.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 umadd()
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: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
:fonte
#{bean.entity.property}
produz o valor, mas<p:selectBooleanCheckbox value="#{bean.entity.property}"/>
falha. Meu booleano tem um setter. Uma propriedade integer sobre a mesma entidade faz trabalho quando usado em um campo de entrada. Alguma ideia?Target Unreachable, identifier 'bean' resolved to null
Em projetos maven de múltiplos módulos (contendo módulos para ejb, web, ear), verifique se o seu módulo da web declara uma dependência do seu módulo ejb. Sem isso, o@ManagedBean
não pode ser resolvido usando o JSF2.0 e você deve declará-losfaces-config.xml
. Me levou cerca de duas horas percebendo que eu não declarou uma dependência para incluir o EJB no meu web-module (EJB só tinha e web no meu ouvido)@ManagedBean
classes não pertencem à camada de serviço (projeto EJB) em primeiro lugar. Veja também stackoverflow.com/questions/13011392/jsf-service-layerPara quem ainda está preso ...
Usando o NetBeans 8.1 e o GlassFish 4.1 com CDI, por algum motivo, tive esse problema apenas localmente, não no servidor remoto. O que fez o truque:
-> usando javaee-web-api 7.0 em vez da versão padrão do pom fornecida pelo NetBeans, que é javaee-web-api 6.0, portanto:
-> faça o upload deste javaee-web-api-7.0.jar como uma lib no servidor (pasta lib na pasta domain1) e reinicie o servidor.
fonte
Decidi compartilhar minha descoberta sobre esse erro depois de resolvê-lo.
Antes de tudo, as soluções BalusC devem ser levadas a sério, mas existe outro problema provável no Netbeans, principalmente ao criar um EAR (Enterprise Application Project) usando o Maven.
O Netbeans gera, um arquivo POM pai , um projeto EAR , um projeto EJB e um projeto WAR . Todo o resto do meu projeto estava bem, e eu quase assumi que o problema é um bug no GlassFish 4.0 (eu tive que instalar e conectá-lo ao Netbeans) porque o GlassFish 4.1 possui um bug do Weld CDI que torna o GlassFish 4.1 incorporado no Netbeans 8.0. 2 inutilizáveis, exceto através de um patch.
Solução:
Para resolver o erro "Destino inacessível, identificador 'bean' resolvido como nulo"
I Clique com o botão direito do mouse no projeto POM pai e selecione Propriedades . Uma caixa de diálogo Propriedades do projeto é exibida, clique em "Fontes"; você ficará surpreso ao ver o " Formato de origem / binário " definido como 1.5 e " Codificação " definido para o Windows 1250. Altere o " Formato de origem / binário " para 1.6 0r 1.7, o que ocorrer você prefere tornar seu projeto compatível com CDI e " Codificar " para UTF-8.
Faça o mesmo para todos os outros subprojetos (EAR, EJB, WAR) se eles ainda não estiverem compartimentáveis. Execute seu projeto e você não receberá esse erro novamente.
Espero que isso ajude alguém por aí com erro semelhante.
fonte
Decidi compartilhar minha solução, porque, embora muitas respostas fornecidas aqui fossem úteis, eu ainda tinha esse problema. No meu caso, estou usando JSF 2.3, jdk10, jee8, cdi 2.0 para o meu novo projeto e executei meu aplicativo no wildfly 12, iniciando o servidor com o parâmetro standalone.sh -Dee8.preview.mode = true, conforme recomendado no site wildfly . O problema com "bean resolvido para nulo" desapareceu após o download do wildfly 13. O upload exatamente da mesma guerra para o wildfly 13 fez com que tudo funcionasse.
fonte
Fiquei preso nesse erro porque na classe que
@SpringBootApplication
esqueci de especificar o nome do pacote do controlador.Desta vez, eu queria ser mais específico, apontando quais componentes o Spring tinha que verificar, em vez de configurar o pacote base.
Foi assim:
@ComponentScan(basePackages = {"br.com.company.project.repository", "br.com.company.project.service"})
Mas a forma correta é uma delas:
@ComponentScan(basePackages = {"br.com.company.project.repository", "br.com.company.project.service", "br.com.company.project.controller"})
@ComponentScan(basePackages = {"br.com.company.project")
Decidi compartilhar minha solução, porque, embora a resposta correta seja muito abrangente, ela não cobre esse erro (idiota) :)
fonte
No meu caso, cometi um erro ortográfico em @Named ("beanName"), era suposto ser "beanName", mas escrevi "beanNam", por exemplo.
fonte
Estou usando o wildfly 10 para o contêiner javaee. Eu havia enfrentado o problema "Alvo inacessível, 'entidade' retornou nulo". Obrigado pelas sugestões da BalusC, mas o problema da minha solução foi explicado. Acidentalmente usando "import com.sun.istack.logging.Logger;" em vez de "import org.jboss.logging.Logger;" CDI causado implementado JSF EL. Espero que ajude a melhorar a solução.
fonte
Eu tive o mesmo problema. A solução acabou sendo muito mais simples. Parece que uma tabela de dados deseja o método na forma de um getter, ou seja, getSomeMethod (), não apenas someMethod (). No meu caso, na tabela de dados, eu estava chamando findResults. Alterei o método no meu backing bean para getFindResults () e funcionou.
Um commandButton funcionou find sem o get, que serviu para torná-lo apenas mais confuso.
fonte
Quanto ao # 2, no meu caso, ele ganhou vida mágica depois de substituir
marcar com
Depois de ter feito vários projetos JSF (mais simples, para ser honesto), não conseguia me lembrar de fazer nada diferente ao configurá-lo agora e recebi esse tipo de erro pela primeira vez. Eu estava criando uma página de login muito básica (nome de usuário, senha, usuário Bean ...) e configurei tudo como de costume. A única diferença que vi são as tags mencionadas acima. Talvez alguém ache isso útil.
fonte
O problema no meu caso foi que incluí um construtor que aceita parâmetros, mas não um construtor vazio com a anotação Inject, dessa forma.
Acabei de testá-lo sem qualquer construtor e isso parece funcionar também.
fonte
Para o 1. tópico ( Destino inacessível, identificador 'bean' resolvido como nulo );
Eu verifiquei respostas valiosas do @BalusC e dos outros compartilhadores, mas supero esse problema como este no meu cenário. Após criar um novo xhtml com nome diferente e criar classe de bean com nome diferente, escrevi (não copie e cole) os códigos passo a passo para a nova classe de bean e o novo arquivo xhtml.
fonte
Quando removo o parâmetro de contexto AnnotationConfigWebApplicationContext do arquivo web.xml
Se você possui um parâmetro que, como mostrado abaixo, deve removê-lo do arquivo web.xml
fonte
Trabalhando com JSF no estilo antigo Você deve definir o bean gerenciado no arquivo beans-config.xml (localizado na pasta WEB-INF) e fazer uma referência a ele no arquivo web.xml , desta maneira:
beans-config.xml
(Tentei usar outros escopos, mas ...)
web.xml
fonte
Outra dica: eu estava usando JSF e adicionei dependências mvn: com.sun.faces jsf-api 2.2.11
Em seguida, tentei mudar para Primefaces e adicionar dependência de primefaces:
Alterei meu xhtml de h: para p :, adicionando xmlns: p = "http://primefaces.org/ui ao modelo. Somente com o JSF o projeto estava funcionando ok e o managedbean foi atingido ok. Quando adiciono Primefaces Eu estava obtendo o objeto inacessível (javax.el.propertynotfoundexception) .O problema era que o JSF estava gerando o ManagedBean, não o Primefaces, e eu estava pedindo o primefaces para o objeto. Eu tive que excluir o jsf-impl do meu. instalar o projeto.Tudo correu bem a partir deste ponto.Espero que ajude.
fonte
O EL interpreta $ {bean.propretyName} conforme descrito - o propertyName torna-se getPropertyName () na suposição de que você esteja usando métodos explícitos ou implícitos para gerar getter / setters
Você pode substituir esse comportamento identificando explicitamente o nome como uma função: $ {bean.methodName ()} Isso chama o método da função Name () diretamente sem modificação.
Nem sempre é verdade que seus acessadores são nomeados "get ...".
fonte
action="#{bean.property}"
vez deaction="#{bean.method}"
.No meu caso, "el-ri-1.0.jar" estava ausente.
fonte