Objetivo del tema
Aplicaras Gradle en proyectos reales: desde un proyecto Java con pruebas hasta un multi-modulo con Spring Boot, una app Android y un flujo de publicacion en Maven Central.
Al finalizar, tendras plantillas para iniciar proyectos end-to-end y adaptar builds a requisitos empresariales.
Un proyecto Java clasico incluye dependencias, pruebas unitarias y scripts para ejecutar la aplicacion.
plugins {
id 'application'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'com.google.guava:guava:33.0.0-jre'
implementation 'org.apache.commons:commons-lang3:3.14.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.10.2'
}
application {
mainClass = 'com.ejemplo.App'
}
tasks.withType(Test).configureEach {
useJUnitPlatform()
}
Incluye el bloque repositories { mavenCentral() }
para que Gradle resuelva las dependencias. Agrega testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.10.2'
para disponer del launcher en tiempo de ejecucion de pruebas. Ejecuta gradle run
y gradle test
para validar funcionalidad y cobertura basica.
La estructura de directorios sugerida es:
src/
main/
java/
com/
ejemplo/
App.java
test/
java/
com/
ejemplo/
AppTest.java
App.java
contiene el punto de entrada de la aplicacion:
package com.ejemplo;
import com.google.common.base.Joiner;
public class App {
public static void main(String[] args) {
String mensaje = Joiner.on(" ").join("Hola", "Gradle", "desde", "un", "proyecto", "Java");
System.out.println(mensaje);
}
}
La clase de prueba AppTest.java
verifica el comportamiento usando JUnit 5:
package com.ejemplo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
class AppTest {
@Test
void mensajePrincipal() {
String[] argumentos = {};
App.main(argumentos); // no lanza excepciones
assertEquals(1, 1, "Prueba basica de sanidad");
}
}
Ajusta los paquetes y los contenidos segun la logica de tu aplicacion.
Un entorno corporativo puede incluir modulos independientes que comparten logica. Usa settings.gradle
para registrar modulos y un build raiz que defina convenciones.
// settings.gradle
rootProject.name = 'plataforma-servicios'
include 'api-rest'
// build.gradle (raiz)
plugins {
id 'io.spring.dependency-management' version '1.1.6'
}
subprojects {
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
bootJar { enabled = false }
jar { enabled = true }
repositories { mavenCentral() }
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
}
tasks.register('bootAll') {
dependsOn subprojects.collect { it.tasks.named('bootJar') }
}
Para cada modulo crea el arbol de directorios dentro de api-rest
, servicio-autenticacion
y cliente-web
. Por ejemplo, el modulo api-rest
puede comenzar con:
api-rest/
src/
main/
java/
com/
ejemplo/
api/
ApiRestApplication.java
resources/
application.yml
Contenido basico de ApiRestApplication.java
:
package com.ejemplo.api;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class ApiRestApplication {
public static void main(String[] args) {
SpringApplication.run(ApiRestApplication.class, args);
}
@RestController
static class HelloController {
@GetMapping("/saludo")
String saludo() {
return "Hola desde api-rest";
}
}
}
Para pruebas en api-rest
, crea src/test/java/com/ejemplo/api/ApiRestApplicationTests.java
:
package com.ejemplo.api;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ApiRestApplicationTests {
@Test
void contextLoads() {
}
}
Repite la estructura para servicio-autenticacion
y cliente-web
, ajustando paquetes y controladores. Por ejemplo, en servicio-autenticacion
:
servicio-autenticacion/
src/
main/
java/
com/
ejemplo/
auth/
ServicioAutenticacionApplication.java
AuthController.java
resources/
application.yml
Contenido basico para autenticacion:
package com.ejemplo.auth;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class ServicioAutenticacionApplication {
public static void main(String[] args) {
SpringApplication.run(ServicioAutenticacionApplication.class, args);
}
}
@RestController
class AuthController {
@PostMapping("/login")
AuthResponse login(@RequestBody AuthRequest request) {
return new AuthResponse(request.username(), true);
}
record AuthRequest(String username, String password) {}
record AuthResponse(String username, boolean authenticated) {}
}
El modulo cliente-web
puede exponer una interfaz sencilla:
cliente-web/
src/
main/
java/
com/
ejemplo/
web/
ClienteWebApplication.java
ProxyController.java
resources/
application.yml
Ejemplo de controlador en cliente web:
package com.ejemplo.web;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class ClienteWebApplication {
public static void main(String[] args) {
SpringApplication.run(ClienteWebApplication.class, args);
}
}
@RestController
class ProxyController {
@GetMapping("/ping")
String ping() {
return "Cliente web operativo";
}
}
Finalmente, ejecuta gradle :api-rest:bootRun
para iniciar el microservicio de ejemplo y gradle bootAll
para construir todos los modulos.
Android Studio genera un build basado en Gradle. Ajusta variantes, flavors y tareas de empaquetado segun tus necesidades.
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'com.ejemplo.app'
compileSdk 35
defaultConfig {
applicationId 'com.ejemplo.app'
minSdk 24
targetSdk 35
versionCode 5
versionName '1.2.0'
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
// Generar APK debug: gradle assembleDebug
Agrega tareas personalizadas (por ejemplo uploadArtifacts
) para automatizar la distribucion via Play Store o herramientas internas.
// build.gradle (modulo Android)
tasks.register('uploadArtifacts') {
group = 'distribucion'
description = 'Sube el APK generado a un repositorio interno'
mustRunAfter 'assembleRelease'
doLast {
def apk = file('build/outputs/apk/release/app-release.apk')
if (!apk.exists()) {
throw new GradleException('El APK release no existe. Ejecuta gradle assembleRelease primero.')
}
println "Subiendo ${apk.name} al repositorio interno..."
// Integrar aqui la API de subida a Play Store o repositorio interno
}
}
// Ejecutar: gradle assembleRelease uploadArtifacts
Combina los conceptos de versionado, firma y publicacion para distribuir bibliotecas.
plugins {
id 'java-library'
id 'maven-publish'
id 'signing'
}
version = '1.0.0'
publishing {
publications {
create('mavenJava', MavenPublication) {
from components.java
artifact tasks.named('javadocJar')
artifact tasks.named('sourcesJar')
}
}
repositories {
maven {
url = uri('https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/')
credentials {
username = findProperty('sonatypeUser')
password = findProperty('sonatypePassword')
}
}
}
}
signing {
sign publishing.publications['mavenJava']
}
Genera Javadoc y sources con tareas javadocJar
y sourcesJar
. Ejecuta gradle publish
para subir artefactos.
Los ejemplos practicos muestran como Gradle se adapta a diferentes escenarios: aplicaciones Java, plataformas multi-modulo, apps Android y librerias publicadas en Maven Central. Reutiliza estas plantillas para iniciar builds robustos en minutos.