Tenho uma aplicaçao em JSF 2.0 usando Postgres e Glassfish e tbm Primefaces.
Em algumas situações, tudo depende do tempo que o sistema fica aberto sem nenhuma ação, quando executo algo simplesmente acontece o erro abaixo, tentei de várias formas encontrar e forçar o erro e nao consegui.
Existe alguma forma de fazer que quando aconteça algum erro antes emitir essa tela eu consiga enviar uma msg ou mandar para um xhtml informando a msg do erro corrente?
o Glassfish e outros servidores de aplicações web (JBOSS, IIS, TOMCAT …), quando iniciam sua aplicação costumam carregar alguns objetos próprios para controlar as conexões, criar sessões privadas, criar sessão pública onde são mantidos objetos globais de sua aplicação, controlar as requisições e respostas e canais com recursos de retaguarda como banco de dados e interface com outros sistemas.
O problema mencionado por você pode ter relação com:
Timeout de sessão ocorrido porque no Glassfish o tempo padrão para encerrar uma sessão ociosa foi atingido e objetos forem descarregados.
Memory leak (lixo em memória) gerado por alguma ou algumas rotinas de sua aplicação web. Isso ocorre quando você instancia objetos com muita frequência e os deixa na memória, seja porque colocou num contexto permanente ou seja porque você abriu um objeto muito complexo e mesmo tendo acabado com ele através de ter colocado ele no escopo de um método, a JVM não conseguiu destruir porque é complexo.
Utilize o Admin Console (porta padrão 4848 ) do Glassfish e vá ao menu “Application Server”. Verifica sua aplicação e o log dela para entender a origem do stacktrace.
Estas análise preliminar é baseada no que você relatou.
Mas o problema pode ser mais simples do que uma pane, isto é, pode ser uma situação constante que é descoberta somente quando o usuário faz um certo procedimento. Por causa disso, também é interessante você mapear o que está sendo feito onde ocorre o problema porque o ambiente de produção e de teste podem variar muito e inibir a situação em seu ambiente.
Mas vamos aos detalhes, sobre a primeira opção de timeout acho que não cabe nessa situação, alem de ter aumentado o tempo de timeout as vezes o erro ocorre no acesso mesmo, em alguma seleção/ação do sistema.
Quanto a segunda opção tem muito sentido e creio que possa ser isso mesmo, até revisei toda a tela principal onde mais ocorre esses erros, colocando todos try-catch fazendo parada em todo erro/exceção mas muitas vezes mesmo assim o erro acontece sem acusar exceção.
Quando faço algum teste, desenvolvo em ambiente windows e o meu sistema roda em um servidor linux-centOs, no ambiente de desenvolvimento tudo roda muito bem, e nao acontece esses erros que acontece no ambiente de uso. Existe alguma coisa alem da configuração básica do Glassfish em linux para ser configurado? ou algum item que poderia estar talvez ocasionando isso?
Até fui no Enterprise Server do meu Admin Console, tentei ver os logs mas nao me diz muita coisa aqueles logs, aparentemente parece estar tudo ok.
Se tiver alguma configuração ou passos para seguir do Glassfish diferentes do padrao?
Realmente deve ser algum problema de ambiente se não tem nada no log. Pode ser uma falha mesmo no GlassFish.
Você sabe se o binário do GlassFish instalado linux-centOs é compatível? Se for um sistema 64-bits e você instalou um GlassFish 32-bits ou vice-versa, pode operar de forma anormal.
Agora a minha classe onde está referenciando o erro:
public void tipoTela(Integer _tipo, Integer _idUsuario) {
tela = "";
if (emailLogado.equals("Sem e-mail")) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Impossível Abertura de Chamado:", "Usuário e Supervisor sem e-mail cadastrado. Verifique!"));
tela = "enviaEmailUsuario.xhtml";
} else {
try {
rs = Conexao.Consulta("select htc.id, hm.url, htc.descricao " //ESSA É A LINHA 79
+ "from help_menu hm "
+ "left join help_tipos_chamados htc on htc.id = hm.id_tipos_chamados "
+ "where hm.id = " + _tipo.toString());
} catch (SQLException ex) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Erro ao Carregar Menu - Tela", ex.getMessage()));
return;
}
try {
rs.next();
} catch (SQLException ex) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Erro ao Carregar Menu - Tela - Next", ex.getMessage()));
return;
}
try {
tela = rs.getString("url");
tituloChamado = rs.getString("descricao");
idCodigoTipoChamado = rs.getInt("id");
} catch (SQLException ex) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Erro ao Passar Tipo tela para Chamada", ex.getMessage()));
return;
}
try {
if (rs.getInt("id") > 0) {
try {
rs = Conexao.Consulta("select count(*) as qtd "
+ "from help_abertura_chamado "
+ "where id_usuario = " + _idUsuario.toString()
+ " and status = 'F' and (status_retorno_usuario = 'R' or status_retorno_usuario is null)");
} catch (SQLException ex) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Erro ao Carregar Menu - Tela - Erro qtd", ex.getMessage()));
return;
}
try {
while (rs.next()) {
if (rs.getInt("qtd") > 0) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Impossível Abertura de Chamado:", "Você possuí um chamado pendente para finalização. Verifique!"));
tela = "meusChamadosUsuario.xhtml";
}
}
} catch (SQLException ex) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Erro ao Carregar Menu - Tela - While Impossivel Abrir chamados", ex.getMessage()));
}
}
} catch (SQLException ex) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Erro ao Carregar Menu - Tela - If id > 0", ex.getMessage()));
}
}
telaChamada();
}
Coloquei todos os try para poder ver se em algum caso aconteceria essa exceção, mas nao entra em nenhuma dessas.
Ate no meu web.xml adicionei essa opçao para ver se chamava minha tela, mas tbm nao chama:
Exatamente, seu fabricante de conexões não está funcionando no ambiente de produção que é outro sistema operacional.
Isso pode ter a ver com a configuração do banco de dados e configuração do conector JAR (driver) de banco de dados para sua aplicação carregar.
O NullPointerException você não pega porque é um erro não verificável. Você pode evitar este erro se verificar se o objeto está nulo antes de operá-lo.
E onde você inicializa a variável stmt? Com certeza ela não foi inicializada ou teve seu valor atribuído para null.
Vou ser sincero com você, seu programa poderia muito bem usar um Datasource do servidor de aplicação para você retirar esses controles da classe Conexao que irão detonar seu sistema quando for utilizado por mais de um usuário.
Realmente nao estava inicializando a variavel, o que eu fiz para inicializar ela e rever a conexao toda vez foi chamando o metodo de conectar, assim inicializa toda vez.
public static ResultSet Consulta(String sql) throws SQLException {
Conecta(); //ALTERADO AQUI
resultado = stmt.executeQuery(sql); ///ESSA AQUI É A LINHA 85 QUE DÁ O ERRO
return resultado;
}
Como eu poderia usar pelo servidor de aplicação essa conexão, pq realmente estou tendo muito problema nessa questao de conexão, horas funciona muito bem, ora dá um erro de NullPointer do nada, na primeira vez que conecta no sistema
[quote=josivanl]Realmente nao estava inicializando a variavel, o que eu fiz para inicializar ela e rever a conexao toda vez foi chamando o metodo de conectar, assim inicializa toda vez.
public static ResultSet Consulta(String sql) throws SQLException {
Conecta(); //ALTERADO AQUI
resultado = stmt.executeQuery(sql); ///ESSA AQUI É A LINHA 85 QUE DÁ O ERRO
return resultado;
}
Como eu poderia usar pelo servidor de aplicação essa conexão, pq realmente estou tendo muito problema nessa questao de conexão, horas funciona muito bem, ora dá um erro de NullPointer do nada, na primeira vez que conecta no sistema
Alguma sugestão, luz?
Obrigado a todos!!
[/quote]
Utilize Datasources. Todo servidor de aplicação provê. É muito melhor você configurar um pool de conexões do que fazer um código macarrônico pra conectar no banco. Isso só vai te trazer problemas (que você mesmo já constatou).