ANT vs Maven vs Gradle

Antes de entrar en ANT, Maven o Gradle, debemos entender algunas cosas relacionadas con ellos.

Dependencia: En general, una dependencia se refiere a cuando algo requiere alguna otra cosa para ejecutarse. En pocas palabras, ‘A’ tiene una dependencia de ‘B’ si ‘A’ requiere ‘B’ para su ejecución exitosa. En el mundo del software, una dependencia es cualquier cosa que su aplicación requiere para su ejecución exitosa. Es básicamente cualquier biblioteca de apoyo externo requerido por la aplicación. por ejemplo, zuul, hystrix, lombok, jdbc, etc.

Inicialmente, solíamos gestionar las dependencias por:

  • descargar el archivo jar de la biblioteca requerida manualmente desde Internet y añadirlo a nuestro proyecto.
  • escribir un script que descargará automáticamente la biblioteca de una fuente externa a través de la red.

Problemas a los que se enfrentan estas herramientas:

  • Añadir las dependencias descargándolas manualmente de internet es una tarea muy agotadora.
  • Nuestros scripts pueden fallar si la URL de la fuente externa cambia en internet.
  • Es muy difícil identificar y gestionar las dependencias transitivas en nuestra aplicación.

Herramienta de gestión de dependencias: Resuelve y gestiona las dependencias que requiere la aplicación.

Herramienta de construcción: Automatiza la creación de aplicaciones ejecutables a partir del código fuente. La construcción incorpora la compilación, el enlace y el empaquetado del código en una forma utilizable o ejecutable. La automatización de la construcción implica:

  1. Descargar las dependencias
  2. Compilar el código fuente en código binario
  3. Empaquetar ese código binario
  4. Ejecutar pruebas
  5. Desplegar en sistemas de producción

Gestión de dependencias y herramientas de construcción en java:

  • ANT + Ivy (2000/2004)
  • Maven (2004)
  • Gradle (2012)

Apache ANT (Another Neat Tool) es un proyecto de código abierto de Apache, lanzado en el año 2000. Es una librería java utilizada para automatizar los procesos de construcción de aplicaciones java. También se puede utilizar para construir aplicaciones no java. Sigue el principio de «Configuración sobre convención». En Ant, las diferentes fases del proceso de construcción se denominan «objetivos». Los archivos de compilación de ANT están escritos en XML y, por convención, se llaman «build.xml». Contiene tres elementos: proyecto, objetivo y tarea. Cada archivo de construcción contiene un proyecto. Cada cosa en el build.xml está bajo el elemento proyecto. El proyecto contiene al menos un objetivo (por defecto). El objetivo contiene un conjunto de tareas dentro de él y define un estado específico del proceso de construcción. Una tarea es una pieza de código que puede ser ejecutada. Cada nodo puede tener atributos asociados:

Atributos del proyecto:

  • Nombre: El nombre del proyecto.
  • Basedir: La carpeta raíz del proyecto y es opcional.
  • Default: El objetivo por defecto para la construcción. El proyecto puede tener uno o más números de objetivos. Se utiliza para especificar el objetivo por defecto del proyecto.

Atributos del objetivo:

  • Nombre: El nombre del objetivo.
  • Descripción: Una descripción sobre el objetivo.
  • Depende: Lista de todos los objetivos, separados por coma de los que depende este objetivo.
  • If: El objetivo se ejecuta si el atributo es verdadero.
  • Unless: El objetivo se ejecuta si el atributo no está establecido.

Ejemplo de Build.xml:

<?xml version="1.0"?>
<project>
<target name="hello">
<echo>Hello, World</echo>
</target>
</project>

Añadir dependencia en Ant + Ivy:

<dependency org="org.projectlombok" name="lombok" rev="1.18.10"/>

La principal ventaja de Ant es su flexibilidad. Ant no impone al desarrollador ninguna convención de codificación o estructura de proyecto. En consecuencia, esto significa que Ant requiere que los desarrolladores escriban todos los comandos por sí mismos, lo que a veces conduce a grandes archivos de construcción y son difíciles de mantener. Inicialmente, Ant no tenía soporte incorporado para la gestión de dependencias. Más tarde adoptó Apache Ivy, desarrollado como un subproyecto del proyecto Apache Ant, para la gestión de dependencias.

Apache Maven

Es una herramienta de gestión de dependencias y de automatización de la construcción, lanzada en 2004. Sigue utilizando XML pero supera los inconvenientes siguiendo el principio de «Convention over configuration». Se basa en convenciones y proporciona comandos predefinidos (objetivos). Su archivo de configuración, que contiene instrucciones de construcción y gestión de dependencias, se llama por convención «pom.xml» y está presente en la carpeta raíz del proyecto.

Flujo de trabajo de Maven

El motor de Maven toma pom.xml y el proyecto como entradas. Lee el archivo pom.xml y descarga las dependencias mencionadas en él como archivos jar en el repositorio local. Luego, ejecuta los ciclos de vida, las fases de construcción y los plugins. Al final, se genera un artefacto empaquetado y probado.

pom.xml ejemplo:

Algunas etiquetas importantes en el archivo pom.xml:

  • groupId: Representa la organización a la que pertenece el proyecto.
  • artifactId: Es el nombre del proyecto.
  • versión: Representa la versión del proyecto.
  • packaging: Representa la forma final de la construcción del proyecto. por ejemplo, jar, war.

Añadir dependencia en maven:

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>

Repositorio de maven:

Un repositorio es un directorio donde existen todos los archivos jar empaquetados junto con sus propios archivos pom. Estos archivos pom contienen las dependencias externas de ese proyecto. De esta manera maven descarga las dependencias de su proyecto recursivamente hasta que todas las dependencias requeridas están presentes en su repositorio local. Hay tres tipos de repositorios en maven:

  1. Repositorio local: Es un repositorio presente en la propia máquina del desarrollador.
  2. Repositorio a nivel de organización/remota: Es un repositorio presente dentro de la organización.
  3. Repositorio central: Es un repositorio a través de internet, creado y mantenido por la comunidad maven.

Cuando se especifica una dependencia en el fichero pom.xml de un proyecto, maven la busca en el repositorio local. Si no se encuentra allí, lo busca en el repositorio remoto/org wide. Si ni siquiera está presente allí, entonces lo busca en el repositorio central.

Maven prescribe una estructura de proyecto estricta, mientras que Ant proporciona flexibilidad allí también. Sus estrictas convenciones tienen el precio de ser mucho menos flexibles que Ant – la personalización de objetivos es muy difícil.

Desventajas de maven:

  1. La gestión de dependencias no maneja bien los conflictos entre diferentes versiones de la misma biblioteca.
  2. La personalización de los objetivos es difícil.

Gradle

Es una herramienta de gestión de dependencias y automatización de la construcción de código abierto, lanzada en 2012. Combina las partes buenas de Apache Ant y Apache Maven y construye sobre ellas y utiliza un lenguaje específico de dominio (basado en Groovy) en lugar de XML. Adoptó la flexibilidad de Ant y su ciclo de vida de Maven. También sigue el principio de «Convención sobre la configuración». Soporta los repositorios Maven e Ivy para recuperar las dependencias. Su archivo de configuración es por convención conocido como «build.gradle» y está presente en la carpeta raíz del proyecto. Gradle dio a sus pasos de construcción el nombre de «tareas», a diferencia de los «objetivos» de Ant o las «fases» de Maven. Google adoptó Gradle como la herramienta de construcción por defecto para el sistema operativo Android.

Gradle no utiliza XML. En su lugar, tiene su propio lenguaje específico de dominio basado en Groovy (uno de los lenguajes de la JVM). Como resultado, los scripts de construcción de Gradle tienden a ser mucho más cortos y claros que los escritos para Ant o Maven. La cantidad de código boilerplate es mucho menor con Gradle.

Configuraciones de Gradle

  • implementación: Se utiliza para declarar dependencias que no queremos exponer al tiempo de compilación de nuestros consumidores.
  • api: Se utiliza para declarar las dependencias que forman parte de nuestra API, es decir, para las dependencias que queremos exponer explícitamente a nuestros consumidores.
  • compileOnly: Nos permite declarar dependencias que sólo deben estar disponibles en tiempo de compilación, pero que no son necesarias en tiempo de ejecución. Un ejemplo de uso para esta configuración es un procesador de anotaciones como Lombok, que modifica el bytecode en tiempo de compilación. Después de la compilación ya no se necesita, por lo que la dependencia no está disponible en tiempo de ejecución.
  • runtimeOnly: Nos permite declarar dependencias que no son necesarias en tiempo de compilación, pero que estarán disponibles en tiempo de ejecución. Un ejemplo es SLF4J donde incluimos slf4j-api a la configuración implementation y una implementación de esa API (como slf4j-log4j12 o logback-classic) a la configuración runtimeOnly.
  • testImplementation: Similar a implementation, pero las dependencias declaradas con testImplementation sólo están disponibles durante la compilación y el tiempo de ejecución de las pruebas. Podemos utilizarlo para declarar dependencias a frameworks de pruebas como JUnit o Mockito que sólo necesitamos en las pruebas y que no deben estar disponibles en el código de producción.
  • testCompileOnly: Similar a compileOnly, pero las dependencias declaradas con testCompileOnly sólo están disponibles durante la compilación de las pruebas y no en tiempo de ejecución.
  • testRuntimeOnly: Similar a runtimeOnly, pero las dependencias declaradas con testRuntimeOnly sólo están disponibles durante el tiempo de ejecución de las pruebas y no en tiempo de compilación.

Proyectos y tareas en Gradle

Cada compilación de Gradle consta de uno o más proyectos. Cada proyecto consiste en un conjunto de tareas. Cada tarea representa una sola pieza de trabajo que un build realiza, por ejemplo, generar JavaDoc, publicar algunos archivos a un repositorio, etc.

Ejemplo de build.gradle

Repositorio de Gradle:

Los «alias» en Gradle se utilizan en caso de añadir repositorios de Maven a nuestro build del proyecto. Estos alias son los siguientes:

  • mavenCentral(): Este alias representa las dependencias que se obtienen del repositorio central de Maven 2.
  • jcenter(): Este alias representa las dependencias que se obtienen del repositorio de Maven JCenter de Bintray.
  • mavenLocal(): Este alias representa las dependencias que se obtienen del repositorio local de Maven.

Ejemplo: añadir el repositorio central de Maven en nuestro proyecto, añadir el siguiente fragmento de código a nuestro archivo ‘build.gradle’:

repositories {
mavenCentral()
}

Añadir dependencia en Gradle:

compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'

Ventajas:

  1. Maneja bastante bien las dependencias transitivas. Si existe una dependencia transitiva conflictiva en el proyecto, entonces para resolverla, selecciona la última versión de la dependencia. Por ejemplo, la dependencia ‘A’ requiere internamente la dependencia ‘C’ con la versión 2.0 y la dependencia ‘B’ requiere internamente la dependencia ‘C’ con la versión 3.0. Entonces Gradle utilizará la última versión de la dependencia ‘C’.
  2. Los archivos de configuración de Gradle son más pequeños en tamaño y más limpios, ya que utiliza un lenguaje específico de dominio, basado en Groovy en lugar de XML.
  3. Gradle utiliza el concepto de construcción incremental y evita el trabajo mediante el seguimiento de la entrada y salida de las tareas y sólo se ejecuta lo que es necesario, y sólo procesa los archivos que cambiaron cuando es posible y por lo tanto, realiza más rápido que maven.

Deja un comentario