• Skip to primary navigation
  • Skip to content

Mauda

IT, Java and Music

Graduação   SCJP   Mestrado
  • Apresentação
  • Certificação Java
  • JPA
    • Exceptions
  • JSF
  • Versionamento
  • Contato

Erros JSF – javax.faces.FacesException: Cannot find component with expression

December 7, 2015 by Mauda Leave a Comment

Conteúdo do Post:
  1. Descrição do Erro
  2. Código – Versão Inicial
  3. Rodando o código da Versão Inicial… e ERRO!
  4. Código utilizando o método component
  5. finnaly{

Olá Pessoal, tudo bom?

No artigo de hoje iremos descrever um erro que ocorre quando o JSF não consegue localizar determinado ID em uma página xhtml. Especificamente estamos falando da exception javax.faces.FacesException: Cannot find component with expression “id” referenced from “panel”.

Descrição do Erro

Observe as telas representadas na Figuras 01. A primeira parte da Figura 01 representa um “filtro” de pesquisa, o qual possui um botão Pesquisar, que, de acordo com a segunda parte da Figura 01, irá mostrar um Data Table com as informações de cada Herói. E a terceira parte da Figura 01 nos mostra que ao selecionar um Herói na data table, irá aparecer o nome deste em um panel abaixo da data table.

Figura 01 – Representação da tela de testePComponent.xhtml

Código – Versão Inicial

Para representar essa tela o desenvolvedor construiu o seguinte código para a página testePComponent.xhtml:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
 
<h:head>
<title>Vingadores</title>
</h:head>
<h:body>
<h:form>
<p:panel>
<f:facet name="header">
Teste p:component
</f:facet>
<p:commandButton value="Pesquisar"
action="#{testePComponentMB.pesquisar}"
update="resultados" />
</p:panel>
<p:panel id="resultados" style="border:0px;">
<p:dataTable value="#{testePComponentMB.vingadores}"
var="vingador"
rendered="#{not empty testePComponentMB.vingadores}"
rowKey="#{vingador.id}"
selectionMode="single"
selection="#{testePComponentMB.selecionado}">
<p:ajax event="rowSelect"
update="posResultados" />
 
<f:facet name="header">
Vingadores
</f:facet>
<p:column headerText="Heroi">
#{vingador.nome}
</p:column>
</p:dataTable>
</p:panel>
<p:panel id="posResultados" style="border:0px;">
<p:panel rendered="#{testePComponentMB.selecionado ne null}">
<h:outputText
value="O Heroi selecionado foi #{testePComponentMB.selecionado.nome}"/>
</p:panel>
</p:panel>
</h:form>
 
</h:body>
</html>

Repare que para que todos os painéis representados nessa tela, nós já utilizamos do conceito apresentado nesse artigo. Assim não temos problema do componente não estar representado na arvore DOM e podemos re renderizá-lo corretamente.

Outro aspecto aqui importante é que nós utilizamos um componente, de nome p:ajax, dentro da data table para que possamos selecionar determinada linha e exibir a última parte que é uma frase representado qual foi o herói escolhido no data table.

Para que essa tela funcione foi implementado um Managed Bean (MB) de nome TestePComponentMB, que possui o escopo View, indicando que o Managed Bean permanecerá vivo, não será destruído pelo JSF, enquanto ele permanecer nesta página. O código deste MB está representado abaixo:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package br.com.mauda.view.mb;
 
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
 
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
 
@ManagedBean
@ViewScoped
public class TestePComponentMB implements Serializable{
/////////////////////////////////////
// Atributos
/////////////////////////////////////
private static final long serialVersionUID = 1L;
private Collection<Vingador> vingadores;
private Vingador selecionado;
/////////////////////////////////////
// Construtores
/////////////////////////////////////
public TestePComponentMB() {
}
@PostConstruct
private void init(){
vingadores = new ArrayList<Vingador>();
}
/////////////////////////////////////
// Actions
/////////////////////////////////////
//Action de Pesquisar a partir do filtro
public void pesquisar() {
if(vingadores.isEmpty()){
Long i = 0L;
String[] nomes = {"Hulk", "Capitão América", "Homem de Ferro", "Thor", "Viuva Negra", "Gavião Arqueiro"};
for(String nome : nomes){
Vingador v = new Vingador();
v.setId(i++);
v.setNome(nome);
vingadores.add(v);
}
}
}
/////////////////////////////////////
// Getters and Setters
/////////////////////////////////////
public Collection<Vingador> getVingadores() {
return vingadores;
}
public Vingador getSelecionado() {
return selecionado;
}
public void setSelecionado(Vingador selecionado) {
this.selecionado = selecionado;
}
}

Por fim, ambos os códigos utilizam-se de uma classe Vingador, representada abaixo:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package br.com.mauda.model;
 
import java.io.Serializable;
 
public class Vingador implements Serializable {
/////////////////////////////////////
// Atributos
/////////////////////////////////////
private static final long serialVersionUID = 1L;
private Long id;
private String nome;
/////////////////////////////////////
// Getters and Setters
/////////////////////////////////////
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}

Rodando o código da Versão Inicial… e ERRO!

Ao rodar o código, você conseguirá entrar na tela. Mas, ao clicar no botão Pesquisar, ele não fará nada na tela, mas se você observar o console da IDE verificará a seguinte mensagem:

GRAVE [javax.enterprise.resource.webcontainer.jsf.context] (http-localhost-127.0.0.1-8080-3) javax.faces.FacesException: Cannot find component with expression “posResultados” referenced from “j_idt6:j_idt10”.

Vamos pensar na arvore DOM desta página. O nodo <h:form> possui 3 filhos do elemento <p:panel>. E dentro de um desses filhos existe um filho do elemento <p:dataTable>. Aí que o problema começa…

p:dataTable ((p:dataTable – API – link)) implementa a interface javax.faces.component.NamingContainer((javax.faces.component.NamingContainer – API – link)). Essa interface define um novo padrão de id, o qual deve ser mencionado em outras referencias. Dessa forma quando está em um novo NamingContainer, não é possível acessar outros NamingContainer definidos na página senão forem referenciados diretamente. Em um futuro irei descrever um pouco mais sobre NamingContainer já que é um assunto que confunde a maioria dos desenvolvedores.

Código utilizando o método component

Para corrigir esse erro então é necessário referenciar diretamente o NamingContainer. Mas isso pode ser um pouco maçante ou mesmo difícil de ser feito, assim se você estiver utilizando a biblioteca JSF do primefaces existe um método que trabalha para localizar itens. Esse método é o p:component ((p:component – API – link)). Para utilizá-lo você deverá passar qual é o componente que o primefaces deverá localizar, no caso posResultados. O primefaces irá substituir essa linha, pelo caminho completo até o componente. O exemplo pode ser visualizado na linha 32 do código abaixo.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
 
<h:head>
<title>Vingadores</title>
</h:head>
<h:body>
<h:form>
<p:panel>
<f:facet name="header">
Teste p:component
</f:facet>
<p:commandButton value="Pesquisar"
action="#{testePComponentMB.pesquisar}"
update="resultados" />
</p:panel>
<p:panel id="resultados" style="border:0px;">
<p:dataTable value="#{testePComponentMB.vingadores}"
var="vingador"
rendered="#{not empty testePComponentMB.vingadores}"
rowKey="#{vingador.id}"
selectionMode="single"
selection="#{testePComponentMB.selecionado}">
<p:ajax event="rowSelect"
update=":#{p:component('posResultados')}" />
 
<f:facet name="header">
Vingadores
</f:facet>
<p:column headerText="Heroi">
#{vingador.nome}
</p:column>
</p:dataTable>
</p:panel>
<p:panel id="posResultados" style="border:0px;">
<p:panel rendered="#{testePComponentMB.selecionado ne null}">
<h:outputText
value="O Heroi selecionado foi #{testePComponentMB.selecionado.nome}"/>
</p:panel>
</p:panel>
</h:form>
 
</h:body>
</html>

Um detalhe importante é que se o componente estiver debaixo do mesmo form, deve ser inserido os dois pontos (“:”) antes da chamada do método.

finnaly{

Duvidas ou sugestões? Deixe seu feedback! Isso ajuda a saber a sua opinião sobre os artigos e melhorá-los para o futuro! Isso é muito importante!

Até um próximo post!

Filed Under: Java, JSF Tagged With: JSF, p:component, PrimeFaces

About Mauda

Mestre em Informática, Analista de Sistemas, Professor, SCJP e Baterista. Desde 2002 trabalhando no mundo Java e ensinando pessoas sobre desenvolvimento de sistemas. Mais informações

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Advertisements

Copyright © 2026 · Genesis Framework · WordPress · Log in