Porque você deve trocar o Maven pelo Gradle?


Gradle

Qual ferramenta de build é a melhor?

Esse assunto é polêmico hein! Razão de inúmeros flamewars, brigas, mortes, guerras, protestos, atentados terroristas.

Não vou dizer que farei um análise imparcial aqui, porque não vou. Mas também não vou apenas ficar cuspindo no prato que comi – embora não sei porque isso é um problema, cuspir… em um prato vazio… qual problema… já comi mesmo…

Enfim! Minha ideia é apenas mostrar bons motivos para se usar o Gradle no lugar do Maven, assim como alguns anos atrás eu tive bons motivos para usar o Maven no lugar do Ant.

Muitos já se convenceram que o Gradle é uma alternativa mais interessante, inclusive o novo sistema de build do Android SDK é em Gradle.

Existe até uma teoria – bem justificada – do Neil Ford da Thoughtworks que eventualmente todo mundo vai ficar puto com o Maven e abandoná-lo.

Mas voltaremos nisso mais pra frente. Primeiro queria fazer um pequeno retrospecto autobiográfico…

Minha história com ferramentas de build

Meu background profissional é principalmente relacionado a Java e posso afirmar com bastante segurança que no mundo Java as ferramentas de build mais conhecidas e usadas são duas: o Ant e o Maven.

Tive a oportunidade de usar ambas na prática, em grandes e pequenos projetos, e essa foi minha experiência resumida com cada uma:

Experiências com Ant

– car***o, não tenho idéia do que esse build.xml de 32989 linhas faz…
– meu deus do céu, que target que eu rodo primeiro?

Experiências com Maven

– que maravilha, todos os 726362 projetos estão padronizados. É só fazer mvn install
\o/

– ah, agora eu sei que o source está em src/main/java e os resources em src/main/resources
\o/

– preciso implementar, buildar e distribuir um maldito plugin só pra fazer isso?!?!
<o>

– meu projeto precisa herdar desse mega-gigante pom.xml da empresa? Mas eu estou duplicando praticamente tudo novamente só para especializar meu build.
<o>

Explicando o que aconteceu:
Na época do Ant existia um grande problema de falta de padronização entre diferentes projetos. Cada um colocava o código fonte e os recursos onde julgava melhor, cada um colocava os artefatos gerados em uma pasta diferente, sem falar que muitos projetos não usavam nenhuma ferramenta para gerenciamento de dependências.

Além disso, os próprios arquivos descritores de build eram despadronizados. Se alguém trocava de projeto, a primeira coisa era descobrir qual target do Ant rodar primeiro.

Quando implantamos o Maven na empresa em que eu trabalho houve um ganho instantâneo em termos de padronização, adaptação de novas pessoas nas equipes e gerenciamento de dependências.

Claro que nem tudo é perfeito, no começo tivemos problemas com integração com IDEs, resistência e adaptação das pessoas, builds mais lentos. Mas os ganhos gerais compensaram essas dores de cabeça iniciais.

Mas depois de muitos anos usando o Maven, você começa a esbarrar em problemas muito inconvenientes a medida em que os builds se torna mais sofisticados e fora do comum, te obrigando a fazer vários malabarismos somente para contornar as imposições e limitações da ferramenta.

O Maven fez sua parte, mas já pode ir embora agora

Por ser uma ferramenta de opinião muito forte, a ponto de ser até considerada dogmática, ele conseguiu trazer uma padronização muito grande entre projetos da comunidade Java, criando praticamente uma nova cultura:

  • repositórios Maven
  • layout padrão de diretórios: src/main, src/test, target
  • build lifecycle

Mas se o Maven trouxe tantos benefícios, porque alguns estão trocando ele pelo Gradle?

Gosto de pensar no Maven como uma grande ditadura totalitária que veio instaurar a ordem quando tudo estava em um estado de total caos. Você tem que seguir o modelo rígido de build que ele impõe, seguir somente as fases que ele determina, ou então você terá muito trabalho subvertendo o sistema!

Imposition over Configuration

Assim o Maven funciona muito bem para 90% das coisas mais comuns de um build, mas complica muito para aqueles 10% de detalhes específicos do seu projeto (leia mais sobre a Dietzler’s Law no link do Neal Ford acima), já que a maneira como o Maven permite extensão é limitada e complicada demais.

Já está na hora dessa ditadura acabar e dar origem a um sistema mais flexível.

Gradle junta o melhor dos dois mundos e vai além

Enquanto o Ant oferece total flexibilidade para você definir as tarefas do seu build e como elas se sucedem umas as outras, o Maven vem com a proposta de um ciclo de vida rígido que todo build deve seguir.

A proposta do Gradle é continuar reforçando essa cultura e padronização do Maven através de convenção ao invés de imposição.

O Gradle incorporou o melhor dos dois lados:
Do Ant:

  • tasks altamente configuráveis
  • ciclo de vida de build flexível baseado em grafo aciclico direcionado.
  • gerenciamento de dependências com repositórios Ivy

Do Maven:

  • padronização do layout de diretórios
  • padronização do build lifecycle
  • builds multi-projeto
  • gerenciamento de dependências com repositórios Maven

Mas o Gradle vai muito além do Ant e do Maven: ele implementa uma verdadeira DSL em Groovy, permitindo a maior flexibilidade possível; no fim das contas, seu descritor de build é um script!

Enquanto no Maven e no Ant para criar uma coisinha diferente para seu build é preciso que você implemente e disponibilize um plugin, no Gradle você pode programar sua task ali mesmo, no build file.

Perai, o descritor de build é um script, então significa que vou voltar para o caos novamente?

Não, não vai, e o segredo está em seu sistema de plugins.

Conhecendo melhor o Gradle

No Gradle, a unidade de trabalho é a Task; equivalente ao Target do Ant ou ao Phase e o Goal do Maven.

Como no Ant, essas tasks podem ter dependência para outras tasks, criando um grafo direcionado acíclico. Dessa forma, quando você executa uma task, o Gradle executa antes todas as dependências dessa task.

No entanto, o Gradle conta com um sistema de plugin, e vários plugins nativos, que evitam que os builds voltem para o caos novamente, através da convenção.

Um plugin no Gradle é essencialmente um conjunto de tasks e configurações pré-definidas, que você pode importar em seu projeto. É como se um plugin no Gradle fosse uma Trait do Scala ou um Mixin do Ruby, ficando muito fácil estender um build através da composição e não da herança.

Portanto com o Gradle temos tanto a convenção, que nos permite ter a padronização e o inicio rápido de um novo projeto, como também a flexibilidade para customizar o build da maneira que for necessária, através de uma poderosa DSL Groovy.

Veja como é simples um build file para um projeto Java, com classes, resources e testes unitários.

Arquivo build.gradle:

apply plugin: 'java'

Sim, com uma linha você tem um projeto Java que compila, testa e empacota um JAR.

Outras vantagens do Gradle

Só uma listinha para te convencer a usar o Gradle:

  • Descritor de build em Groovy e não em XML
  • Suporte a repositórios Maven e Ivy
  • Build incremental que funciona de verdade
  • Composição ao invés de Herança
  • Suporte nativo a várias linguagens como Groovy e Scala
  • Integração com Eclipse, IntelliJ
  • Dezenas de plugins disponíveis
  • Android SDK e Hibernate já usam (vai ficar fora dessa?)

Estou convencido! E agora?

Shut up and take my money
Eu pretendo fazer outros posts sobre o funcionamento do Gradle, tentando destilar um pouco da documentação que tem por aí, mas para quem ficou entusiasmado com o Gradle, o guia dele é bem completo.

Também recomendo o livro Building and Testing with Gradle que é gratuito para leitura online.

Anúncios