Produtividade com hot deploy no Eclipse e Tomcat
Aprenda como habilitar o hot deploy de aplicações Web no plugin WTP do Eclipse
Quando desenvolvemos aplicações Web em Java, uma tarefa que fazemos várias vezes ao dia é reiniciar o servidor de aplicação sempre que modificamos uma classe Java ou arquivo de configuração. Isso é tão natural para a maioria dos desenvolvedores que eles não percebem o tempo gasto para derrubar e levantar o servidor. O problema é que este "pequeno" intervalo para reiniciar a aplicação interfere drasticamente na produtividade do desenvolvedor.
Para você ter uma idéia, a maioria das aplicações Web de pequeno e médio porte levam em torno de 30s para iniciarem em um container leve como o Tomcat; se tomarmos como 8h/dia de trabalho de um desenvolvedor e que, em média ele reinicia a aplicação umas 120-150 vezes durante o dia, este desenvolvedor leva em torno de 60-75min por dia apenas esperando o servidor subir. São aproximadamente 5h/semana olhando pro console do Eclipse aguardando a aplicação iniciar.
Esta demora não acontece por acaso! Sempre que alteramos uma classe Java do projeto no Eclipse o plugin WTP (Web Tools Project) se encarrega de automaticamente recarregar todo o contexto da aplicação no Tomcat. Este processo do WTP é tão demorado e problemático que na maioria das vezes é mais rápido e seguro reiniciar manualmente o Tomcat. Muitos desenvolvedores não sabem, mas mesmo com o WTP podemos alterar classes Java sem a necessidade de reiniciar o contexto da aplicação, semelhante ao que acontece com as JSPs.
Este recurso do plugin é chamado de hot deploy.
Habilitando o hot deploy no Eclipse e Tomcat
Levando em consideração que você desenvolve no Eclipse IDE for Java EE Developers e já possui o Apache Tomcat configurado no WTP, habilitar o hot deploy no Eclipse é uma tarefa simples, basta desligarmos o recurso responsável pelo recarregamento automático dos projetos no Tomcat e depois iniciarmos o servidor em modo debug. Para simplificar a configuração no Eclipse e não deixar nenhum detalhe passar, siga os seguintes passos para habilitar o hot deploy de classes:
Abra a view Servers e dê um duplo-clique no servidor Tomcat (normalmente o nome está como "Tomcat v7.0 Server at localhost");
Acesse a aba Modules que fica na parte inferior da view Servers. Depois selecione um módulo, então clique em "Edit..." e desabilite a opção "Auto reloading enabled";
Salve as modificações da aba Servers;
Por fim, sempre inicie o Tomcat em modo Debug;
Pronto! A partir de agora sempre que você modificar o conteúdo de alguma classe Java no projeto o hot deploy irá acontecer imediatamente na aplicação em execução e, com isso, você poderá ver as mudanças bastando dar um F5 (refresh) no navegador.
Limitações
O suporte a hot deploy de classes foi adicionado ao Java Platform Debugger Architecture (JPDA) da JVM desde o Java 1.4.1 com o nome de HotSwap. O Eclipse faz uso do HotSwap via WTP através do Hot code replace (HCR). E é graças ao HCR que podemos por exemplo alterar o valor de variáveis ou mesmo o código fonte de uma classe em modo debug e continuar o fluxo sem a necessidade de reiniciar a aplicação.
Apesar das vantagens, o HCR possui algumas limitações na qual precisamos ficar atentos. Por exemplo, não podemos alterar a estrutura de classes, ou seja, adicionar/remover atributos e métodos ou mudar a assinatura de métodos; também não podemos adicionar novas classes enquanto debugamos; além disso, alguns tipos de métodos não podem ser modificados, como o conteúdo do método main
ou de qualquer método invocado via reflections com o uso de java.lang.reflect.Method.invoke()
.
Olhando o código abaixo fica mais simples entender como o HotSwap funciona:
public class ExemploDeHotdeploy {
public static void main(String[] args) {
String foo = "não é modificável"; // hot deploy não funciona aqui!
foo += blah();
System.out.println(foo);
}
public static String blah() {
String bar = "bar";
bar += "blah"; // hot deploy funciona aqui! <3
return bar;
}
}
No fim das contas, o que podemos modificar é o corpo dos métodos.
Para ter suporte a um hot deploy mais robusto, existem soluções pagas e muito boas como o JRebel ou gratuitas como o DCE VM ou Spring-Loaded. Com elas podemos alterar a estrutura de classes, adicionar/remover classes e até arquivos de configurações de alguns frameworks enquanto a aplicação estiver rodando.
É possível obter uma licença gratuita para desenvolvedor do JRebel bastando apenas fazer algumas divulgações da ferramenta em redes sociais. Para maiores detalhes, siga os passos no blog do Arthur Gregório.
Temos também alguns plugins do Eclipse que simplificam a vida dos desenvolvedores e já configuram o hot deploy na configuração da IDE, além de sempre iniciarem os servidores em modo debug, como o MyEclipse, por exemplo.
Dicas para melhorar o hot deploy
Por estarmos sempre iniciando a aplicação em modo debug, mais recursos da máquina são utilizados, como memória e cpu. Por esse motivo, é possível perceber que a aplicação inicia ligeiramente mais lenta, além disso, dependendo do tamanho da aplicação, é importante configurar os argumentos de memória da JVM na configuração do Tomcat. Por exemplo, meu Tomcat está sempre configurado com os seguintes argumentos:
-Xms256m -Xmx512m -XX:MaxPermSize=192m
Quando o Tomcat demora muito a iniciar ou parar, o WTP automaticamente mata o processo do Tomcat. Por padrão o tempo máximo que o WTP espera para iniciar o Tomcat é de 45s, mas podemos alterar este timeout para um valor superior, como 120s, por exemplo. Para isso, basta na view Servers, no painel "Timeouts", modificarmos o limite de start para algo compatível com a sua aplicação:
As versões mais recentes do Eclipse, como Kepler e Luna, já trazem uma opção para desabilitar o "Auto reloading" dos contextos no Tomcat. Dessa forma, sempre que você fizer o deploy de um novo projeto no Tomcat ele já terá o recarregamento automático desligado por padrão. Para isso, basta na view Servers, dentro do painel "Server Options", desabilitar a opção "Modules auto reload by default":
Produtividade no dia a dia
A idéia deste post veio da experiência de sala de aula durante os cursos de Java para Web e JSF 2 com Spring, pois muitos alunos não conheciam o suporte ao hot deploy do Eclipse. O curioso é que os alunos um pouco mais experientes, que nunca usaram hot deploy, ficavam maravilhados em não ter que reiniciar o servidor sempre que modificavam o corpo de um método - muitos deles até consideraram esta dica muito valiosa!
Com uma técnica simples dessa, conseguimos melhorar a produtividade do nosso dia a dia consideravelmente. Passamos menos tempo esperando o servidor iniciar e mais tempo programando e corrigindo código.
E você, já conhecia ou usava o suporte a hot deploy do Eclipse? Ou tem utilizado outras soluções como o JRebel?
You might also be interested in these articles...
Desenvolvedor e instrutor na TriadWorks
Posted in: ambiente de desenvolvimentoeclipseheap spacehot deployhotdeployjavajava eejavaeejeeoutofmemoryperformanceprodutividadetomcatweb