Un entorno mal preparado es la causa número uno de frustración cuando se empieza con Spring Boot: errores de compilación que parecen del framework pero son de versión de Java, dependencias que no se descargan, o un IDE que marca en rojo un proyecto perfectamente válido. Esta lección te guía para dejar la máquina lista de forma verificable: instalar y comprobar el JDK 21, entender la elección de Maven y su wrapper, escoger IDE, disponer de herramientas para probar la API y tener Docker preparado para los módulos avanzados. Terminaremos con un checklist que puedes ejecutar tal cual.

Contenido

  1. El JDK 21: instalación y verificación
  2. Gestionar varias versiones de Java con SDKMAN!
  3. Maven frente a Gradle, y por qué este curso usa Maven
  4. El wrapper de Maven (mvnw)
  5. Elegir un IDE: IntelliJ IDEA, Eclipse/STS y VS Code
  6. Herramientas para probar la API
  7. Docker: requisito para los módulos posteriores
  8. Checklist final de verificación
  9. Errores Comunes y Consejos
  10. Ejercicios

  1. El JDK 21: instalación y verificación

Spring Boot 3 exige Java 17 o superior. Usaremos Java 21, la versión LTS (soporte a largo plazo) más reciente y ampliamente adoptada en producción.

Necesitas un JDK (Java Development Kit), no solo un JRE: el JDK incluye el compilador javac, sin el cual Maven no puede construir nada.

Distribuciones disponibles

Todas implementan el mismo estándar; la diferencia está en el soporte y el empaquetado.

Distribución Proveedor Notas
Eclipse Temurin Adoptium La opción por defecto recomendada: gratuita, sin registro, multiplataforma
Amazon Corretto AWS Buena si despliegas en AWS; soporte largo
Azul Zulu Azul Systems Amplia cobertura de plataformas
Oracle JDK Oracle Licencia con condiciones; innecesario para aprender
OpenJDK de la distro Debian, Ubuntu, Fedora Cómodo en Linux, versión atada a la distribución

Linux

En distribuciones basadas en Debian o Ubuntu:

# Actualizar índices e instalar el JDK 21 desde los repositorios
sudo apt update
sudo apt install openjdk-21-jdk

# Comprobar la instalación
java -version
javac -version

En Fedora o derivadas de Red Hat:

sudo dnf install java-21-openjdk-devel
java -version

macOS

Con Homebrew:

brew install --cask temurin@21

# Comprobar
java -version

# Ver todos los JDK instalados en el sistema
/usr/libexec/java_home -V

Windows

Descarga el instalador .msi de Eclipse Temurin 21 desde adoptium.net y, durante la instalación, marca la opción "Set JAVA_HOME variable". Después, en PowerShell:

java -version
javac -version
echo $env:JAVA_HOME

Interpretar la salida

Una instalación correcta produce algo así:

$ java -version
openjdk version "21.0.5" 2024-10-15 LTS
OpenJDK Runtime Environment Temurin-21.0.5+11 (build 21.0.5+11-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.5+11 (build 21.0.5+11-LTS, mixed mode)

Fíjate en tres cosas:

  • 21.0.5: la versión mayor es 21. Es lo único crítico.
  • 64-Bit Server VM: es una JVM de 64 bits, la que quieres.
  • javac -version debe existir y coincidir. Si java responde pero javac da "comando no encontrado", has instalado un JRE o falta el paquete -devel/-jdk.

La variable JAVA_HOME

Maven y muchos IDEs localizan el JDK a través de JAVA_HOME. Comprobarla:

# Linux / macOS
echo $JAVA_HOME
# Debería imprimir algo como /usr/lib/jvm/java-21-openjdk-amd64

# Si está vacía, fíjala en tu ~/.bashrc o ~/.zshrc
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
export PATH="$JAVA_HOME/bin:$PATH"

  1. Gestionar varias versiones de Java con SDKMAN!

Es habitual mantener proyectos con Java 8, 17 y 21 a la vez. SDKMAN! permite cambiar de versión con un comando, sin tocar variables del sistema. Funciona en Linux y macOS (en Windows, a través de WSL o Git Bash).

# Instalar SDKMAN!
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"

# Ver las versiones de Java disponibles
sdk list java

# Instalar Temurin 21
sdk install java 21.0.5-tem

# Usar esa versión solo en la terminal actual
sdk use java 21.0.5-tem

# Fijarla como predeterminada del sistema
sdk default java 21.0.5-tem

# Comprobar cuál está activa
sdk current java

Un detalle muy útil: SDKMAN! reconoce un fichero .sdkmanrc en la raíz del proyecto.

# .sdkmanrc en la raíz de ciclourbana
java=21.0.5-tem
maven=3.9.9

Con sdk env dentro de esa carpeta, la terminal cambia automáticamente a las versiones declaradas. Es la forma más limpia de garantizar que todo el equipo compila con lo mismo.

SDKMAN! también instala Maven, Gradle y otras herramientas:

sdk install maven
sdk list maven

  1. Maven frente a Gradle, y por qué este curso usa Maven

Ambas son herramientas de construcción: descargan dependencias, compilan, ejecutan pruebas y empaquetan. Spring Boot soporta las dos con la misma calidad.

Criterio Maven Gradle
Fichero de construcción pom.xml (XML declarativo) build.gradle / build.gradle.kts (Groovy o Kotlin)
Curva de aprendizaje Baja: estructura rígida y predecible Media-alta: es un lenguaje de programación
Verbosidad Alta Baja
Velocidad de compilación Buena Mejor: caché de tareas y compilación incremental
Flexibilidad Limitada, por convención Muy alta, scripts arbitrarios
Documentación y ejemplos Mayoritaria en el mundo Spring Abundante, pero menos frecuente en tutoriales
Uso típico Aplicaciones empresariales Android, proyectos grandes o multi-módulo

Este curso usa Maven por tres razones prácticas:

  1. El pom.xml es declarativo y explícito: se lee de arriba abajo y no esconde lógica. Al aprender, eso importa más que la velocidad.
  2. La inmensa mayoría de la documentación de Spring y de las respuestas que encontrarás usan Maven.
  3. Es la opción por defecto de Spring Initializr, la herramienta con la que crearás el proyecto en la lección 01-03.

Si tu empresa usa Gradle, todo lo que aprendas aquí se traslada casi literalmente: cambian la sintaxis del fichero de construcción y los nombres de las tareas, no los conceptos.

Comprobar Maven

mvn -version

Salida esperada:

Apache Maven 3.9.9
Maven home: /home/usuario/.sdkman/candidates/maven/current
Java version: 21.0.5, vendor: Eclipse Adoptium

Observa la última línea: Maven reporta qué JDK está usando. Si dice Java version: 17, Maven no está viendo tu JDK 21 aunque java -version sí lo diga; revisa JAVA_HOME.

  1. El wrapper de Maven (mvnw)

Aquí viene una buena noticia: no necesitas instalar Maven para seguir este curso.

Spring Initializr genera en el proyecto un wrapper: dos scripts (mvnw para Linux/macOS y mvnw.cmd para Windows) y una carpeta .mvn/wrapper con la configuración. La primera vez que lo ejecutas, el wrapper descarga la versión exacta de Maven que el proyecto declara y la usa.

# En lugar de: mvn clean package
./mvnw clean package

# En Windows (PowerShell o CMD)
mvnw.cmd clean package

Ventajas, y son importantes:

  • Reproducibilidad: todo el equipo y el servidor de integración continua usan la misma versión de Maven, sin coordinarse.
  • Cero instalación: alguien clona el repositorio y construye sin instalar nada más que el JDK.
  • Versionado: la versión de Maven se actualiza cambiando un fichero y se revisa como cualquier otro cambio de código.

La versión concreta vive aquí:

# .mvn/wrapper/maven-wrapper.properties
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip

En este curso siempre usaremos ./mvnw. Si tienes Maven instalado, mvn funcionará igual, pero acostúmbrate al wrapper: es la convención profesional.

Un detalle habitual en Linux/macOS: si al clonar un repositorio ./mvnw da "permiso denegado", falta el bit de ejecución.

chmod +x mvnw

  1. Elegir un IDE: IntelliJ IDEA, Eclipse/STS y VS Code

Puedes seguir el curso con cualquiera de los tres. Esto es lo que aporta cada uno:

IDE Edición gratuita Puntos fuertes Inconvenientes
IntelliJ IDEA Community (suficiente para el curso) Mejor autocompletado y refactorización de Java del mercado; excelente depurador El soporte específico de Spring (navegación de beans, autocompletado de application.properties) solo está en Ultimate
Eclipse / Spring Tool Suite (STS) Sí, todo gratuito STS es Eclipse con herramientas Spring ya incluidas: panel de beans, arranque de aplicaciones Boot, edición asistida de propiedades Interfaz menos pulida; consume bastante memoria
VS Code + Extension Pack for Java Sí Ligero, arranca rápido, mismo editor para frontend y backend; extensión "Spring Boot Extension Pack" muy completa Menos potente en refactorizaciones grandes

Qué instalar en cada caso

IntelliJ IDEA Community: descárgalo de jetbrains.com o instálalo con la Toolbox App. Reconoce proyectos Maven automáticamente al abrir la carpeta que contiene el pom.xml.

Spring Tool Suite: descarga STS 4 desde spring.io/tools. Se distribuye como un JAR autoejecutable que despliega el IDE. Para importar el proyecto: File → Import → Existing Maven Projects.

VS Code: instala estas dos extensiones desde el Marketplace.

# Desde la línea de comandos, si tienes el comando "code" disponible
code --install-extension vscjava.vscode-java-pack
code --install-extension vmware.vscode-boot-dev-pack
  • Extension Pack for Java: compilador, depurador, soporte Maven, ejecutor de pruebas.
  • Spring Boot Extension Pack: autocompletado en application.properties, panel de Spring Boot Dashboard para arrancar y parar aplicaciones, navegación entre endpoints.

Configuración recomendada, sea cual sea el IDE

  1. Comprueba que el IDE usa el JDK 21, no uno interno más antiguo. En IntelliJ: File → Project Structure → SDK. En VS Code: la variable java.configuration.runtimes.
  2. Activa la construcción automática y el formateo al guardar.
  3. Configura la codificación en UTF-8 para todo el proyecto. Los nombres de las estaciones de Ribalta llevan tildes, y una codificación mal fijada produce "Parque del Río".

  1. Herramientas para probar la API

Vas a construir una API REST, así que necesitas algo con lo que llamarla. Conviene conocer varias opciones:

curl

Está en prácticamente cualquier sistema y es el lenguaje común de la documentación.

# Petición GET simple
curl http://localhost:8080/api/v1/estaciones

# Ver también las cabeceras de respuesta y el código de estado
curl -i http://localhost:8080/api/v1/estaciones

# Petición POST con cuerpo JSON
curl -X POST http://localhost:8080/api/v1/estaciones \
  -H "Content-Type: application/json" \
  -d '{"nombre":"Plaza Mayor","capacidad":24}'

Las opciones que más usarás: -i (incluir cabeceras), -X (método HTTP), -H (cabecera), -d (cuerpo), -s (silencioso).

HTTPie

Sintaxis más legible y coloreado del JSON de salida. Muy cómodo para explorar.

# Instalación
sudo apt install httpie        # Debian/Ubuntu
brew install httpie            # macOS

# GET
http :8080/api/v1/estaciones

# POST: los pares clave=valor se convierten en JSON automáticamente
http POST :8080/api/v1/estaciones nombre="Plaza Mayor" capacidad:=24

Detalle importante: nombre="Plaza Mayor" genera una cadena, mientras que capacidad:=24 (con :=) genera un número. Es un error frecuente enviar "24" cuando la API espera un entero.

Postman

Aplicación gráfica. Su valor está en organizar colecciones de peticiones guardadas, usar variables de entorno ({{baseUrl}}), gestionar tokens de autenticación y compartir todo con el equipo. Muy útil a partir del módulo 5, cuando aparezcan los tokens JWT.

Ficheros .http

Es mi recomendación para este curso. Son ficheros de texto plano, versionables en Git, que IntelliJ (nativo) y VS Code (extensión REST Client) ejecutan directamente desde el editor.

### Listar todas las estaciones de Ribalta
GET http://localhost:8080/api/v1/estaciones
Accept: application/json

### Consultar una estación concreta
GET http://localhost:8080/api/v1/estaciones/1
Accept: application/json

### Dar de alta una estación nueva
POST http://localhost:8080/api/v1/estaciones
Content-Type: application/json

{
  "nombre": "Parque del Río",
  "direccion": "Paseo Fluvial 12",
  "capacidad": 18
}

Cada bloque separado por ### es una petición independiente con su propio botón de ejecución. Crea el fichero api-ciclourbana.http en la raíz del proyecto y ve añadiendo ahí cada endpoint que construyas: acabarás con documentación viva y ejecutable de toda la API.

  1. Docker: requisito para los módulos posteriores

En los módulos 1 a 3 no necesitas Docker. A partir del módulo 4 sí conviene tenerlo, y es imprescindible en los módulos 6, 7 y 8:

  • Módulo 4: levantar un PostgreSQL real sin instalarlo en tu máquina.
  • Módulo 6: Testcontainers arranca bases de datos efímeras para las pruebas de integración.
  • Módulos 7 y 8: empaquetar CicloUrbana como imagen y desplegarla.

Instalación

  • Linux: instala Docker Engine siguiendo la guía oficial de tu distribución y añade tu usuario al grupo docker para no necesitar sudo.
  • macOS y Windows: instala Docker Desktop. En Windows, activa la integración con WSL 2, que es donde funcionará mejor.
# En Linux, tras instalar
sudo usermod -aG docker $USER
# Cierra sesión y vuelve a entrar para que el cambio surta efecto

Verificación

docker --version
docker compose version

# Prueba real: descarga y ejecuta una imagen mínima
docker run --rm hello-world

Un ensayo de lo que harás en el módulo 4, solo para comprobar que todo funciona:

# Arrancar un PostgreSQL temporal para CicloUrbana
docker run --name ciclourbana-db \
  -e POSTGRES_DB=ciclourbana \
  -e POSTGRES_USER=ciclo \
  -e POSTGRES_PASSWORD=secreto \
  -p 5432:5432 \
  -d postgres:16

# Comprobar que está en marcha
docker ps

# Detenerlo y eliminarlo cuando termines
docker stop ciclourbana-db && docker rm ciclourbana-db

  1. Checklist final de verificación

Guarda este script como verificar-entorno.sh y ejecútalo. Si todas las líneas responden, tu entorno está listo.

#!/usr/bin/env bash
echo "=== Verificación del entorno para CicloUrbana ==="

echo "--- 1. JDK (se espera 21) ---"
java -version 2>&1 | head -1
javac -version 2>&1

echo "--- 2. JAVA_HOME ---"
echo "JAVA_HOME=${JAVA_HOME:-NO DEFINIDA}"

echo "--- 3. Maven (opcional: usaremos ./mvnw) ---"
mvn -version 2>/dev/null | head -1 || echo "Maven no instalado (correcto si usas el wrapper)"

echo "--- 4. Herramientas HTTP ---"
curl --version 2>/dev/null | head -1 || echo "curl NO disponible"
http --version 2>/dev/null || echo "HTTPie no instalado (opcional)"

echo "--- 5. Docker (necesario desde el módulo 4) ---"
docker --version 2>/dev/null || echo "Docker no instalado (aún no es obligatorio)"

echo "--- 6. Git ---"
git --version 2>/dev/null || echo "Git NO disponible"

echo "=== Fin de la verificación ==="

Ejecución:

chmod +x verificar-entorno.sh
./verificar-entorno.sh

Tabla de lo que debe cumplirse antes de pasar a la lección 01-03:

Requisito Cómo se comprueba ¿Obligatorio ya?
JDK 21 instalado java -version muestra 21.x Sí
Compilador disponible javac -version muestra 21.x Sí
JAVA_HOME apuntando al JDK 21 echo $JAVA_HOME Sí
IDE instalado y usando el JDK 21 Configuración del proyecto Sí
Cliente HTTP curl --version Sí
Conexión a internet Maven descargará dependencias Sí
Git git --version Recomendado
Docker docker run --rm hello-world Desde el módulo 4

Errores Comunes y Consejos

  • Tener instalado un JRE en lugar de un JDK. El síntoma es claro: java funciona pero javac no existe, y Maven falla con "No compiler is provided in this environment". Instala el paquete con sufijo -jdk o -devel.
  • JAVA_HOME apuntando a otra versión. java -version dice 21 pero Maven compila con 17. Fíate siempre de la línea Java version: que imprime mvn -version, porque es la que realmente usa la construcción.
  • Usar mvn en lugar de ./mvnw. Funciona, pero introduce una variable no controlada: la versión de Maven de tu máquina. En equipo, esto acaba en un "a mí me compila".
  • Olvidar chmod +x mvnw tras clonar. Error muy frecuente en Linux y macOS.
  • La primera construcción tarda muchísimo. Es normal: Maven descarga cientos de artefactos a ~/.m2/repository. Las siguientes usan esa caché local y son rápidas. No canceles el proceso a medias, porque puedes dejar ficheros corruptos en la caché.
  • Consejo — trabajar sin conexión. Si la caché queda inconsistente, borra la carpeta problemática dentro de ~/.m2/repository y vuelve a construir. Borrar todo ~/.m2 funciona, pero obliga a descargarlo todo otra vez.
  • Consejo — codificación UTF-8. Fíjala en el IDE y en el sistema. Ribalta tiene estaciones como "Parque del Río" y verás las tildes rotas al primer descuido.

Ejercicios

Ejercicio 1

Prepara tu máquina y documenta el resultado: instala el JDK 21, comprueba java -version, javac -version y JAVA_HOME, e indica qué distribución has elegido y por qué.

Ejercicio 2

Tu equipo mantiene un sistema antiguo con Java 17 y quiere empezar CicloUrbana con Java 21 en el mismo portátil. Explica cómo lo resolverías con SDKMAN! y escribe los comandos concretos, incluyendo cómo dejar fijada la versión por proyecto sin cambiar la del sistema.

Ejercicio 3

Crea un fichero api-ciclourbana.http con tres peticiones a endpoints que aún no existen: listar estaciones, obtener la estación con id 1 y crear la estación "Estación Norte" con capacidad 30. Escribe además el comando curl equivalente a la tercera.

Soluciones

Solución 1

En una máquina Ubuntu:

sudo apt update
sudo apt install openjdk-21-jdk

java -version
# openjdk version "21.0.5" 2024-10-15 LTS

javac -version
# javac 21.0.5

echo $JAVA_HOME
# (vacío) → hay que definirlo

# Averiguar la ruta real del JDK
readlink -f $(which javac)
# /usr/lib/jvm/java-21-openjdk-amd64/bin/javac

# Añadir al ~/.bashrc
echo 'export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64' >> ~/.bashrc
echo 'export PATH="$JAVA_HOME/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

echo $JAVA_HOME
# /usr/lib/jvm/java-21-openjdk-amd64

Elección justificada: el OpenJDK de los repositorios es cómodo en Linux porque se actualiza con el sistema. Si necesitas una versión concreta y reproducible entre máquinas, es preferible Temurin vía SDKMAN!.

Solución 2

# 1. Instalar SDKMAN! si no lo tienes
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"

# 2. Instalar las dos versiones que necesita el equipo
sdk install java 17.0.13-tem
sdk install java 21.0.5-tem

# 3. Mantener 17 como versión por defecto del sistema (el proyecto antiguo)
sdk default java 17.0.13-tem

Para que CicloUrbana use 21 sin cambiar la versión global, se declara en la raíz del proyecto:

# ciclourbana/.sdkmanrc
java=21.0.5-tem
maven=3.9.9

Y en cada sesión de terminal dentro del proyecto:

cd ciclourbana
sdk env          # activa las versiones del .sdkmanrc
java -version    # 21.0.5
cd ..
java -version    # vuelve a 17.0.13 (la global)

El fichero .sdkmanrc se versiona en Git, así que cualquier miembro del equipo obtiene la misma configuración al clonar. Con sdk env install se instalan de golpe las versiones que falten.

Solución 3

### 1. Listar todas las estaciones de la red de Ribalta
GET http://localhost:8080/api/v1/estaciones
Accept: application/json

### 2. Detalle de la estación con id 1
GET http://localhost:8080/api/v1/estaciones/1
Accept: application/json

### 3. Alta de la estación "Estación Norte"
POST http://localhost:8080/api/v1/estaciones
Content-Type: application/json
Accept: application/json

{
  "nombre": "Estación Norte",
  "direccion": "Avenida de la Estación 3",
  "capacidad": 30
}

El equivalente en curl de la tercera petición:

curl -i -X POST http://localhost:8080/api/v1/estaciones \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
        "nombre": "Estación Norte",
        "direccion": "Avenida de la Estación 3",
        "capacidad": 30
      }'

Nota sobre las cabeceras: Content-Type describe lo que envías; Accept declara lo que quieres recibir. Confundirlas es una fuente clásica de respuestas 415 y 406, que veremos en el módulo 3.

Conclusión

Ya tienes el entorno preparado y, más importante, verificado: JDK 21 con JAVA_HOME correcto, un IDE que apunta a ese JDK, un cliente HTTP para probar la API y Docker listo para cuando lo necesites. Has visto también por qué el curso usa Maven y por qué siempre invocaremos ./mvnw en lugar de mvn: reproducibilidad para ti y para todo el equipo.

En la siguiente lección, Creando tu Primera Aplicación Spring Boot, generarás el proyecto ciclourbana con Spring Initializr, escribirás tu primer endpoint GET /api/v1/estaciones con las estaciones de Ribalta, lo ejecutarás con ./mvnw spring-boot:run y lo empaquetarás en un JAR ejecutable.

Curso de Spring Boot

Módulo 1: Introducción a Spring Boot

Módulo 2: Conceptos Básicos de Spring Boot

Módulo 3: Construyendo Servicios Web RESTful

Módulo 4: Acceso a Datos con Spring Boot

Módulo 5: Seguridad en Spring Boot

Módulo 6: Pruebas en Spring Boot

Módulo 7: Funciones Avanzadas de Spring Boot

Módulo 8: Despliegue de Aplicaciones Spring Boot

Módulo 9: Rendimiento y Monitoreo

Módulo 10: Mejores Prácticas y Consejos

© Copyright 2026. Todos los derechos reservados