Semana 13 - Gestores de Dependencias en Java
¿Para qué sirve un gestor de dependencias?
Un gestor de dependencias es una herramienta que automatiza la gestión de bibliotecas y dependencias externas en un proyecto de software. Sus principales funciones son:
- Descarga automática de dependencias: Obtiene bibliotecas y sus versiones específicas desde repositorios remotos (como Maven Central o JCenter).
- Gestión de versiones: Resuelve conflictos entre versiones de dependencias y asegura compatibilidad.
- Configuración centralizada: Define todas las dependencias en un solo archivo, facilitando su mantenimiento.
- Automatización de tareas: Compila, prueba, empaqueta y despliega el proyecto.
- Reproducibilidad: Garantiza que todos los entornos (desarrollo, producción) usen las mismas versiones de bibliotecas.
- Transitividad: Maneja dependencias de dependencias automáticamente.
En Java, los gestores de dependencias más populares son Maven y Gradle.
Maven
¿Qué es Maven?
Maven es un gestor de dependencias y herramienta de construcción ampliamente utilizado en proyectos Java. Se basa en un archivo de configuración XML llamado pom.xml
(Project Object Model).
Características principales
- Estructura estandarizada: Define una estructura de directorios predeterminada (
src/main/java
,src/test/java
, etc.). - Repositorios centralizados: Usa Maven Central como repositorio principal, pero permite configurar otros.
- Ciclo de vida de construcción: Incluye fases predefinidas como
compile
,test
,package
,install
, ydeploy
. - Gestión de dependencias: Declara dependencias en
pom.xml
, y Maven las descarga y gestiona automáticamente. - Plugins: Extiende funcionalidades mediante plugins (por ejemplo, para empaquetar un JAR o ejecutar pruebas).
Ejemplo de pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.3.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.3.4</version>
</plugin>
</plugins>
</build>
</project>
Ventajas
- Configuración sencilla y estandarizada.
- Gran comunidad y soporte.
- Amplia disponibilidad de dependencias en Maven Central.
- Fácil integración con herramientas CI/CD (Jenkins, GitHub Actions).
Desventajas
- Archivos XML extensos en proyectos grandes.
- Menos flexible que Gradle para tareas personalizadas.
- Curva de aprendizaje inicial para configurar plugins avanzados.
Comandos comunes
mvn clean
: Limpia el directorio de compilación.mvn compile
: Compila el código.mvn test
: Ejecuta pruebas.mvn package
: Empaqueta el proyecto (JAR/WAR).mvn install
: Instala el artefacto en el repositorio local.mvn dependency:tree
: Muestra el árbol de dependencias.
Gradle
¿Qué es Gradle?
Gradle es un gestor de dependencias y herramienta de construcción moderna que usa un lenguaje basado en Groovy o Kotlin (DSL) para configurar proyectos. Su archivo principal es build.gradle
.
Características principales
- Flexibilidad: Permite scripts personalizados y configuraciones complejas.
- Rendimiento: Usa un modelo incremental y caching para construcciones más rápidas.
- Sintaxis concisa: Los archivos
build.gradle
son más compactos quepom.xml
. - Soporte multiplataforma: Compatible con Java, Android, Kotlin, y más.
- Ecosistema de plugins: Similar a Maven, pero con mayor facilidad para tareas personalizadas.
Ejemplo de build.gradle
(Kotlin DSL)
plugins {
id("org.springframework.boot") version "3.3.4"
id("io.spring.dependency-management") version "1.1.6"
java
}
group = "com.example"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web:3.3.4")
testImplementation("org.springframework.boot:spring-boot-starter-test:3.3.4")
}
tasks.test {
useJUnitPlatform()
}
Ventajas
- Sintaxis más legible y concisa.
- Construcciones más rápidas gracias a la compilación incremental.
- Mayor flexibilidad para proyectos no estándares.
- Soporte nativo para Kotlin DSL, ideal para proyectos modernos.
Desventajas
- Menor estandarización que Maven, lo que puede llevar a configuraciones inconsistentes.
- Curva de aprendizaje para Groovy/Kotlin si no estás familiarizado.
- Menos adoptado en proyectos empresariales tradicionales.
Comandos comunes
gradle build
: Compila, prueba y empaqueta el proyecto.gradle clean
: Limpia el directorio de compilación.gradle test
: Ejecuta pruebas.gradle dependencies
: Muestra las dependencias.gradle wrapper
: Genera el Gradle Wrapper para reproducibilidad.
Comparación entre Maven y Gradle
Característica | Maven | Gradle |
---|---|---|
Lenguaje de configuración | XML (pom.xml ) |
Groovy/Kotlin (build.gradle ) |
Rendimiento | Más lento en proyectos grandes | Más rápido (compilación incremental) |
Flexibilidad | Menos flexible, estandarizado | Muy flexible, personalizable |
Curva de aprendizaje | Media (XML) | Media-alta (Groovy/Kotlin) |
Estandarización | Alta (convenciones estrictas) | Media (más libertad) |
Uso principal | Proyectos empresariales | Proyectos modernos, Android |
¿Cuándo usar cada uno? - Maven: Ideal para proyectos que requieren estandarización, simplicidad y una gran comunidad (empresas, proyectos legacy). - Gradle: Mejor para proyectos que necesitan flexibilidad, rendimiento optimizado o están en ecosistemas modernos como Android o Kotlin.
Tutorial: Proyecto Básico con Vaadin, MySQL y JPA (Instalación de dependencias)
En este tutorial, construiremos una aplicación web simple para gestionar tareas usando Vaadin para la interfaz de usuario, Spring Data JPA para la persistencia y MySQL como base de datos. La aplicación permitirá agregar, editar, eliminar y listar tareas con una interfaz amigable.
Tecnologías utilizadas
- Java 21: Lenguaje de programación.
- Spring Boot 3.3.4: Framework para el backend.
- Vaadin 24.5.0: Framework para la interfaz de usuario.
- Spring Data JPA: Para interactuar con la base de datos.
- MySQL: Base de datos relacional.
- Maven: Sistema de construcción.
Prerrequisitos
- Java 21 instalado (verifica con
java -version
). - Maven instalado (verifica con
mvn -version
). - MySQL instalado y corriendo.
- Un IDE como IntelliJ IDEA, Eclipse o VS Code (opcional, pero recomendado).
Estructura del Proyecto
La estructura del proyecto sigue el estándar de un proyecto Maven con Spring Boot. A continuación, se detalla la organización de carpetas y archivos:
vaadin-todo-app/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/vaadintodoapp/
│ │ │ ├── MainView.java # Vista principal de Vaadin
│ │ │ ├── Task.java # Entidad JPA
│ │ │ ├── TaskRepository.java # Repositorio JPA
│ │ │ └── VaadinTodoAppApplication.java # Clase principal de Spring Boot
│ │ └── resources/
│ │ └── application.properties # Configuración de la base de datos
├── pom.xml # Archivo de configuración de Maven
└── README.md # (Opcional) Documentación del proyecto
Paso 1: Configurar el Proyecto
1.1 Crear el proyecto Maven
- Crea un directorio llamado
vaadin-todo-app
y navega a él:mkdir vaadin-todo-app cd vaadin-todo-app
- Crea un archivo
pom.xml
con las dependencias necesarias para Spring Boot, Vaadin, JPA y MySQL.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>vaadin-todo-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Vaadin To-Do App</name>
<description>Proyecto básico con Vaadin, MySQL y JPA</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
<relativePath/>
</parent>
<properties>
<java.version>21</java.version>
<vaadin.version>24.5.0</vaadin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
<version>${vaadin.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
- Si usas un IDE, importa el proyecto como un proyecto Maven.
Paso 2: Configurar la Base de Datos
2.1 Crear la base de datos en MySQL
Crea una base de datos llamada todo_db
:
CREATE DATABASE todo_db;
2.2 Configurar la conexión a MySQL
Crea el archivo application.properties
en src/main/resources
para configurar la conexión a la base de datos.
MySQL configuration.
spring.datasource.url = jdbc:mysql://localhost:3306/data_b1?createDatabaseIfNotExist=true&useSSL=false&serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password =
spring.jpa.hibernate.ddl-auto = update
- Reemplaza
tu_contraseña
con la contraseña de tu usuario de MySQL. spring.jpa.hibernate.ddl-auto=update
crea o actualiza las tablas automáticamente según las entidades JPA.
Paso 3: Crear el Modelo de Datos
3.1 Definir la Entidad Task
Crea la clase Task
en src/main/java/com/example/vaadintodoapp
. Esta entidad representa una tarea con un ID, una descripción y un estado (completada o no).
package com.example.vaadintodoapp;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;
@Entity
@Data
public class Task {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String description;
private boolean completed;
}
@Entity
: Marca la clase como una entidad JPA.@Id
y@GeneratedValue
: Define el campoid
como clave primaria con incremento automático.@Data
(Lombok): Genera getters, setters y otros métodos automáticamente.
Paso 4: Crear el Repositorio JPA
Crea la interfaz TaskRepository
en src/main/java/com/example/vaadintodoapp
para manejar las operaciones CRUD.
package com.example.vaadintodoapp;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TaskRepository extends JpaRepository<Task, Long> {
}
JpaRepository<Task, Long>
proporciona métodos CRUD predefinidos comosave
,findAll
,delete
, etc.
Paso 5: Crear la Interfaz de Usuario con Vaadin
Crea la clase MainView
en src/main/java/com/example/vaadintodoapp
para definir la interfaz de usuario. Esta vista incluye un formulario para agregar/editar tareas y una tabla para mostrarlas.
package com.example.vaadintodoapp;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.router.Route;
import org.springframework.beans.factory.annotation.Autowired;
@Route("")
public class MainView extends VerticalLayout {
private final TaskRepository taskRepository;
private final TextField descriptionField = new TextField("Descripción");
private final Checkbox completedCheckbox = new Checkbox("Completada");
private final Button saveButton = new Button("Guardar");
private final Button deleteButton = new Button("Eliminar");
private final Grid<Task> taskGrid = new Grid<>(Task.class);
private final Binder<Task> binder = new Binder<>(Task.class);
public MainView(TaskRepository taskRepository) {
this.taskRepository = taskRepository;
// Configurar el formulario
binder.bind(descriptionField, Task::getDescription, Task::setDescription);
binder.bind(completedCheckbox, Task::isCompleted, Task::setCompleted);
saveButton.addClickListener(e -> saveTask());
deleteButton.addClickListener(e -> deleteTask());
// Configurar la cuadrícula
taskGrid.setColumns("description", "completed");
taskGrid.asSingleSelect().addValueChangeListener(e -> {
binder.setBean(e.getValue());
});
refreshGrid();
// Layout
HorizontalLayout formLayout = new HorizontalLayout(descriptionField, completedCheckbox, saveButton, deleteButton);
add(formLayout, taskGrid);
}
private void saveTask() {
Task task = binder.getBean() != null ? binder.getBean() : new Task();
try {
binder.writeBean(task);
taskRepository.save(task);
refreshGrid();
binder.setBean(null);
clearForm();
} catch (com.vaadin.flow.data.binder.ValidationException e) {
// Handle validation exception (e.g., show a notification)
e.printStackTrace();
}
}
private void deleteTask() {
Task task = binder.getBean();
if (task != null) {
taskRepository.delete(task);
refreshGrid();
binder.setBean(null);
clearForm();
}
}
private void refreshGrid() {
taskGrid.setItems(taskRepository.findAll());
}
private void clearForm() {
descriptionField.clear();
completedCheckbox.clear();
}
}
@Route("")
: Define esta vista como la página principal (ruta raíz).Binder
: Vincula los campos del formulario con los atributos de la entidadTask
.Grid
: Muestra las tareas en una tabla.
Paso 6: Crear la Clase Principal de Spring Boot
Crea la clase VaadinTodoAppApplication
en src/main/java/com/example/vaadintodoapp
para iniciar la aplicación.
package com.example.vaadintodoapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class VaadinTodoAppApplication {
public static void main(String[] args) {
SpringApplication.run(VaadinTodoAppApplication.class, args);
}
}
Paso 7: Ejecutar la Aplicación
- Asegúrate de que MySQL esté corriendo y la base de datos
todo_db
esté creada. - Desde la raíz del proyecto, ejecuta:
mvn spring-boot:run
- Abre tu navegador en
http://localhost:8080
.
Interfaz de la aplicación
- Formulario: Ingresa una descripción y marca si la tarea está completada.
- Botón "Guardar": Agrega una nueva tarea o actualiza una existente.
- Tabla: Muestra todas las tareas. Selecciona una tarea para editarla o eliminarla.
- Botón "Eliminar": Elimina la tarea seleccionada.
Paso 8: Probar la Aplicación
- Agrega una tarea:
- Escribe "Comprar víveres" en el campo de descripción.
- Marca la casilla "Completada" si corresponde.
- Haz clic en "Guardar".
- Edita una tarea:
- Selecciona una tarea en la tabla.
- Modifica la descripción o el estado.
- Haz clic en "Guardar".
- Elimina una tarea:
- Selecciona una tarea en la tabla.
- Haz clic en "Eliminar".