Recebi ontem um e-mail de um provável leitor dos meus artigos sobre Java EE 6, publicados nas edições 80, 81 e 82 da Java Magazine. Ele reportava um erro, mostrado na imagem a seguir, e pedia ajuda para resolvê-lo.
A resposta rápida é a seguinte: com a parte do erro que eu consigo ver na imagem, acredito que a causa mais provável para o erro seja a referência ao bean CDI utilizada na página JSF: [cci_java]#{logincontroller.login}[/cci_java].
Tal referência faz com que o CDI procure o bean que tenha o nome [cci_java]logincontroller[/cci_java] (no contexto em questão) e, em seguida, chame o método [cci_java]getLogin()[/cci_java] nesta instância, utilizando o resultado no local em que a referência foi feita (ex.: mostrando o valor na página).
Para que um bean tenha este nome existem duas possibilidade:
- Existe uma classe chamada [cci_java]Logincontroller[/cci_java] (exatamente assim, com somente a primeira letra maiúscula) com a anotação [cci_java]@Named[/cci_java] (ou alguma anotação que represente um estereótipo que inclua [cci_java]@Named[/cci_java], como por exemplo [cci_java]@Model[/cci_java])
- Existe uma classe, com um nome qualquer, com a anotação [cci_java]@Named(“logincontroller”)[/cci_java]
O que desconfio que tenha acontecido foi a criação de uma classe [cci_java]LoginController[/cci_java] (com L e C maiúsculos) com a anotação [cci_java]@Named[/cci_java] ou [cci_java]@Model[/cci_java]. Neste caso, o nome CDI desta classe seria [cci_java]loginController[/cci_java] (com o C maiúsculo) e não [cci_java]logincontroller[/cci_java]. Lembremos sempre que Java é case-sensitive.
E, acreditem ou não, esta foi a explicação curta. 🙂
A explicação longa encontra-se no padrão CDI, mais especificamente seção 2.5: Bean EL names. Todo Bean CDI pode ter um nome para poder ser referenciado em expressões EL (Expression Language) se, como já disse anteriormente, ele possuir a anotação [cci_java]@Named[/cci_java] ou alguma anotação de estereótipo que inclua [cci_java]@Named[/cci_java].
Esta anotação admite como parâmetro ([cci_java]value[/cci_java]) uma string que define o nome do bean. Veja o exemplo a seguir:
[cce_java]
@Named(“mb”)
public class MeuBean {
/* Implementação da classe… */
}
[/cce_java]
Para se referir ao bean [cci_java]MeuBean[/cci_java], basta usar o nome [cci_java]mb[/cci_java] na expressão EL. Ou seja, para mostrar na tela a versão string do objeto em questão (ou seja, o resultado da chamada de [cci_java]toString()[/cci_java]), basta inserir na página a tag [cci_java]
No entanto, quando não especificamos o valor na tag [cci_java]@Named[/cci_java], o container determina um nome default para o bean. E isso também é especificado no padrão CDI, para que todos os servidores de aplicação compatíveis com Java EE 6 determinem os mesmos nomes default para os diferentes elementos. A especificação diz:
- Seções 3.1.5 e 3.2.5: o nome default para um bean (EJB ou não) é o nome não-qualificado da classe (ou seja, desconsidera-se o pacote), convertendo o primeiro caractere deste nome para minúsculo. Por exemplo, se o nome da classe do bean é [cci_java]MeuBean[/cci_java], o nome EL default será [cci_java]meuBean[/cci_java];
- Seção 3.3.8: o nome default para um método produtor é o próprio nome do método, a não ser que o mesmo siga a convenção JavaBean para getters. Em tal caso, o nome default é o nome da propriedade JavaBean. Por exemplo, tanto o método produtor [cci_java]listaProdutos()[/cci_java] quanto [cci_java]getListaProdutos()[/cci_java] possuem o nome default [cci_java]listaProdutos[/cci_java];
- Seção 3.4.3: o nome default de um campo produtor é o próprio nome do campo. Por exemplo, um campo produtor [cci_java]listaProdutos[/cci_java] tem como nome default [cci_java]listaProdutos[/cci_java].
Para mais detalhes sobre o CDI, aconselho a leitura do artigo que escrevi para a Java Magazine, publicado em duas partes, iniciando com a edição 84. Bons estudos!