I think that I found a error in runtime of Java with JSF 2.0 (Using Primefaces), in this project I'm using JSF 2.0 Primefaces and CDI.
Resuming the problem, I have a method setter in my business class Role that received a List, but the JSF is setting a ArrayList on that.
Should the java throw a exception or at least should not find a method that matches?
here is:
public void setAcl(List<Integer> acl) {
this.acl = acl;
System.out.println("Received: " + this.acl);
for(Object i : this.acl) {
System.out.println(i.getClass() + " > " + i);
}
}
The output of this method is:
Received: [1, 5]
class java.lang.String > 1
class java.lang.String > 5
And when I try to use in foreach like this:
for(Integer i : this.acl) {
System.out.println(i.getClass() + " > " + i);
}
Throws
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
Can you explain what is going on here? Is it a error on JSF or Java? Or is my misunderstood?
First I have a UI JSF (.xhtml) that has a p:selectManyCheckbox
, this manyCheckbox receive a array of enum PontoSenha (using the enum's method values() ) from managedbean and define the values to itemValue and itemLabel.
Follow the code of manyCheckbox:
<p:selectManyCheckbox id="acl" value="#{roleController.role.acl}" layout="grid" columns="4" required="true" requiredMessage="Selecione pelo menos um ponto de senha" >
<f:selectItems value="#{roleController.pontosSenha}" var="pontoSenha" itemValue="#{pontoSenha.pontoSenha}" itemLabel="#{pontoSenha.descricao}" />
</p:selectManyCheckbox>
Declaration of enum PontoSenha:
package br.com.bsetechnology.atacadao.business;
public enum PontoSenha {
CADASTRO_FORNECEDOR(1, "Cadastrar fornecedor"),
CADASTRO_LOJA(2, "Cadastrar loja"),
CADASTRO_PRODUTO(3, "Cadastrar produto"),
RELATORIO(4, "Gerar relatório"),
SEGURANCA_GRUPOS(5, "Gerenciar grupos de usuário"),
SEGURANCA_USUARIOS(6, "Gerenciar usuários");
private int pontoSenha;
private String descricao;
private PontoSenha(int pontoSenha, String descricao) {
this.pontoSenha = pontoSenha;
this.descricao = descricao;
}
public int getPontoSenha() {
return pontoSenha;
}
public String getDescricao() {
return descricao;
}
@Override
public String toString() {
return String.format("%02d - %s", pontoSenha, descricao);
}
}
Declaration of the ManagedBean
package br.com.bsetechnology.atacadao.controller;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.inject.Inject;
import javax.inject.Named;
import br.com.bsetechnology.atacadao.business.PontoSenha;
import br.com.bsetechnology.atacadao.business.Role;
import br.com.bsetechnology.atacadao.core.FacesUtil;
import br.com.bsetechnology.atacadao.dao.RoleDAO;
@Named("roleController")
@RequestScoped
public class RoleController {
@Inject
private RoleDAO roleDao;
private Role role;
public void setRoleDao(RoleDAO roleDao) {
this.roleDao = roleDao;
}
public Role getRole() {
if(role == null)
role = new Role();
return role;
}
public void setRole(Role role) {
this.role = role;
}
public PontoSenha[] getPontosSenha() {
return PontoSenha.values();
}
public List<Role> getAll() {
return roleDao.getAll();
}
public void salva() {
System.out.println("Salvando");
boolean resultAction = false;
if(role.getCodigo() > 0) {
resultAction = roleDao.update(role);
} else {
resultAction = roleDao.insert(role);
}
if(resultAction) {
role = new Role();
FacesUtil.addMessage(FacesMessage.SEVERITY_INFO, "Grupo salvo com sucesso.", null);
} else {
FacesUtil.addMessage(FacesMessage.SEVERITY_WARN, "Grupo não foi salvo.", null);
}
}
}
Business class Role
package br.com.bsetechnology.atacadao.business;
import java.util.ArrayList;
import java.util.List;
public class Role {
private int codigo;
private String descricao;
private List<Integer> acl;
public Role() {
acl = new ArrayList<Integer>();
}
public Role(int codigo, String descricao, List<Integer> acl) {
setCodigo(codigo);
setDescricao(descricao);
setAcl(acl);
}
public int getCodigo() {
return codigo;
}
public void setCodigo(int codigo) {
this.codigo = codigo;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
public List<Integer> getAcl() {
return acl;
}
public void setAcl(List<Integer> acl) {
this.acl = acl;
System.out.println("Received: " + this.acl);
for(Object i : this.acl) {
System.out.println(i.getClass() + " > " + i);
}
}
public void addPontoSenha(int pontoSenha) {
this.acl.add(pontoSenha);
}
public void remPontoSenha(int pontoSenha) {
this.acl.remove(pontoSenha);
}
}
The page JSF that I use to register roles (template.xhtml is only HTML and CSS):
<ui:composition template="/WEB-INF/template.xhtml" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui">
<ui:define name="body-content">
<div class="row">
<h:form id="formGrupo" class="form-horizontal"><fieldset>
<p:panel header="Edição de grupo de usuário" >
<div class="control-group">
<h:outputLabel for="codigo" value="Código" readonly="" styleClass="control-label" />
<div class="controls">
<h:inputText id="codigo" class="form-control" value="#{roleController.role.codigo}"
style="width:100px;text-align:right;" />
</div>
</div>
<div class="control-group">
<h:outputLabel for="descricao" value="Descrição" styleClass="control-label" />
<div class="controls">
<h:inputText id="descricao" class="form-control" value="#{roleController.role.descricao}"
required="true" maxlength="20" requiredMessage="Descrição obrigatória" converterMessage="Descrição inválida" />
<h:message for="descricao" class="error" />
</div>
</div>
<div class="control-group">
<h:outputLabel value="Pontos de senha" styleClass="control-label" />
<div class="controls checkbox">
<p:selectManyCheckbox id="acl" value="#{roleController.role.acl}" layout="grid" columns="4"
required="true" requiredMessage="Selecione pelo menos um ponto de senha" >
<f:selectItems value="#{roleController.pontosSenha}" var="pontoSenha" itemValue="#{pontoSenha.pontoSenha}" itemLabel="#{pontoSenha.descricao}" />
</p:selectManyCheckbox>
<h:message for="acl" errorClass="error" />
</div>
</div>
<div class="form-actions">
<hr/>
<p:commandLink value="Salvar" styleClass="btn btn-primary" style="color:#fff;" action="#{roleController.salva}" update=":formGrupo,:formTable:tblRoles">
</p:commandLink>
</div>
<p:messages globalOnly="true" showDetail="false" closable="true" />
</p:panel>
</fieldset></h:form>
</div>
<br/>
<div class="row">
<h:form id="formTable" styleClass="form-horizontal"><fieldset>
<p:panel header="Grupos de usuários">
<p:dataTable id="tblRoles" var="role" value="#{roleController.all}" rowKey="#{role.codigo}" stickheader="true" >
<p:column headerText="Código" width="20">
<h:outputText value="#{role.codigo}" />
</p:column>
<p:column headerText="Descrição">
<h:outputText value="#{role.descricao}" />
</p:column>
<p:column width="200">
<p:commandLink value="Editar" class="btn btn-success btn-sm" style="color:#fff;margin-left:5px;" update=":formGrupo">
<f:setPropertyActionListener value="#{role}" target="#{roleController.role}" />
</p:commandLink>
<p:commandLink value="Excluir" styleClass="btn btn-danger btn-sm" style="color:#fff;margin-left:5px;" />
</p:column>
</p:dataTable>
</p:panel>
</fieldset></h:form>
</div>
</ui:define>
</ui:composition>
Full print stack trace
Jan 29, 2014 10:59:43 PM com.sun.faces.context.AjaxExceptionHandlerImpl handlePartialResponseError
SEVERE: javax.faces.component.UpdateModelException: javax.el.ELException: /seguranca/grupos.xhtml @27,87 value="#{roleController.role.acl}": Error writing 'acl' on type br.com.bsetechnology.atacadao.business.Role
at javax.faces.component.UIInput.updateModel(UIInput.java:867)
at javax.faces.component.UIInput.processUpdates(UIInput.java:749)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1286)
at org.primefaces.component.panel.Panel.processUpdates(Panel.java:288)
at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1286)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1286)
at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1254)
at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at br.com.bsetechnology.atacadao.core.AccessControlFilter.doFilter(AccessControlFilter.java:31)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: javax.el.ELException: /seguranca/grupos.xhtml @27,87 value="#{roleController.role.acl}": Error writing 'acl' on type br.com.bsetechnology.atacadao.business.Role
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:139)
at javax.faces.component.UIInput.updateModel(UIInput.java:832)
... 30 more
Caused by: javax.el.ELException: Error writing 'acl' on type br.com.bsetechnology.atacadao.business.Role
at javax.el.BeanELResolver.setValue(BeanELResolver.java:153)
at com.sun.faces.el.DemuxCompositeELResolver._setValue(DemuxCompositeELResolver.java:255)
at com.sun.faces.el.DemuxCompositeELResolver.setValue(DemuxCompositeELResolver.java:281)
at org.apache.el.parser.AstValue.setValue(AstValue.java:218)
at org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:253)
at org.jboss.weld.el.WeldValueExpression.setValue(WeldValueExpression.java:64)
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131)
... 31 more
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at br.com.bsetechnology.atacadao.business.Role.setAcl(Role.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at javax.el.BeanELResolver.setValue(BeanELResolver.java:142)
... 37 more