Esse artigo faz parte da revista Java Magazine edição 13. Clique aqui para ler todos os artigos desta edição.

e aperfeiçoamentos. Estes são detalhados no documento J2SE 1.5 “Tiger” Feature List, cujo primeiro release público foi aprovado há pouco pelo JCP. É, porém, uma especificação dirigida aos implementadores da J2SE e não aos usuários finais – os desen­volvedores Java. A documentação do J2SDK 1.5.0-beta1 apresenta as novidades de forma mais clara, mas ainda insuficiente. Aqui tentarei “destrinchar” a nova plataforma tomando como base a especificação formal, mas com uma abordagem mais coesa, mos­trando vantagens e usos práticos de cada item, para motivar o leitor.


Diversos itens da especificação já foram explorados em artigos anteriores – novida­des da linguagem na Edição 12, e nova API de concorrência na Edição 11 – portanto, vou apenas focar no que ainda não foi visto. Também agrupei itens relacionados e reordenei alguns tópicos de acordo com suas interdependências para estruturar melhor a explicação.

Confiabilidade e gerenciamento

Alguns itens nesta seção podem parecer grego para muitos desenvolvedores. Certas APIs, como a JPDA, são usadas apenas por quem faz ferramentas de baixo nível, como depuradores e profilers. A maioria dos desenvolvedores jamais precisará lidar com essas coisas – mas veremos os resultados nas ferramentas. Mesmo a API java.util.concurrent é mais útil para quem im­plementa infra-estrutura.


Os tipos genéricos estão neste grupo porque a robustez adicional é o principal argumento a favor dessa melhoria, que elimina a possibilidade da maioria das ClassCastException. Veremos também que diversas interfaces da JVM precisaram ser atualizadas para contemplar mudanças na linguagem, até em casos de alterações apa­rentemente superficiais (“açúcar sintático”), como enums.


A maior novidade neste grupo: o Tiger inaugura uma nova era em qualidade de serviço para Java. Teremos incluídos na JVM um grande número de recursos avan­çados – de monitoração, gerenciamento, profiling, depuração etc. – possibilitando analisar aplicações Java de forma tão fácil e não-intrusiva (sem impacto em desem­penho, segurança ou deployment), que é bem possível que qualquer servidor em produção possa manter esses recursos sempre ativados, agilizando a resolução de
bugs e de problemas de desempenho. A seguir, detalhes sobre cada feature
neste grupo.

Suporte a JMX (JSR-003)

A API javax.management já faz parte do J2EE, e agora será incluída também no J2SE. A mudança é necessária para o su­porte a outras features do Tiger.

JMX (JSR-160)

Inclusão do conector JMX/RMI: javax.management.remote, javax.
management.remote.rmi
. Estes conectores são um subconjunto da JMX Remote API, que também inclui pacotes opcionais não incluídos no Tiger.

API de monitoração e gerenciamento da JVM (JSR-174)

Atualmente, o gerenciamento remoto da JVM é limitado e não padronizado. Admi­nistradores de aplicações Java dependem de ferramentas proprietárias, e que geral­mente exigem algum container. No JRE 1.5, a VM exporta um grande número de dados de monitoração e de desempenho (co­brindo a atividade de garbage collection, compilador JIT, threads etc.). Esses dados poderão ser acessados pelo código, como MBeans do pacote java.lang.management, ou remotamente, via RMI ou SNMP.

Com os conectores remotos, consoles de administração existentes poderão ser usa­dos para gerenciar uma JVM. A Figura 1 mostra o console XtremeJ 2.0, que funciona como plug-in para o Eclipse, conectado a um processo Java. Observe o enorme nível de detalhe das informações exibi­das. Nem dá para comparar com o parco volume de informações que poderíamos obter até o J2SE 1.4 (por exemplo, usando Runtime.freeMemory()). A ferramenta não depende de novas APIs do J2SE 1.5, mas com essa versão irá detectar os MBeans da VM, além de MBeans de aplicação (como os exportados pelo Tomcat, que usei no exemplo mostrado na figura).

Por default, a configuração do recurso de monitoração só ativa os MBeans que não têm impacto sobre o desempenho. Note que muitos destes medidores já existiam nas JVMs anteriores, pois são necessários para a inteligência do sofisticado runtime de Java – só não eram expostos por uma API. Também, por default, a JVM não ativa nenhum conector remoto. Se tais conecto­res forem ativados, seu acesso será seguro, exigindo autenticação e encriptação via SSL. No diretório jre/lib/management da distribuição do Tiger, você encontrará novos arquivos de configuração que per­mitem customizar todas essas opções.

Em vez de usar um console, o código da aplicação – ou o container, ou outro compo­nente do mesmo processo – pode invocar métodos da classe ManagementFactory para obter os MBeans que descrevem o compor­tamento da JVM. Por exemplo, você precisa saber quantas vezes algum thread ficou bloqueado fazendo wait()? Fácil:

import java.lang.management.*;

ThreadMBean tbean =

   ManagementFactory.getThreadMBean();

ThreadInfo tinfo =

   tbean.getThreadInfo(Thread.currentThread().getId());

...

System.out.println(“Waits = “ + tinfo.getWaitedCount());

Essa API é muito útil para técnicas avan­çadas, mas desenvolvedores e administra­dores acharão mais fácil usar aplicações de monitoração, como a mostrada anterior­mente, que podem gerar gráficos, ou dis­parar notificações quando certos valores excederem limites especificados etc.

Segurança de tipos em tempo de compi­lação com tipos genéricos (JSR-014)

Determina a inclusão de tipos genéricos. Veja a Edição 12 e também o quadro “A generalização do Java”.

API para gerar stack traces Java para todos os threads

Especifica os métodos Thread.getStackTrace()
e Thread.getAllStackTraces(). Atualmente, se você tem um processo Java que parece estar “em pane”, pode obter um dump de todos os threads, usando Ctrl+Break (Windows) ou Ctrl+\ (Unix). Isso exige ter um console aberto para o processo, o que raramente ocorre com aplicações em produção. No Unix, podemos usar kill –SIGQUIT pid para obter o mesmo efei­to sem um console, mas isso ainda exige intervenção manual – e a sorte de acionar o dump num momento crítico. Com a nova API, a aplicação poderá gerar esse dump de forma automática, por exemplo ao capturar exceções críticas.

Por falar nisso, a interface Thread.UncaughtExceptionHandler permite definir tratadores de exceções não-captu­radas. Se uma exceção não-checada (por exemplo, NullPointerException) não for tratada por nenhum catch da aplicação, a JVM irá disparar o handler definido para este thre­ad. Se não houver um handler específico, será executado um handler global, tam­bém configurável. Não havendo qualquer handler, a JVM recorre ao procedimento padrão de versões anteriores do J2SE, que é abortar o thread.

JPPA: profiling e instrumentação (JSR-163)

A Java Platform Profiling Architecture é uma API padronizada para profiling (aná­lise de desempenho) da JVM. Substitui a velha JVMPI (Java Virtual Machine Profiling Interface), que tinha status experimental e várias limitações. A nova API permitirá a implementação de profilers mais efi­cientes e padronizados: qualquer profiler será compatível com qualquer JVM, sem necessidade de usar JVMs modificadas; novos profilers serão mais poderosos e eficientes.


Uma das maiores vantagens da JPPA é permitir a ativação dinâmica de profiling. Se uma aplicação em produção começar a apresentar problemas de desempenho, um desenvolvedor poderá conectar-se ao processo existente e iniciar o profiling – que pode ser seletivo, restrito às classes de determinada aplicação de um container, por exemplo. Terminada a análise, basta desativar o profiling para que o desem­penho do processo volte ao normal. Tudo sem reiniciar a aplicação e sem ter que reproduzir o problema em ambiente de desenvolvimento.


A JPPA inclui o pacote java.lang.instrument, que permite criar, em 100% puro-Java, um instrumentador de bytecode, código que intercepta o carregamento de classes e executa qualquer modificação nessas classes dinamicamente. Um profiler pode usar isso, por exemplo, para injetar, após todos os new, código que atualiza
estatísticas de alocação. Mas é possível usar a API para qualquer técnica que envolva a transformação do código. Um exemplo é a nova versão do IDE IntelliJ, que usa instrumentação para gerar dina­micamente parte do código de interface gráfica.

JPDA: adicionar suporte a Generics e enums

Adiciona suporte a tipos genéricos e enums às APIs, protocolos e ferramentas de depuração da JVM (JVMDI, JDWP, JDI, JDB).

JPDA: conexões e transportes plugáveis

Adiciona à JPDA a capacidade de criar conectores customizados. Atualmente essa API suporta sockets e memória com­partilhada, mas será possível adicionar outros transportes. Por exemplo, com um conector SOAP você poderia depurar um processo executando na rede interna do cliente, sem complicações, como instalar uma VPN ou abrir portas do firewall.

JDI: subconjunto read-only da JDI; mé­todos can...(); exceções

Melhorias para a JDI – Java Debugging Interface. O item mais interessante é a operação read-only, que permite depu­radores conectar à JVM, mas só executar operações de leitura. Isso torna possível deixar processos “abertos” para conexões de depuração, sem perda de segurança.

JDI: clarificações sobre HotSwap

Corrige alguns pontos obscuros da JDI em relação ao recurso de HotSwap (“edi­te-e-continue”). A especificação atual permite incompatibilidades entre alguns depuradores e JVMs.

JVMTI: requisitos para depuração

A especificação diz que essa melhoria permitirá aos depuradores acompanhar corretamente a inicialização e o encerra­mento da JVM. Isso é bastante útil, mas a letra miúda dessa feature inclui um item pouco relacionado que é meu favorito: “adicionar valor de retorno ao evento de saída de método”. Esse recurso permite aos depuradores exibir o valor retornado pelo último método invocado, o que atualmente não é possível. Quando o retorno do mé­todo não é usado (ou é usado diretamente como argumento de outra invocação ou expressão), muitos programadores recor­rem a uma variável dummy somente para saber o valor retornado. Isso deixará de ser necessário.

Adicionar bibliotecas de concorrência ao núcleo de Java (JSR-166)

...

Quer ler esse conteúdo completo? Tenha acesso completo