Após algumas horas de uso minha aplicação WEB Java apresenta erro

Estou usando Java EE, JSF, Hibernate, Spring. O erro que esta apresentando é:

06:15:09.027 [http-bio-8080-exec-2] ERROR o.h.transaction.JDBCTransaction - JDBC begin failed
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 30.883.101 milliseconds ago. The last packet sent successfully to the server was 30.883.101 milliseconds ago. is longer than the server configured value of ‘wait_timeout’. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property ‘autoReconnect=true’ to avoid this problem.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3364)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1983)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2618)
at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:5000)
at org.apache.tomcat.dbcp.dbcp.DelegatingConnection.setAutoCommit(DelegatingConnection.java:371)
at org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.setAutoCommit(PoolingDataSource.java:328)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:91)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1463)
at sun.reflect.GeneratedMethodAccessor21.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:344)
at com.sun.proxy.$Proxy30.beginTransaction(Unknown Source)
at lepostiche.web.filter.ConexaoHibernateFilter.doFilter(ConexaoHibernateFilter.java:61)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:344)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:110)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:98)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:95)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:79)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:55)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:36)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:106)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:150)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3345)
… 58 common frames omitted

Estou usando a classe ConexaoHibernateFilter para gerar as conexões no momento do acesso web.

public class ConexaoHibernateFilter implements Filter {

private SessionFactory sf;

public void init(FilterConfig config) throws ServletException {
this.sf = HibernateUtil.getSessionFactory();
}

public void destroy() {
}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws ServletException {

  Session currentSession = this.sf.getCurrentSession();

  Transaction transaction = null;

  try {
  	transaction = currentSession.beginTransaction();
  	chain.doFilter(servletRequest, servletResponse);
  	transaction.commit();
  	if (currentSession.isOpen()) {
  		currentSession.close();
  	}
  } catch (Throwable ex) {
  	try {
  		if (transaction.isActive()) {
  			transaction.rollback();
  		}
  	} catch (Throwable t) {
  		t.printStackTrace();
  	}
  	throw new ServletException(ex);
  }

}
}

A boa notícia é que a stacktrace que postou está relacionada à configuração de timeout do MYSQL.

Se quiser aumentar o timeout, aqui tem um exemplo.

Porém, vejo que não está finalizando a sessão do banco. O que provavelmente está ocasionando seu problema. Vc abre a sessão, trabalha e deixa ela em aberto, ocasionando o timeout da mesma.

Uma sugestão seria tratar o evento no finally, garantindo que a sessão seja sempre finalizada.

Boa tarde,

Concordo com o Raphael. Sua memória heap está ficando lotada de pool, portanto, provocando a queda da aplicação.

Sempre lembre de fechar uma conexão, imediatamente após de utiliza-la no propósito que foi definido. Só isso já vai dar um grande ganho de performance na aplicação, pensando somente no ponto da liberação do pool de conexões.

Se vc usa c3p0, é bom pensar em colocar uma linha como:
hibernate.c3p0.timeout=1800

O próprio Spring tem seu jeitinho de fazer essa contenção.

Deve ter uma forma melhor de declarar um método transacional no mundo “JavaEE/Spring/Hibernate”? Não é esse o propósito de filtros.

Bom dia!

@pfk66, meu rapaz, calma! Existe sim, mas requer paciência para ler. Eu mesmo gastei qze um ano pra entender como o Spring lidava com toda essa parafernalha. Hoje, eu tenho projetos monstruosos por aí no mercado utilizando Spring com primazia, velocidade e simplicidade. Mas pra isso acontecer, tive que gastar umas boas noites estudando. Eu comecei lendo isso aqui, no próprio site oficial dos caras:

https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/transaction.html

Aí, vc decide, com seu conhecimento e expertise como utilizar pra atender suas necessidades e deixar seus clientes felizes.

Esta dizendo que não é só apenas começar a usar? Hmmm. Faz sentido esse negócio de ler a documentação do Java EE, JSF, Hibernate, Spring, pra saber como funcionam, qual problema eles resolvem, etc.

Mas no caso em questão, onde a aplicação para de funcionar após algumas horas é porque esta abrindo uma transação por request, bastava ler a documentação sobre servlets filtros.

Dá pra só começar a usar sim. No caso do Spring, é só anotar o método onde a transação deve de fato ocorrer com @Transactional e a mágica acontece.

Ler a documentação? Da onde?
Para quê perder tempo lendo a documentação? Aliás, o que é isso, documentação? Come com colher?

Eu sou técnico raiz, do tipo que investe tempo lendo e aprendendo pra qdo escrever um código, ter certeza de que aquele código realmente vai funcionar e, mais que isso, a resultado vai fazer o meu bolso e o do cliente sorrirem.

Contudo, eu entendo. Se vc não quer ler nada e sair programando, é uma escolha sua. Eu não critico não. Até entendo.

Mas, eu, como profissional, prefiro ter certeza de que o meu trabalho está sendo bem feito devido ao conhecimento adquirido por estudo ao invés de tentativa e erro.

A mágica acontece? Sim. Mas vc sabe como a mágica foi bolada, criada? Fica aí um ponto pra um outro tópico.

Abraços a todos!

É isso que eu não consigo aceitar com relação ao desenvolvimento de sistemas hoje.
Quando eu dava aulas de java, insistia em ensinar servlets + jsp (ao menos 2 aulas), para que todos soubessem como funciona um framework action-based (no caso, era o Struts 2) ou o component-based (JSF 2). Era fácil de assimilar coisas como ciclos de vida e identificar possíveis falhas, corrigir erros e evoluir, sabendo como funciona por baixo dos panos.
A mesma coisa com hibernate. Eu fazia um overview de SQL, criando queries e sempre mostrava os dois lados, quando o sistema é modelado a partir das tabelas do banco e quando é projetado a partir dos objetos que o sistema terá.
Mas, o mais importante, era ensinar a olhar documentação. A procurar solução, em tentar, ao invés de, simplesmente, ficar olhando o código e esperar cair uma solução do céu.

@darlan_machado,

Não desanime. Os problemas de ontem são os problemas de hoje. Vc pode se perguntar: “Quantos projetos eu trabalhei na vida em que a documentação era boa, ou existia uma?”

A culpa não é nossa, nós os Engenheiros, Arquitetos, Analistas, Progarmadores. A culpa é do tempo que muitas vezes (se não todas) não é justo para vc trabalhar e documentar.

Aí, vem um tal de Xcrum Maxter e te fala que a documentação boa é a do código do sistema e que só isso já está bom pra deixar pra novos recursos que estão chegando ao projeto.

O sistema fica sem documentação, vira um Deus nos acuda pra dar manutenção e cada um que fique com suas mazelas.

O esquema é relaxar e deixar acontecer, claro, falando dessa parte de documentação. Nos outros aspectos, nós continuamos com nossas certificações, expertise, etc.

No fim, vc apela na magia e já era…rs

Não, brother.
A culpa é nossa sim.
Veja só, o cara chega com uma porrada de especificações, a gente mapeia e faz as análises e determina um prazo de 1 ano para desenvolver, com 8 devs sr e 12 pl. O cara diz que precisa disso em 6 meses, com 10 pl/jr. A culpa é de quem? Nossa, que aceita isso.
Aí descamba em horas extras, fins de semana, madrugada.
Além disso, a maioria passou por faculdades onde ignorou (se é que teve) as disciplinas de engenharia de sistemas e de análise. Focou em desenvolvimento e, um belo dia, percebe que poderia ser melhor se utilizasse alguma documentação.
Além de tudo isso, eu me refiro a ler coisas como o javadoc, ou os docs do Spring, do Hibernate e afins. Que, sim, existem. Podem não ser 100%, mas existem.

Eu não vou discordar do que vc falou não.

Mas, ao meu ver, penso que tudo o que vc disse e eu disse são pontos que, no fim do dia, vão interessar ao cliente somente se ele ver que ele vai ganhar muito dinheiro ou não vai ter muitas perdas financeiras.

Qto a aceitar ou não, vai muito de como está o mercado e de como está a necessidade da pessoa que está louca pra arrumar um emprego pq está desempregada há muito tempo.

Se for confrontar esse pensamento com o do junior que está chegando agora ao mercado, o que vc vai ter é um cara faminto por uma oportunidade de emprego, que, provavelmente, vai, realmente, aceitar qq desafio. Mas, quem nunca?

É tudo uma questão de objetivo financeiro do cliente versus o objetivo profissional de alguém.

Mas, é só meu ponto de vista, baseado no que tenho visto por aí.

Mas, no final do dia, pra quem realmente quer fazer um trabalho de qualidade, o que vai valer é vc se municiar bem de conhecimento, tecnologias e gerenciamento de pessoas + conflitos.

As pessoas sempre me perguntam: O que eu tenho que fazer pra ser arquiteto?
Eu respondo: estude.

Simples assim.