Skip to content

Connection Leak Paradise

Leak

Quem programa em Java e nunca passou por esse problema? Você está desenvolvendo, tudo funciona perfeitamente, quando a aplicação vai para produção e os usuários começam a usar você percebe que o contador de conexões disponíveis no seu pool só diminui.

As razões para isso podem ser as mais variadas (sendo a maioria deles problemas da aplicação e não algo ligado ao data source, servidor de aplicação ou mesmo driver jdbc), mas as mais comuns são:

  • ausência de chamada ao connection.close();
  • falta de um tratamento de excessões, e conseqüentemente, o método close() não é chamado;

É importante saber, que sempre que você estiver lidando diretamente com Connection (o que não é algo muito aconselhável, sabendo que já existem diversos frameworks que abstraem/simplificam a utilização de jdbc), você deve fechar ela através do método close() e o mesmo deve estar dentro de um bloco finally{}, para que ele seja executado mesmo se ocorrer um problema durante a execução do seu código.

Mas e quando você já revisou “todo” seu código e mesmo assim as conexões continuam vazando? Você olha as conexões do seu pool e elas simplesmente parecem ir para o limbo. Aqui alguns já podem começar a se perguntar, “mas tem como eu monitorar as conexões do meu pool?”. E é aqui que entra um recurso não muito conhecido (e menos ainda, usado): Java Management Extensions ou simplesmente JMX.

Copiando o site da Sun:

JMX technology provides the tools for building distributed, Web-based, modular and dynamic solutions for managing and monitoring devices, applications, and service-driven networks. By design, this standard is suitable for adapting legacy systems, implementing new management and monitoring solutions, and plugging into those of the future.

A maioria (se não todos) dos application servers já vem com recursos JMX prontos pra monitoramento e diagnóstico de connection leaks. Ativar o monitoramento do data source pode muitas vezes sacrificar um pouco da performance da aplicação (principalmente em um arquitetura Database-Centered), mas normalmente é um custo aceitável para descobrir os pontos de perda das conexões.

No JBoss, servidor de aplicação que eu utilizo no meu atual projeto, ligar o monitoramento é bem simples. Quando ativo, ele basicamente armazena o stack trace de todos os pontos onde temos chamadas à getConnection(), até que essa conexão sehja devolvida ao pool. Para ligar o monitoramento, altere o arquivo de configuração do seu data source(provavelmente um *-ds.xml) adicionando a linha abaixo
<local-tx-datasource>
.....
<track-statements>true</track-statements>
</local-tx-datasource>

Agora basta acessar o mbean CachedConnectionManager através da interface JMX do Jboss e invocar listInUseConnections() para ver o stack trace das conexões que não foram fechadas. Provavelmente vai ser algo semelhante à essa. Se você quizer apenas ver como anda seu pool, acesse o mbean ManagedConnectionPool, procurando principalmente pelos seguinte valores:

  • AvailableConnectionCount - total de conexões disponíveis no pool
  • InUseConnectionCount - total de conexões sendo usadas atualmente
  • ConnectionCount - indica o total de conexões abertas atualmente no pool

Utilizando esses recursos e tendo um pouco de paciência, fica bem mais fácil achar os pontos de vazamento da aplicação.

Mais informações:

Popularity: 33% [?]

Vote for Eclipse!

today i wear my sunday hat :)

Quem lê meu blog já à algum tempo, sabe que eu uso o Eclipse como principal ferramenta de trabalho. O que poucos sabem é que todos podem colaborar nas decisões do projeto, e de quebra, priorizar as correções de bugs e melhorias. Pra dar um empurrãozinho nos preguiçosos, segue minha lista atual de votos.

Community

  • 71735 - Eclipse source repository should convert to subversion.
  • 177497 - Bug status explanation page does not mention RESOLVED REMIND
  • 178923 - Remove LATER and REMIND resolutions when Bugzilla 3.0 is released

JDT

  • 182064 - Should be possible to “Migrate JAR File” in User Libraries
  • 182071 - [1.5][compiler] Unnecessary cast detection fails on ternary operation

Platform

  • 2009 - [EditorMgmt] Need to sort out handling of out-of-synch resources (1GDFD96)
  • 8009 - [Editor Mgmt] Split File Editor
  • 14916 - [Navigator] How can I recover from a “resource is out of sync” problem ?
  • 19419 - [resources] Cancellation during file transfer leaves files out-of-sync
  • 35973 - [resources] Better project organization
  • 46207 - [Workbench] [Services] Combine, compose, nest workbenchparts and editorparts
  • 52338 - [find/replace] regex replace with newline doesn’t insert anything
  • 92250 - [Workbench] Excessive amount of Permanent Generation memory reported by the VM
  • 102527 - [Wizards] Add support for projects refactoring (ie add/remove nature)
  • 118294 - Renaming an External Tool Builder (set to run during Auto Builds) causes error
  • 134416 - “Run As..” - “Ant Build” results in “Unable to find ant file to run”
  • 142364 - Replacing a large number of files hangs Eclipse
  • 163714 - Update manager interactively asks for mirror selection
  • 167660 - Out of sync not refreshed after file is closed
  • 169121 - cpu get >50 when I did refactor to a method
  • 169386 - [Edit] Local side of java compare should be more like java editor

Web Tools

  • 95450 - add extract include file for JSP source refactoring
  • 100511 - JavaScript refactoring and better code complete
  • 107052 - jsp editor error if jsp is under a subdirectory
  • 119334 - [jsp20] jsp:directive.tag import= list not recognized in .tagx XML tag files
  • 124288 - [Plan] Improve JSP 2.0 support
  • 124796 - [refactoring] moving a servlet is not reflected in web.xml
  • 136850 - JSTL Code Assist from imported projects.
  • 157465 - jsp fragment does not see any variables/tags from its parent
  • 168538 - “Convert to a Dynamic Web Project” should work for Java projects

Popularity: 29% [?]

Hibernate com PostGIS

Green pentagons

Uns meses atrás tive um problema com o uso do Hibernate, em um caso um tanto quanto incomum: o projeto usava Ingres, um banco de dados muito pouco usado, e com algumas particularidades idiotas (sendo gentíl com eles). O tipo responsável por armazenar as datas no Ingres, diferentemente de todos os outros bancos que já vi, aceita três “estados” nas colunas de data: uma data (óbvio), null, - sim, uma empty string.

Com isto, eu não poderia usar as classes padrão para datas no Java, acabei criando uma classe Data para tratar desses estados. Como o tipo foi criado por mim, o Hibernate não oferece nada pronto (por razões óbvias), tive que achar uma alternativa.

Lendo um pouco a referência, mais especificamente o capítulo Custom value types, descobri que para esses casos especiais, onde muitos já apelariam para alguma forma menos ortodoxa, o Hibernate oferece um mecanismo muito poderoso : os UserTypes.

Um UserType é basicamente uma interface que permite a implementação de como um determinado tipo será recuperado e persistido no seu banco de dados. Este recurso é extremamente útil e me salvou graciosamente.

E porque estou escrevendo isso tudo? Recebi hoje uma dúvida bem interessante por mensagem privada no GUJ. O usuário perguntava se haveria possibilidade de usar Hibernate em conjunto com o banco PostGIS - focado em armazenar dados geométricos.

O principal desafio é como mapear os dados que são armazenados em Geometry, como são chamados os tipos geométricos no PostGIS. Como não existe nenhum tipo nativo do Java que seria correspondente (e nem a especificação do JDBC preve isso - tipos clob, lobs e variantes não contam!), o trabalho pode ser um pouco mais complicado que se imagina.

Dando uma pesquisada, acabei encontrado uma thread da lista de users do PostGIS que trata exatamente disso. Nela é apresentada uma solução elegante para o tratamento dos tipos no Hibernate - e que acabou virando parte do projeto. SpatialEJB3 nada mais é que um UserType (GeometryType no caso) com a implementação responsável por tratar o tipo Geometry. Ele pode ser usadao tanto com Hibernate puro, quanto para EJB3. Só achei estranho que as classes ainda não estão no postgis.jar.

Para usar o recurso, fica extremamente simples:

@Type(type = "org.postgis.hibernate.GeometryType")
public Geometry getLocation(){
return location;
}

No site é possível encontrar a documentação do projeto.

Popularity: 25% [?]

We CAN Change The World

And we did it.

ps: e eles tão com um timinho bem produtivo de marketing, einh?

Popularity: 20% [?]

Democratic web host

Let's pretend we're just two people - 41/365

Desde que o porca morreu, estou hospedando meu blog no Dreamhost. Host bem bacana, uma série de features úteis (Subversion, Rails, etc etc), mas sempre há espaço pra melhoras. E eles tem uma forma bem legal de fazer isso, através de um espaço para os usuários votarem quais features acham legais de serem adicionadas. Dando uma passada rápida por cima achei algumas legais:

Sugestões também são bem-vindas.

Popularity: 21% [?]