google-site-verification: google61fe8ba583a51912.html
Gradle Build Scripts in Java: Complete Guide

Gradle is a powerful build automation tool that uses a Groovy or Kotlin DSL. This guide covers comprehensive Gradle build scripts for Java projects.

1. Basic Java Project Setup

Basic build.gradle

plugins { id 'java' id 'application' } group = 'com.example' version = '1.0.0' description = 'A simple Java application' java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } repositories { mavenCentral() google() maven { url 'https://jitpack.io' } } dependencies { // Production dependencies implementation 'com.google.guava:guava:31.1-jre' implementation 'org.apache.commons:commons-lang3:3.12.0' // Test dependencies testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' testImplementation 'org.mockito:mockito-core:5.3.1' testImplementation 'org.assertj:assertj-core:3.24.2' // Runtime dependencies runtimeOnly 'ch.qos.logback:logback-classic:1.4.6' } application { mainClass = 'com.example.Main' } test { useJUnitPlatform() testLogging { events "passed", "skipped", "failed" exceptionFormat "full" } } tasks.withType(JavaCompile) { options.encoding = 'UTF-8' options.compilerArgs += ['-Xlint:unchecked', '-Xlint:deprecation'] } jar { manifest { attributes( 'Main-Class': 'com.example.Main', 'Implementation-Title': project.name, 'Implementation-Version': project.version, 'Built-By': System.getProperty('user.name'), 'Built-Date': new Date(), 'Built-JDK': System.getProperty('java.version') ) } }

settings.gradle for Basic Project

rootProject.name = 'my-java-app' // Include subprojects if any // include 'subproject1', 'subproject2'

2. Multi-Project Build

Root settings.gradle

rootProject.name = 'enterprise-app' include 'core' include 'web-api' include 'batch-processor' include 'shared-lib' include 'integration-tests' // Custom project paths project(':core').projectDir = file('modules/core') project(':web-api').projectDir = file('modules/web-api') project(':batch-processor').projectDir = file('modules/batch') project(':shared-lib').projectDir = file('libs/shared') project(':integration-tests').projectDir = file('testing/integration')

Root build.gradle

plugins { id 'java' id 'idea' id 'eclipse' } allprojects { group = 'com.enterprise' version = '2.0.0' repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } } } subprojects { apply plugin: 'java' apply plugin: 'jacoco' java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 toolchain { languageVersion = JavaLanguageVersion.of(17) } } dependencies { implementation 'org.slf4j:slf4j-api:2.0.7' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' testImplementation 'org.mockito:mockito-core:5.3.1' } test { useJUnitPlatform() maxHeapSize = '1G' testLogging { events "passed", "skipped", "failed" } } jacoco { toolVersion = "0.8.8" } jacocoTestReport { dependsOn test reports { xml.required = true html.required = true csv.required = false } } } // Project-specific configurations project(':core') { dependencies { implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2' } } project(':web-api') { apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' dependencies { implementation project(':core') implementation project(':shared-lib') implementation 'org.springframework.boot:spring-boot-starter-web:3.0.6' implementation 'org.springframework.boot:spring-boot-starter-data-jpa:3.0.6' } } project(':batch-processor') { dependencies { implementation project(':core') implementation 'org.springframework.boot:spring-boot-starter-batch:3.0.6' } } project(':shared-lib') { // Shared library configuration } project(':integration-tests') { dependencies { implementation project(':web-api') implementation project(':batch-processor') testImplementation 'io.rest-assured:rest-assured:5.3.0' } }

3. Spring Boot Application

Spring Boot build.gradle

plugins { id 'java' id 'org.springframework.boot' version '3.1.0' id 'io.spring.dependency-management' version '1.1.0' id 'com.github.ben-manes.versions' version '0.46.0' } group = 'com.example' version = '2.1.0' sourceCompatibility = '17' configurations { compileOnly { extendsFrom annotationProcessor } developmentOnly runtimeClasspath { extendsFrom developmentOnly } } repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } } ext { set('springCloudVersion', "2022.0.3") set('testcontainersVersion', "1.18.0") } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" mavenBom "org.testcontainers:testcontainers-bom:${testcontainersVersion}" } } dependencies { // Spring Boot Starters implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-cache' // Database implementation 'org.postgresql:postgresql:42.6.0' implementation 'com.h2database:h2' implementation 'org.flywaydb:flyway-core' // Cache implementation 'com.github.ben-manes.caffeine:caffeine:3.1.6' // API Documentation implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' // Security implementation 'io.jsonwebtoken:jjwt-api:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' // Utilities implementation 'com.google.guava:guava:31.1-jre' implementation 'org.apache.commons:commons-lang3:3.12.0' implementation 'org.modelmapper:modelmapper:3.1.1' // Development compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' annotationProcessor 'org.projectlombok:lombok' // Testing testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.testcontainers:junit-jupiter' testImplementation 'org.testcontainers:postgresql' testImplementation 'com.tngtech.archunit:archunit-junit5:1.0.1' } bootRun { systemProperties = System.properties jvmArgs = [ '-Xmx512m', '-Dspring.profiles.active=dev', '-Djava.security.egd=file:/dev/./urandom' ] } bootJar { archiveFileName = "${project.name}-${project.version}.jar" launchScript() manifest { attributes( 'Implementation-Title': project.name, 'Implementation-Version': project.version, 'Built-By': System.getProperty('user.name'), 'Build-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), 'Created-By': "Gradle ${gradle.gradleVersion}", 'Build-Jdk': System.getProperty('java.version') ) } } test { useJUnitPlatform() systemProperty 'spring.profiles.active', 'test' testLogging { events "passed", "skipped", "failed" exceptionFormat "full" showStandardStreams = true } reports { html.required = true junitXml.required = true } maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 } tasks.named('dependencyUpdates').configure { checkForGradleUpdate = true outputDir = "build/dependencyUpdates" reportfileName = "report" rejectVersionIf { isNonStable(candidate.version) && !isNonStable(currentVersion) } } static boolean isNonStable(String version) { return ['alpha', 'beta', 'rc', 'cr', 'm', 'preview', 'b', 'ea'].any { version.toLowerCase().contains(it) } } // Custom task for code quality task codeQualityCheck { group = 'verification' description = 'Runs all code quality checks' dependsOn test, jacocoTestReport } // Generate build info task generateBuildInfo { doLast { def buildInfoFile = new File("$buildDir/resources/main/build-info.properties") buildInfoFile.parentFile.mkdirs() buildInfoFile.text = """ build.version=${project.version} build.timestamp=${new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")} build.java.version=${System.getProperty('java.version')} build.os.name=${System.getProperty('os.name')} """.stripIndent().trim() } } processResources.dependsOn generateBuildInfo

4. Advanced Configuration with Custom Tasks

Advanced build.gradle with Custom Tasks

plugins { id 'java' id 'jacoco' id 'checkstyle' id 'pmd' id 'com.github.spotbugs' version '5.0.14' id 'org.sonarqube' version '4.0.0.2929' id 'com.bmuschko.docker-java-application' version '9.3.1' } group = 'com.enterprise' version = '3.0.0' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } repositories { mavenCentral() maven { url 'https://plugins.gradle.org/m2/' } } configurations { codeQuality asciidoclet } dependencies { implementation 'io.vavr:vavr:0.10.4' implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' testImplementation 'org.assertj:assertj-core:3.24.2' testImplementation 'org.mockito:mockito-core:5.3.1' testImplementation 'org.testcontainers:testcontainers:1.18.0' codeQuality 'com.puppycrawl.tools:checkstyle:10.9.3' codeQuality 'net.sourceforge.pmd:pmd-java:6.55.0' codeQuality 'com.github.spotbugs:spotbugs:4.7.3' asciidoclet 'org.asciidoctor:asciidoclet:2.0.0' } // Checkstyle Configuration checkstyle { toolVersion = '10.9.3' config = resources.text.fromUri('https://checkstyle.org/sun_checks.xml') maxErrors = 0 maxWarnings = 10 } tasks.withType(Checkstyle) { reports { xml.required = false html.required = true } exclude '**/generated/**' } // PMD Configuration pmd { toolVersion = '6.55.0' ruleSetFiles = files("$projectDir/config/pmd/ruleset.xml") ruleSets = [] ignoreFailures = false } tasks.withType(Pmd) { reports { xml.required = false html.required = true } } // SpotBugs Configuration spotbugs { toolVersion = '4.7.3' effort = 'max' reportLevel = 'low' excludeFilter = file("$projectDir/config/spotbugs/exclude.xml") } tasks.withType(com.github.spotbugs.snom.SpotBugsTask) { reports { html.required = true xml.required = false } } // JaCoCo Configuration jacoco { toolVersion = "0.8.8" } jacocoTestReport { dependsOn test reports { xml.required = true html.required = true csv.required = false } executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec") afterEvaluate { classDirectories.setFrom(files(classDirectories.files.collect { fileTree(dir: it, exclude: [ '**/config/**', '**/entity/**', '**/dto/**', '**/*Application*' ]) })) } } jacocoTestCoverageVerification { violationRules { rule { limit { minimum = 0.8 } } rule { element = 'CLASS' excludes = [ '*.config.*', '*.entity.*', '*.dto.*', '*Application*' ] limit { counter = 'LINE' value = 'COVEREDRATIO' minimum = 0.7 } } } } // SonarQube Configuration sonarqube { properties { property "sonar.projectKey", "enterprise-java-app" property "sonar.projectName", "Enterprise Java Application" property "sonar.coverage.jacoco.xmlReportPaths", "${buildDir}/reports/jacoco/test/jacocoTestReport.xml" property "sonar.java.checkstyle.reportPaths", "${buildDir}/reports/checkstyle/main.xml" property "sonar.pmd.reportPaths", "${buildDir}/reports/pmd/main.html" property "sonar.spotbugs.reportPaths", "${buildDir}/reports/spotbugs/main.xml" } } // Docker Configuration docker { javaApplication { baseImage = 'eclipse-temurin:17-jre-alpine' maintainer = 'Dev Team <[email protected]>' ports = [8080, 8081] images = ["${project.group}/${project.name}:${project.version}"] jvmArgs = ['-Xmx512m', '-Dspring.profiles.active=prod'] } } // Custom Tasks task codeQuality(group: 'verification') { description = 'Runs all code quality tools' dependsOn checkstyleMain, checkstyleTest, pmdMain, pmdTest, spotbugsMain, spotbugsTest } task securityScan(group: 'verification') { description = 'Runs security scans' dependsOn dependencyCheckAnalyze } task qualityGate(group: 'verification') { description = 'Runs complete quality gate' dependsOn test, jacocoTestReport, jacocoTestCoverageVerification, codeQuality, securityScan } // Build lifecycle customization test.finalizedBy jacocoTestReport check.dependsOn jacocoTestCoverageVerification build.dependsOn qualityGate // Performance optimization tasks.withType(JavaCompile) { options.encoding = 'UTF-8' options.incremental = true options.fork = true options.forkOptions.memoryMaximumSize = '1g' } tasks.withType(Test) { maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 forkEvery = 100 maxHeapSize = '1G' } // Resource filtering processResources { filesMatching('**/application*.yml') { filter org.apache.tools.ant.filters.ReplaceTokens, tokens: [ 'app.version': project.version, 'app.name': project.name ] } } // Generate Javadoc with custom options javadoc { options { encoding = 'UTF-8' charSet = 'UTF-8' docEncoding = 'UTF-8' addBooleanOption('Xdoclint:all,-missing', true) addStringOption('Xmaxwarns', '1000') } options.addStringOption('taglet', 'org.asciidoctor.Asciidoclet') options.addStringOption('tagletpath', configurations.asciidoclet.files.asPath) exclude '**/internal/**' } // Custom task to generate dependency report task dependencyReport(type: DependencyReportTask) { outputFile = file("${buildDir}/reports/dependencies.txt") } // Task to update wrapper task updateWrapper(type: Wrapper) { gradleVersion = '8.2.1' distributionType = Wrapper.DistributionType.ALL }

5. Microservices Build Setup

Microservice build.gradle

plugins { id 'java' id 'org.springframework.boot' version '3.1.0' id 'io.spring.dependency-management' version '1.1.0' id 'com.google.cloud.tools.jib' version '3.3.1' } group = 'com.microservices' version = '1.0.0-' + (System.getenv('BUILD_NUMBER') ?: 'SNAPSHOT') java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } } ext { set('springCloudVersion', "2022.0.3") set('testcontainersVersion', "1.18.0") set('resilience4jVersion', "2.0.2") } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" mavenBom "org.testcontainers:testcontainers-bom:${testcontainersVersion}" } } dependencies { // Spring Boot implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-validation' // Spring Cloud implementation 'org.springframework.cloud:spring-cloud-starter-config' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' implementation 'org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j' implementation 'org.springframework.cloud:spring-cloud-starter-sleuth' implementation 'org.springframework.cloud:spring-cloud-sleuth-zipkin' // Resilience4j implementation "io.github.resilience4j:resilience4j-spring-boot2:${resilience4jVersion}" implementation "io.github.resilience4j:resilience4j-all:${resilience4jVersion}" // Database implementation 'org.postgresql:postgresql:42.6.0' implementation 'org.flywaydb:flyway-core' // API implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' implementation 'io.micrometer:micrometer-registry-prometheus' // Messaging implementation 'org.springframework.kafka:spring-kafka' // Caching implementation 'org.springframework.boot:spring-boot-starter-data-redis' // Security implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server' // Utilities compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' // Testing testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.kafka:spring-kafka-test' testImplementation 'org.testcontainers:junit-jupiter' testImplementation 'org.testcontainers:postgresql' testImplementation 'org.testcontainers:kafka' } // Jib Configuration for Docker image building jib { from { image = 'eclipse-temurin:17-jre-alpine' platforms { platform { architecture = 'amd64' os = 'linux' } platform { architecture = 'arm64' os = 'linux' } } } to { image = "registry.example.com/microservices/${project.name}" tags = ['latest', project.version] auth { username = System.getenv('DOCKER_USERNAME') password = System.getenv('DOCKER_PASSWORD') } } container { jvmFlags = [ '-Xms256m', '-Xmx512m', '-Dspring.profiles.active=prod', '-Djava.security.egd=file:/dev/./urandom' ] ports = ['8080'] environment = [ 'SPRING_PROFILES_ACTIVE': 'prod', 'JAVA_OPTS': '-Xmx512m' ] labels = [ 'maintainer': 'Microservices Team', 'version': project.version, 'description': project.description ] creationTime = 'USE_CURRENT_TIMESTAMP' } } // Spring Boot specific configurations bootRun { systemProperties = System.properties jvmArgs = [ '-Dspring.profiles.active=dev', '-Dspring.cloud.config.uri=http://localhost:8888' ] } bootBuildImage { imageName = "microservices/${project.name}:${project.version}" environment = [ "BPE_DELIM_JAVA_TOOL_OPTIONS" : " ", "BPE_APPEND_JAVA_TOOL_OPTIONS" : "-Xmx512m -Dspring.profiles.active=prod" ] } // Test configuration for microservices test { useJUnitPlatform() systemProperty 'spring.profiles.active', 'test' filter { includeTestsMatching '*Test' excludeTestsMatching '*IT' } } task integrationTest(type: Test) { useJUnitPlatform() systemProperty 'spring.profiles.active', 'integration-test' filter { includeTestsMatching '*IT' } shouldRunAfter test } task smokeTest(type: Test) { useJUnitPlatform() systemProperty 'spring.profiles.active', 'smoke-test' filter { includeTestsMatching '*ST' } shouldRunAfter integrationTest } // Task dependencies check.dependsOn integrationTest build.dependsOn smokeTest // Generate OpenAPI spec task generateOpenApiSpec { doLast { javaexec { main = 'org.springframework.boot.loader.JarLauncher' classpath = bootJar.outputs.files systemProperties = [ 'spring.profiles.active': 'docs', 'spring.main.web-application-type': 'none' ] } } } // Custom task for database migration task dbMigrate { doLast { javaexec { main = 'org.flywaydb.commandline.Main' classpath = configurations.runtimeClasspath args = [ '-url=jdbc:postgresql://localhost:5432/mydb', '-user=admin', '-password=secret', 'migrate' ] } } }

6. gradle.properties Configuration

Common gradle.properties

# Project Properties org.gradle.project.name=my-java-app org.gradle.project.description=A modern Java application org.gradle.project.url=https://github.com/example/my-java-app org.gradle.project.inceptionYear=2023 # Build Performance org.gradle.parallel=true org.gradle.caching=true org.gradle.configureondemand=true org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # Daemon Configuration org.gradle.daemon=true org.gradle.daemon.idletimeout=10800000 # Logging org.gradle.console=plain org.gradle.logging.level=info # Dependency Resolution org.gradle.resolution.parallel=true org.gradle.resolution.runtime.mode=auto # Testing org.gradle.test.worker.max=4 # Publishing org.gradle.publish.overwrite=false # Plugin Versions (for settings.gradle) springBootVersion=3.1.0 springDependencyManagementVersion=1.1.0 jacocoVersion=0.8.8 sonarqubeVersion=4.0.0.2929 jibVersion=3.3.1

Key Gradle Concepts for Java

  1. Plugins: Extend build functionality (java, spring-boot, etc.)
  2. Dependencies: implementation, testImplementation, runtimeOnly
  3. Tasks: Custom build operations
  4. Configurations: Dependency scopes and custom configurations
  5. Properties: Project properties and system properties
  6. Multi-project: Complex project structures with dependencies
  7. Performance: Caching, parallel execution, incremental builds
  8. Quality: Integration with code quality tools
  9. Containerization: Docker image building with Jib
  10. CI/CD: Integration with Jenkins, GitHub Actions, etc.

This comprehensive guide covers Gradle build scripts for various Java project types, from simple applications to complex microservices architectures.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper