Fechar conexao com o Banco no finalize

Bom dia a todos!

Bom, estava eu hoje de manhã lendo algumas threads aqui no GUJ quando uma delas me levou a ler esse link no javaranch:
http://www.coderanch.com/t/481930/Programmer-Certification-SCJP/certification/does-gc-still-have-chance

Bom, em certo momento me deparei com a declaração (repetidas vezes):

Fiquei curioso e fui pesquisar esse shutdown hook (algo como “gancho ao finalizar”, ao pé da letra, melhores traduções por favor me informem hehe).
Nessa busca (que não foi difícil) encontrei esse link interessante:

http://java.sun.com/j2se/1.5.0/docs/guide/lang/hook-design.html

Foi bastante explicativo.

Mas enfim, indo agora ao ponto tenho algumas perguntas:

1 - Por que a execução do finalize não é garantida?

2 - Qual seria uma boa forma (ou melhor/melhores, se houver) de se usar esse “shutdown hook”.
Como exemplo, inicio um método, peço uma conexão pro meu pool, uso-a e então devo fecha-la, como fazer isso de uma forma inteligente ?

3 - Li em uma outra thread a um tempo atrás que no Java7 não haverá a necessidade, por questões de segurança e performance, que se feche os recursos explicitamente mas que não há problemas caso o faça. Isso se aplica a conexões de bancos? Ainda assim seria seguro continuar fazendo essas liberações explicitamente, uma vez que não é garantido quando isso será feito, correto?

Muito obrigado a todos pela paciência em ler meu post, prefiro ser bastante explicativo para não deixar muitas dúvidas do que quero.

Abraços!

Eu te respondo a primeira:

A JVM não garante que o método finalize irá ser executado pois o mesmo é chamado quando o garbage collector considerar que aquele objeto é lixo. Como não é garantido que um objeto será de fato coletado pelo GC (mesmo que o mesmo já esteja sem referências válidas), então também não é garantido que o finalize será chamado.

Nossa, pera ae.
Me confundi.
Confundi o finalize com finally de bloco try…catch :oops:
O finalize realmente não é garantido que será executado nem quando… já o finally isso não se aplica, correto? Daí não há a necessidade de um shutdown hook, ok?

O que ele sugere é que seja criado um hook em alternativa ao finallize, não ao finally então, ok?

Obrigado!

[quote=Tchello] Nossa, pera ae.
Me confundi.
Confundi o finalize com finally de bloco try…catch :oops:
O finalize realmente não é garantido que será executado nem quando… já o finally isso não se aplica, correto? Daí não há a necessidade de um shutdown hook, ok?

O que ele sugere é que seja criado um hook em alternativa ao finallize, não ao finally então, ok?

Obrigado![/quote]

Isso mesmo. O bloco finally executa em quaisquer ocasiões, a menos que a JVM seja interrompida durante a execução do try ou do catch.
Se você colocar um return dentro do try por exemplo, mesmo assim o finally será executado antes que o método retorne.
Muito cuidado pra não confundir gato com lebre, rs.

Foi a falta do açúcar no café =/
Fui pegar meu cafézinho hoje cedo e não tinha açucar, daí peguei de qualquer jeito e me distrai ai ler aquele tópico.

Mas de qualquer forma fica o aprendizado, shutdown hookers em alternativa ao finalize!
Gostei desse cara.

Abraços.

Há uma thread “Finalizer” que executa periodicamente os métodos “finalize” e é integrada ao garbage collector. Essa thread, assim como todo o funcionamento do Garbage Collector, não dá garantias de execução (por exemplo, pode ser que uma determinada finalização nunca seja executada, mesmo usando “runFinalizersOnExit”.

O pool deve ter um timer que fecha periodicamente conexões que foram devolvidas ao pool e estão desocupadas há algum tempo. Um “finalizer” ou um “shutdown hook” sozinho não consegue fazer isso.

Um uso clássico de um shutdown hook é o que é usado no JBoss. Quando você encerra o JBoss, ele efetua o “undeploy” das aplicações, limpa um monte de coisas, talvez feche as conexões do pool , e então sai.

Besteira. Isso seria equivalente a mexer na filosofia do Java (e também o .NET funciona assim também): você tem de fechar (devolver) explicitamente os recursos que são tomados de alguma entidade externa (como o sistema operacional - arquivos, recursos gráficos… ou o banco de dados).

Uma coisa que o C# tem, e que está sendo estudado para entrar no Java 7, é a devolução de recursos através de um comando especial. Vou dar um exemplo em sintaxe C# mas com classes Java, para você entender melhor.

using (PrintWriter pw = new PrintWriter ("teste.txt")) {
    pw.write ("Hello, world!");
}

Isso seria equivalente ao código Java:

PrintWriter pw = null;
try {
    pw = new PrintWriter ("teste.txt");
    pw.write ("Hello, world!");
} finally {
    try {if (pw != null) pw.close();} catch (IOException ex) {}
}

que é bem mais complicado e, convenhamos, nunca vi ninguém escrever isso direito.

Perfeito, eu por exemplo uso o pool do JBoss/WebLogic configurados nos respectivos DataSources.
O que você está sugerindo é que esse pool finalize conexões que possuam um certo tempo de inatividade?
Ou seja, começo a execução de um método que pede uma conexão ao pool, esse método a usa e então a fecha, ainda assim o pool (por questões de segurança) deve verificar de tempos em tempos se há conexões inativas e fecha-las? Isso seria válido apenas nos casos onde eu esqueci de fechar explicitamente, correto?

Abraços.

Mas enfim, os shutdown hooks só serão executados na finalização da JVM, correto?
Então ainda assim para muitos casos ele não serve como alternativa ao finalize, pois esse só liberará esses recursos quando a aplicação for finalizada e em muitos casos queremos essa liberação no tempo de execução da aplicação, correto?