paint-brush
O Gradle é realmente melhor que o Maven? - Meu veredicto finalby@nfrankel
5,520
5,520

O Gradle é realmente melhor que o Maven? - Meu veredicto final

Nicolas Fränkel8m2023/08/09
Read on Terminal Reader

Nesta postagem, gostaria de lançar alguma luz sobre o Gradle, para que eu possa direcionar as pessoas a ele, em vez de desmascarar o mesmo "raciocínio" repetidamente.
featured image - O Gradle é realmente melhor que o Maven? - Meu veredicto final
Nicolas Fränkel HackerNoon profile picture
0-item

Eu tweeto conteúdo técnico que considero interessante, mas os tweets engraçados são os que mais engajam. Participei da conferência JavaLand em março, tropecei no estande do Gradle e encontrei esta joia:

https://twitter.com/nicolas_frankel/status/1638549568957861889


Claro, em algum momento, um fanboy sequestrou o tópico e reivindicou a chamada superioridade de Gradle. Neste post, gostaria de lançar alguma luz sobre minha posição, para que eu possa direcionar as pessoas a ela, em vez de desmascarar o mesmo "raciocínio" repetidamente.


Para administrar isso, preciso voltar no tempo. O desenvolvimento de software é um campo em rápida mudança e muito do nosso entendimento é baseado na experiência pessoal. Então aqui está o meu.

Minha primeira ferramenta de construção: Ant


Comecei a desenvolver em Java em 2002. Na época, não havia ferramentas de construção: compilamos e construímos através do IDE. Só para constar, primeiro usei o Visual Age for Java; então, mudei para o Borland JBuilder.


Construir com um IDE tem um grande problema: cada desenvolvedor tem configurações dedicadas, então a geração do artefato depende da combinação desenvolvedor-máquina.


Compilações não repetíveis são um problema antigo. Minha primeira experiência com compilações repetíveis é Apache Ant:


Apache Ant é uma biblioteca Java e ferramenta de linha de comando cuja missão é conduzir processos descritos em arquivos de construção como alvos e pontos de extensão dependentes uns dos outros. O principal uso conhecido do Ant é a construção de aplicativos Java. O Ant fornece várias tarefas integradas que permitem compilar, montar, testar e executar aplicativos Java. O Ant também pode ser usado efetivamente para construir aplicativos não Java, por exemplo, aplicativos C ou C++. De forma mais geral, o Ant pode ser usado para pilotar qualquer tipo de processo que possa ser descrito em termos de alvos e tarefas.


-- https://ant.apache.org/


Ant é baseado em três abstrações principais:


  • Uma tarefa é uma unidade atômica de trabalho, por exemplo , javac para compilar arquivos Java, war para montar um arquivo da Web, etc. Ant fornece muitas tarefas prontas para uso, mas permite adicionar outras personalizadas.
  • Um destino é uma lista de tarefas.
  • Você pode definir dependências entre tarefas, como pacote dependente de compilação . A esse respeito, você pode ver Ant como um mecanismo de execução de fluxo de trabalho.


Logo me tornei "fluente" em Ant. Como consultor, fui de empresa em empresa, projeto em projeto. Inicialmente, eu configurei principalmente o Ant, mas o Ant se tornou mais difundido com o passar do tempo e encontrei configurações Ant existentes. Eu era consistente em meus projetos, mas outros projetos eram muito diferentes uns dos outros.


Toda vez, ao chegar a um novo projeto, você tinha que ler cuidadosamente a configuração do Ant para entender a construção personalizada. Além disso, a estrutura de cada projeto era diferente. Alguns colocam suas fontes em src , alguns em sources , alguns em uma estrutura aninhada, etc.


Lembro-me de um arquivo de construção genérico que tentava acomodar todas as necessidades de projeto de uma organização. Ele definiu mais de 80 alvos em mais de 2.000 linhas de XML. Levei um tempo não trivial para entender como usá-lo com ajuda e ainda mais tempo para poder ajustá-lo sem interromper os projetos.

Minha segunda ferramenta de construção: Maven

O projeto acima me fez pensar muito. Eu queria melhorar a situação, pois os mantenedores já haviam ultrapassado os limites do Ant. Na época, eu estava trabalhando com meu amigo Freddy Mallet (famoso pelo Sonar). Conversamos e ele me indicou Maven. Certa vez , construí um projeto com Maven , mas não tinha outra experiência anterior. Estudei a documentação por horas e, por meio de tentativas de tentativa e erro, sob a tutela de Freddy, migrei todo o arquivo de construção do Ant para um POM pai simples.


No Ant, você precisaria definir tudo em cada projeto. Por exemplo, o Ant requer a configuração do local dos arquivos Java para compilação; O Maven assume que eles estão em src/main/java , embora seja possível substituí-lo. O Maven revolucionou o campo de construção Java com sua abordagem Convenção sobre Configuração . Hoje em dia, muitos softwares oferecem configurações sensatas por padrão.


Para desenvolvedores que vão de projeto em projeto, como eu fiz, isso significa que há muito menos carga cognitiva ao ingressar em um novo projeto. Espero que as fontes Java estejam localizadas em src/main/java . As convenções do Maven continuam além da estrutura do projeto. Eles também definem o ciclo de vida do projeto, desde a compilação até o upload do artefato em um registro remoto, por meio de testes de unidade e integração.


Por fim, os desenvolvedores juniores tendem a ignorar isso, mas Maven definiu o termo gerenciamento de dependência . Ele introduziu a ideia de registros de artefatos, de onde é possível baixar dependências imutáveis e enviar artefatos. Antes disso, cada projeto tinha que armazenar dependências em seu repositório dedicado.


Para registro, havia algumas dependências armazenadas no projeto mencionado acima. Quando migrei do Ant para o Maven, tive que encontrar a versão exata da dependência. Para a maioria, era simples, como no nome do arquivo ou no manifesto do JAR. Um, no entanto, foi atualizado com classes adicionais.


Tanto para a imutabilidade.


O Maven teve uma profunda influência em todas as ferramentas de construção posteriores: elas se definiram em referência ao Maven.

Nenhuma ferramenta de construção minha: Gradle


A principal reivindicação de Gradle era corrigir as deficiências de Maven, ou pelo menos o que ele percebia como tal. Embora o Maven não esteja isento de censura, Gradle assumiu que o problema mais significativo era sua falta de flexibilidade. É uma suposição surpreendente, porque foi exatamente isso que o Maven melhorou em relação ao Ant. Os projetos Maven têm estruturas semelhantes e usam o mesmo ciclo de vida: o princípio da menor surpresa em vigor. Por outro lado, o Gradle permite personalizar quase todos os aspectos da compilação, incluindo o ciclo de vida.


Antes de confrontar o argumento da flexibilidade, deixe-me reconhecer dois ótimos recursos originais do Gradle que o Maven implementou posteriormente: o daemon do Gradle e o wrapper do Gradle.


Maven e Gradle são aplicativos Java executados na JVM. Iniciar uma JVM é caro em termos de tempo e recursos. O benefício é que a JVM de execução longa otimizará o código JIT-ed ao longo do tempo. Para tarefas de curto prazo, o benefício é zero e até prejudicial se você levar em consideração o tempo de inicialização da JVM. Gradle surgiu com o daemon Gradle. Quando você executar o Gradle, ele procurará um daemon em execução. Caso contrário, ele iniciará um novo. O aplicativo de linha de comando delegará tudo ao daemon. Como o próprio nome indica, o daemon não para quando a linha de comando termina. O daemon aproveita os benefícios da JVM.


As chances são de que seu aplicativo sobreviverá às suas ferramentas de construção atuais. O que acontece quando você precisa consertar um bug daqui a cinco anos, apenas para perceber que a ferramenta de construção do projeto não está disponível online? A ideia por trás do wrapper do Gradle é manter a versão exata do Gradle junto com o projeto e apenas o código suficiente para baixar a versão completa pela Internet. Como efeito colateral, os desenvolvedores não precisam instalar o Gradle localmente; todos usam a mesma versão, evitando qualquer discrepância.

Desmistificando a flexibilidade do Gradle

O Gradle trouxe os dois ótimos recursos acima que o Maven integrou, provando que a concorrência é boa. Apesar disso, ainda não encontro nenhum benefício do Gradle.


Vou tentar afastar o lado emocional. No início, o marketing da Gradle tentou rebaixar Maven em todas as ocasiões possíveis, publicou gráficos de comparação malucos e geralmente era muito agressivo em sua comunicação. Digamos que essa fase durou muito mais do que seria aceitável para uma jovem empresa em busca de seu lugar no mercado. Você poderia dizer que Gradle era muito edipiano em sua abordagem: tentando matar seu "pai" Maven. Finalmente, depois de todos esses anos, parece que ele se deu conta e agora "ama Maven".


Lembre-se de que antes de Maven assumir, todo projeto Ant era ad hoc. Maven acabou com isso. Ele trouxe a lei para o Velho Oeste Mundial de projetos personalizados. Você pode discordar da lei, mas é a lei de qualquer maneira, e todos precisam respeitá-la. Os padrões do Maven são tão arraigados que, embora seja possível sobrescrever alguns parâmetros, por exemplo , local de origem, ninguém nunca o faz.


Eu experimentei dois sintomas da flexibilidade de Gradle. Suspeito que existam muito mais.

Fases personalizadas do ciclo de vida

O Maven gerencia o teste de integração em quatro fases, executadas na ordem:


  1. pre-integration-test : configure tudo o que os testes precisam
  2. integration-test : executa os testes
  3. post-integration-test : limpe os recursos, se houver
  4. verify : agir de acordo com os resultados dos testes


Nunca usei as fases pré e pós, pois cada teste tinha uma lógica dedicada de configuração e desmontagem.


Por outro lado, Gradle não tem nenhuma noção de testes de integração . No entanto, os fanboys do Gradle terão prazer em explicar que você pode adicionar as fases que desejar. De fato, o Gradle permite a "personalização" do ciclo de vida: você pode adicionar quantas fases extras quiser ao ciclo de vida regular.


É uma bagunça, pois cada projeto precisará apresentar o número de fases necessárias e seu nome: integration-test , integration-tests , integration-testing , it (para os preguiçosos) etc. As opções são infinitas.

A síndrome do floco de neve

O Maven trata cada projeto como um projeto padrão regular. E se você tiver necessidades específicas, é possível escrever um plugin para isso. Escrever um plug-in Maven definitivamente não é divertido; portanto, você só escreve um quando é necessário, não apenas porque decidiu que a lei não se aplica a você.


Gradle afirma que a falta de flexibilidade é um problema; portanto, ele deseja corrigi-lo. Eu defendo o oposto: a falta de flexibilidade para minha ferramenta de construção é um recurso, não um bug. Gradle torna mais fácil hackear o build. Portanto, qualquer pessoa que pense que seu projeto é um floco de neve especial e que merece personalização o fará com prazer. Verificação da realidade: raramente é o caso; quando é, é para frameworks, não para projetos regulares. Os proponentes do Gradle dizem que ele ainda oferece padrões, permitindo uma configuração fácil. O cerne da questão é que não é um padrão se pode ser alterado por capricho de qualquer pessoa.


Gradle é a ferramenta de compilação de fato para projetos Android . Em uma das empresas em que trabalhei, alguém escreveu um código Groovy personalizado na compilação Gradle para executar o Sonar e enviar as métricas para a instância interna do Sonar. Não havia nenhum plug-in Sonar pronto para uso na época, ou presumo que não tenha funcionado. Até agora tudo bem.


Quando outra equipe criou o segundo projeto Android da empresa, eles copiaram e colaram a estrutura do primeiro projeto e o arquivo de construção. A coisa inteligente a fazer teria sido, neste momento, criar um plug-in interno do Gradle a partir do código específico do Sonar. Mas eles não fizeram isso porque o Gradle tornou muito fácil hackear a compilação. E eu, o odiador de Gradle, decidi criar o plug-in. Poderia ter sido uma experiência de desenvolvedor melhor, para dizer o mínimo. Na falta de documentação de qualidade e usando uma linguagem não tipada (Groovy), usei o console para imprimir a estrutura dos objetos para progredir.

Conclusão

A concorrência é boa e o Gradle trouxe novas ideias que o Maven integrou, o wrapper e o daemon. No entanto, o Gradle é construído com base na premissa de que a flexibilidade é boa, enquanto minha experiência me mostrou o contrário. Ant era muito flexível e a carga cognitiva para ir de um projeto para o outro era alta.


Nós, desenvolvedores, somos seres humanos: gostamos de pensar que nossos projetos são diferentes dos outros. Na maioria das vezes, eles não são. A personalização é apenas uma forma de satisfazer o nosso ego. Ferramentas de construção flexíveis nos permitem implementar essa personalização, garantida ou não.


Personalizações irrelevantes não trazem nenhum benefício e são fáceis de desenvolver, mas caras de manter. Se o gerenciamento de ativos de software fizer parte de minhas responsabilidades, sempre escolherei estabilidade em vez de flexibilidade para minha ferramenta de construção.


Originalmente publicado em A Java Geek em 6 de agosto de 2023