Como usar o SBT (simple-build-tool) com JRebel


Prólogo

Não muito tempo atrás, em um lugar não muito distante, chamado Web, existiam dois tipos de programadores:

  • Aqueles que dominavam a arte da linguagem interpretada, como Ruby, PHP. Acostumados com o tempo de Turnaround zero, em troca de menos performance.
  • E aqueles que dominavam a disciplina da linguagem compilada e tipada, como o Java, Scala e C#, que em troca de mais performance e servidores de aplicações, submeteram-se ao sofrimento do tempo de Turnaround

Um certo dia, um grupo de sábios estonianos uniram seus poderes e inventaram um artefato chamado JRebel que miraculosamente diminuía o tempo de Turnaround para os desenvolvedores Java e Scala.

Nota de rodapé do autor: Tempo de Turnaround é usado para denominar, entre outras coisas, o intervalo de tempo entre o momento em que você salva seu código e vê as alterações na tela. Em PHP esse tempo é zero, você salva o arquivo, faz refresh no browser e as mudanças estão lá. Em Java, caso você esteja desenvolvendo para um servidor de aplicação como o Weblogic, você tem que salvar seu código, compilar, empacotar, baixar e subir o Weblogic, aí sim você vê suas alterações.

Também conhecido como o tempo em que você levanta para pegar um cafézinho enquanto o servidor está subindo.

E assim eles destruíram os programadores de Ruby on Rails e viveram felizes para sempre.

Brincadeira.

Eles só ficaram mais produtivos, e passaram a tomar menos café (ou não).

JRebel, a salvação

Chega de historinha, esse é um post sério.

JRebel é uma ferramenta criada para diminuir o tempo que você espera para ver seu código funcionando.

Como ele faz isso?

Ele é um Java Agent, que altera os Classloaders da sua aplicação quando ela é executada. Esses classloaders modificados ficam monitorando os arquivos .class de sua aplicação. Quando algum desses .class muda, por exemplo quando você faz uma modificação e compila, o classloader percebe a mudança e recarrega a classe, sem que haja necessidade de reiniciar a aplicação ou o servidor.

Enquanto isso, no mundo dos builds

SBT, ou o Simple-Build-Tool

Essa ferramenta, escrita em Scala, não foi feita pelo Silvio Santos não.

Ela é uma alternativa para o famigerado Maven. Enquanto o Maven vem perdendo adeptos, por ser considerada uma ferramenta engessada, lenta, burra, o SBT vem arrasando corações no submundo emergente de Scala.

O foco aqui não é fazer uma apresentação detalhada de SBT, mas posso elencar alguns pontos chave:

  • É rápido.
  • A configuração é feita em Scala.
  • Integra com Maven e Ivy.
  • Dá para abrir um console Scala com todo seu projeto no Classpath para ficar testando coisas.
  • Consegue monitorar seu código fonte, executando o build assim que algum arquivo muda.

Se você programa em Scala e nunca usou o SBT experimente.

SBT e JRebel, a combinação ágil

Essa combinação vem ficando cada vez mais famosa, especialmente entre os programadores Lift. E tenho que confessar, funciona muito bem. Meu tempo de turnaround está praticamente zero.

Como configurar?

Primeiro baixe o JRebel e em seguida peça uma licença gratuita de um ano para desenvolvedores Scala (ao lado direito da página).

Quando receber a licença siga as instruções (colocar o arquivo da licença no diretório do JRebel).

Em seguida baixe o JAR do SBT, coloque em uma pasta qualquer e crie um script que irá chamá-lo:

java -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=516m -Xmx512M -Xss2M -noverify -javaagent:[CAMINHO_DO_JREBEL.JAR] -jar `dirname $0`/[CAMINHO_DO_JAR_DO_SBT] "$@"

Note que estamos informando ao Java que o JRebel é um javaagent. Assim, quando o você executar o SBT usando esse Script, o JRebel vai subir junto.

Coloque esse Script no seu PATH.

Como usar?

Para tirar os proveitos do JRebel você precisa criar uma aplicação em SBT, usar uma aplicação em SBT, ou configurar o SBT em uma aplicação Maven:

Se você usa Maven, saiba que o SBT consegue ler as dependências do arquivo pom.xml caso você não especifique nenhuma dependência na classe de configuração do SBT. Isso é bastante útil se você precisa manter um projeto em Maven e ao mesmo tempo quiser tirar proveito do SBT.

Vejamos um exemplo. Vamos usar um projeto Lift de exemplo que coloquei no Github:


git clone git://github.com/felipekamakura/sbt_jrebel_lift_example.git myApp


> cd myApp
> sbt


#############################################################

JRebel 3.5 (201011151605)
(c) Copyright ZeroTurnaround OU, Estonia, Tartu.

Over the last 23 days JRebel prevented
at least 92 redeploys/restarts saving you about 3.7 hours.

This product is licensed to Personal
until April 3, 2011
for up to developer seats on site.

The following plugins are disabled at the moment:
* JBoss AOP Plugin (set -Drebel.jbossaop_plugin=true to enable)
Integration with jboss aop agent
* Jackson Plugin (set -Drebel.jackson_plugin=true to enable)
Supports reloading Jackson's JsonSerializer caches.
* Lift Plugin (set -Drebel.lift_plugin=true to enable)
Supports reloading singleton objects that extend LiftScreen or Wizard.
* Log4j plugin (set -Drebel.log4j-plugin=true to enable)
Reloads full configuration of log4j
* RESTEasy Plugin (set -Drebel.resteasy_plugin=true to enable)
Supports adding/changing methods with @Path annotation for RESTEasy application.
* Seam Wicket Plugin (set -Drebel.seam_wicket_plugin=true to enable)
Integration with load time weaving seam annotations to wicket classes
(-javaagent:)
* WebObjects Plugin (set -Drebel.webobjects_plugin=true to enable)
WebObjects JRebel Plugin

#############################################################

Getting Scala 2.7.7 ...
:: retrieving :: org.scala-tools.sbt#boot-scala
confs: [default]
2 artifacts copied, 0 already retrieved (9911kB/5097ms)
Getting org.scala-tools.sbt sbt_2.7.7 0.7.4 ...
:: retrieving :: org.scala-tools.sbt#boot-app
confs: [default]
15 artifacts copied, 0 already retrieved (4096kB/13414ms)
[info] Recompiling project definition...
[info] Source analysis: 1 new/modified, 0 indirectly invalidated, 0 removed.
Getting Scala 2.8.1 ...
:: retrieving :: org.scala-tools.sbt#boot-scala
confs: [default]
2 artifacts copied, 0 already retrieved (15118kB/805ms)
[info] Building project Lift SBT Template 0.1 against Scala 2.8.1
[info] using LiftProject with sbt 0.7.4 and Scala 2.7.7
>

Você está agora no console do SBT. Execute o comando update para baixar as dependências do projeto:

>update

Em seguida, compile e suba a aplicação exemplo com o comando jetty-run:

>jetty-run

Legal, se tudo deu certo, a aplicação Lift de exemplo está disponível em http://localhost:8080/. Entre lá para dar uma olhada, deve estar assim:
Aplicação Lift, JRebel e SBT

Vamos agora ver o poder do JRebel alterando uma classe, compilando-a e vendo a mudança na tela:

Execute o seguinte comando no SBT:

>~prepare-webapp

O prepare-webapp é um comando do SBT que compila e empacota a sua aplicação web. O ~ (til) antes do comando fala para o SBT – “rode o seguinte comando sempre que houve uma mudança no código fonte”.

Sempre que você usar o ~ (til) no SBT, ele vai ficar em um “estado de alerta”, e vai construir tudo sempre que houver mudança. Isso é essencial para conseguirmos baixar o tempo de Turnaround. E também o SBT é esperto o suficiente para compilar apenas as classes de seu projeto que foram alteradas.

Agora abra e altere o arquivo src/main/scala/code/snippet/HelloWorld.scala. Troque a frase de saudação para sua frase favorita.

class HelloWorld {
// Altere a linha abaixo para sua frase favorita
def howdy = "#greet *" #> "Cai fora curioso."
}

Então, quando você salvar a classe, o SBT vai começar a compilar tudo e o JRebel vai notar que houve mudança no .class dessa classe.

De um refresh no browser e note que a tela foi atualizada com suas modificações! Rápido, prático, indolor! Veja que a frase mudou:
Aplicação depois da alteração

É só isso pessoal! Nada de intervalo para o cafézinho durante o build, foi mal…

Anúncios