Reload automático de classes com JavaRebel, da ZeroTurnAround
Uma das coisas mais legais para um cara que desenvolve em Java e depois começa a desenvolver em uma linguagem como Ruby é o feedback instantâneo – basta você alterar o código-fonte e a alteração já é refletida imediatamente na Aplicacão em runtime. Programando em Java tem que passar pelo processo de compilação. Programando Java EE tem que esperar reiniciar o servidor. E isso leva muito tempo.
Um dos primeiros projetos que eu participei foi um software de billing utilizando a boa e velha “arquitetura J2EE”: um monte de EJB sendo utilizado para praticamente todas as operações. Nada contra a arquitetura montada em si (digo, neste post em particular não vou discutir isso, fica para um outro post EJB vs Spring/etc) mas um grande problema era o processo de build e deploy: ele era simplesmente muito demorado! Na melhor das hipóteses, levava uns 5 minutos para executar a build e o deploy no ambiente local de desenvolvimento, mas geralmente levava bem mais tempo. Ou seja, para cada alteração você tinha que esperar pelo menos 5 minutos para poder testar localmente o que você tinha feito.
Esse tipo de situação é muito comum nos projetos desenvolvidos em Java por aí. Como se não bastasse termos perder tempo compilando e empacotarndo o código, temos que reiniciar o servidor e esperar mais algum tempo… É claro que podemos minimizar o problema por usar um pacote expandido e o sistema de debug do Java para recarregar o corpo dos metodos, mas não é o suficiente, você ainda perderá preciosos minutos (ou horas) por dia só com build e deploy.
Eu acho fantástico ter a rapidez de codificar e logo em seguida, sem demorar um segundo sequer a mais, poder testar\executar o código criado ou alterado. É muito chato você ter que esperar todo esse tempo, você acaba com o tempo perdendo a paciência e juntando um monte de alterações para depois fazer a build e o deploy da aplicação. Eu particularmente não gosto disso, quanto mais rápido for o feedback, melhor.

Para amenizar essa situação, você pode usar a excelente ferramenta Javarebel, da Zeroturnaround. Javarebel é um plugin para a JVM (usando aquele esquema maluco do -javaagent) que faz o reload dos arquivos .class alterados sem precisar reiniciar a JVM! É quase que milagroso, basta apontar qual diretórioas suas classes estão localizadas que ele vai automagicamente aplicar as alterações feitas na aplicação em runtime!
Nada de parar a JVM, nada de reiniciar o servidor, nada de perder vários minutos esperando a aplicação voltar ao ar, as alterações são feitas e aplicadas na hora. Sempre que eu falo do JavaRebel pra alguém, me perguntam: “mas funciona mesmo?”. Faz uns 8 meses que eu estou usando o JavaRebel sem grandes problemas.
Infelizmente é uma ferramenta paga, não é muito caro, mas algumas pessoas evitam todas as ferramentas pagas, mesmo que custem barato. Eu mesmo só estou usando o JavaRebel por que eu ganhei uma licença numa promoção do tipo “primeiras pessoas que mandarem um e-mail ganham uma licença”
Mas eu acho que vale a pena fazer um test-drive na ferramenta (tem um trial e um eles devolvem o dinheiro caso não esteja satisfeito em 30 dias).
A instalação e configuração é bem simples, o site deles tem uma documetação bem bacana, mas vai aí um resumão: Coloque o jar do javarebel na mesma pasta que o arquivo de licença do JavaRebel e adicione dois parâmetros na hora de subir a JVM:
- -javaagent:caminho-do-jar-do-javarebel/javarebel.jar
- -Drebel.dirs=diretório-com-os-arquivos-.class
E é basicamente isso
Com esses dois parâmetros o JavaRebel vai automaticamente recarregar todas as alteraçõs feitas nos arquivos .class localizados na pasta passada no parâmetro -Drebel.dirs.
Algumas pessoas me perguntam pra que pagar e configurar se o sistema do debugger do Java já tem um jeito para recarregar classes alteradas. O problema do debugger do Java é que ele só recarrega o corpo dos métodos, se você criar uma classe, adicionar um método, remover um método, adicionar um parâmetro, etc, a sua classe não vai ser recarregada. No site do JavaRebel tem uma comparação bem interessante sobre esse assunto.
Infelizmente a ferramenta não é perfeita, tem uma ou outra incompatibilidade, por isso não acho uma boa idéia usar em ambiente de produção. Além disso, muitas vezes o reload da classe alterada não vai ter efeito algum, por que os frameworks Java em geral se configuram no startup da aplicação e não são reconfigurados quando uma classe é recarreada. Por exemplo, criar uma classe anotada com @Entity não vai fazer o EntityManager enxerge a classe, só depois de ele ser reconfigurado (que geralmente ocorre quando a aplicação é reiniciada), no caso do JPA. O JavaRebel tem algumas gambiarras alguns plug-ins para alguns frameworks como Struts2 e Spring (recomendo não olhar o código para não se assustar).
Eu já usei no Tomcat, JBoss e no Jetty, usando a JVM da Sun, nas versões 1.4, 1.5 e 1.6, tanto no Windows como no Linux. No site deles, eles alegam ser compatíveis com várias VMs e containers:
Supported JVM’s
- Sun Java 1.4.xi, 5.x, 6.x
- JRockit JVM 8.1sp6 or later
- JRockit JVM 9.x 1.5.0_06 or later
- JRockit JVM 1.6.x
- IBM J9 1.4.x, 5.x, 6.x
- Apple MRJ 1.4.x, 5.x, 6.x
Supported Containers
- IBM WebSphere 6.x
- BEA Weblogic 8.x, 9.x, 10.x
- GlassFish 2.x
- Oracle OC4J 9.x, 10.x
- Tomcat 4.x, 5.x, 6.x
- JBoss 3.x, 4.x, 5.x
- Jetty 5.x, 6.x, 7.x
- Caucho Resin 3.0.x
- Jonas 4.x
- Equinox OSGi (including Eclipse plugins)
- IntelliJ IDEA plugins
- Atlassian Confluence plugins
Não sei se em todos os casos vale a pena usar a ferramenta, desde que eu comecei a usar o JavaRebel não tive nenhum problema sério, só elogios á ferrementa, aumento consideravelmente a produtividade. Eu acredito que pelo menos uma teste vale a pena fazer, criei esse post por que percebi que muita gente ainda não teve a oportunidade ou a curiosidade de conhecer essa excelente ferramenta
6 comentários até agora
Leave a reply
Existe alguma integração ou plugin com projetos em Maven ?
Interessante!
Atualmente eu me utilizo da IDE MyEclipse. Ele trabalha muito bem com o HotSwap da JVM e somente quando altero a estrutura física da classe que já está no class-loader é que preciso reiniciar o servidor.
Ter um hot-deploy decente durante o desenvolvimento é algo que paga qualquer custo. Perdemos muitas horas por semanas somente restartando o server.
Uma coisa interessante é que quando você trabalha com abordagens como TDD (ou apenas testes) você diminui muito a necessidade de restartar o servidor, o que acaba por diminuir a perca de tempo com deploys durante o desenvolvimento.
Vou pegar um tempinho e fazer alguns testes com o JavaRebel
Abraços e boa dica!
@boaglio
Não tem nada específico, mas eu uso com o Maven e aponto o -Drebel.dirs para o target/classes
JavaRebel foi um dos poucos produtos que eu paguei com prazer e achando barato. Os ganhos de produtividade com esse carinha são imensos. Utilizo sem qualquer problema com o Mentawai + Sysdeo dentro do Eclipse. Desenvolvimento non-stop com pouquíssimos restart do Tomcat. Como diria Galvão Bueno: “Programar em Java é bom. Programar em Java sem restartar o Tomcat é bão demais!”
Olá, rubem, estou com dificuldade, para instalar o Java Rebel com o plugin do WTP, pelo seguinte problema. O WTP compilar para a pasta $PATH_DO_PROJETO/build/classes, e quando faço deploy ai ele joga para a pasta $TOMCAT_HOME/wtpwebapps/contexto, o problemo e que coloco o agent do javarebel para “escutar” as classes em $TOMCAT_HOME/wtpwebapps/contexto, mas quando mudo no eclipse, ele so muda os .class do pasta $PATH_DO_PROJETO/build/classes, não refletindo as alterações.
Ai se eu marco para o WTP fazer o hot-deploy, ele restarta o Tomcat sozinho.
Sabe como posso configurá-lo para resolver este problema?
Valeu
Poxa isso é uma boa para quem tem a infelicidade de estar em um projeto brutalmente hardcore e com uma arquitetura em que o maven está sendo utilizado. mto boa a dica! abraços!