Chaturmind
LearnDSASystem DesignInterview PrepDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth
  • Java Interview Prep

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Java Interview Prep: 2–5 Years

Revise the Fresher Tier

  • Revise: Core Java Fundamentals (Fresher Tier)
  • Revise: Collections, Threads, Java 8 & Coding (Fresher Tier)
  • Revise: Spring Core, Spring Boot & Spring MVC (Fresher Tier)
  • Revise: Hibernate, SQL, Microservices, Maven & Git (Fresher Tier)

Intermediate Core Java

  • Intermediate OOP & Language Features — Interview Questions
  • Enums, Generics, Pass-by-Value & Imports — Interview Questions
  • Collections Internals & Scenarios — Interview Questions
  • JVM, Memory & Class Loading — Interview Questions
  • Exception Design & Serialization Edge Cases — Interview Questions

Java 8 Deep Dive & Stream Coding

  • Lambdas, Functional Interfaces & Method References — Interview Questions
  • Default Methods, Backward Compatibility & Optional — Interview Questions
  • Stream API Internals (Part 1) — Interview Questions
  • Stream API Internals (Part 2) — Interview Questions
  • Stream Coding Problems (Level 2, Part 1) — Interview Questions
  • Stream Coding Problems (Level 2, Part 2) — Interview Questions

Concurrency & Multithreading

  • Synchronization, Locks & Deadlocks — Interview Questions
  • Executors, ThreadLocal & Concurrent Collections — Interview Questions

Spring Framework In Depth

  • Bean Lifecycle, Contexts & Circular Dependencies — Interview Questions
  • Spring Bean Conflicts, AOP, Batch & Injection Styles — Interview Questions

Spring Boot In Depth & Scenarios

  • Spring Boot Internals & Auto-Configuration — Interview Questions
  • Spring Boot Configuration, Profiles & Secrets — Interview Questions
  • Spring Boot Data, Transactions & Caching — Interview Questions
  • Spring Boot Testing, Error Pages & Deployment — Interview Questions
  • Spring Boot Performance, Scaling & Resilience — Interview Questions
  • Spring Boot Async, Events & Messaging — Interview Questions
  • Spring Boot Security Scenarios — Interview Questions
  • Actuator, AOP, Spring Cloud & Distributed Tracing — Interview Questions
  • External APIs, Files, GraphQL & WebFlux — Interview Questions

Spring Security

  • Spring Security — OAuth2, CORS, CSRF & Access Rules — Interview Questions
  • Spring Security — Passwords, Filter Chain, Sessions & Debugging — Interview Questions

Apache Kafka

  • Kafka Architecture, Topics & ZooKeeper vs KRaft — Interview Questions
  • Kafka Producers, Consumers, Reliability & Streams — Interview Questions
  • Kafka Security, Connect & Core Scenarios — Interview Questions
  • Kafka Production Scenarios — Interview Questions

Git, Maven & Gradle (Level II)

  • Git Workflows, Rebase & Conflict Handling — Interview Questions
  • Git Recovery, Hooks, Tags & Collaboration — Interview Questions
  • Maven Builds, Multi-Module Projects & Dependency Resolution — Interview Questions
  • Maven Profiles, settings.xml, Plugins & Quality Gates — Interview Questions
  • Gradle Fundamentals, Migration & Dependencies — Interview Questions
  • Gradle Performance, Plugins, Testing & Publishing — Interview Questions

Deployment & CI/CD

  • Sessions, CI/CD Pipelines, Rollbacks & Secrets — Interview Questions
  • Migrations, Zero-Downtime Releases, Containers & Monitoring — Interview Questions

JUnit 5 & Mockito

  • JUnit 5 — Interview Questions
  • Mockito Basics — Interview Questions
  • Mockito Advanced & Tricky Questions — Interview Questions
Chaturmind
← Java Interview Prep: 2–5 Years

Revise the Fresher Tier

  • Revise: Core Java Fundamentals (Fresher Tier)
  • Revise: Collections, Threads, Java 8 & Coding (Fresher Tier)
  • Revise: Spring Core, Spring Boot & Spring MVC (Fresher Tier)
  • Revise: Hibernate, SQL, Microservices, Maven & Git (Fresher Tier)

Intermediate Core Java

  • Intermediate OOP & Language Features — Interview Questions
  • Enums, Generics, Pass-by-Value & Imports — Interview Questions
  • Collections Internals & Scenarios — Interview Questions
  • JVM, Memory & Class Loading — Interview Questions
  • Exception Design & Serialization Edge Cases — Interview Questions

Java 8 Deep Dive & Stream Coding

  • Lambdas, Functional Interfaces & Method References — Interview Questions
  • Default Methods, Backward Compatibility & Optional — Interview Questions
  • Stream API Internals (Part 1) — Interview Questions
  • Stream API Internals (Part 2) — Interview Questions
  • Stream Coding Problems (Level 2, Part 1) — Interview Questions
  • Stream Coding Problems (Level 2, Part 2) — Interview Questions

Concurrency & Multithreading

  • Synchronization, Locks & Deadlocks — Interview Questions
  • Executors, ThreadLocal & Concurrent Collections — Interview Questions

Spring Framework In Depth

  • Bean Lifecycle, Contexts & Circular Dependencies — Interview Questions
  • Spring Bean Conflicts, AOP, Batch & Injection Styles — Interview Questions

Spring Boot In Depth & Scenarios

  • Spring Boot Internals & Auto-Configuration — Interview Questions
  • Spring Boot Configuration, Profiles & Secrets — Interview Questions
  • Spring Boot Data, Transactions & Caching — Interview Questions
  • Spring Boot Testing, Error Pages & Deployment — Interview Questions
  • Spring Boot Performance, Scaling & Resilience — Interview Questions
  • Spring Boot Async, Events & Messaging — Interview Questions
  • Spring Boot Security Scenarios — Interview Questions
  • Actuator, AOP, Spring Cloud & Distributed Tracing — Interview Questions
  • External APIs, Files, GraphQL & WebFlux — Interview Questions

Spring Security

  • Spring Security — OAuth2, CORS, CSRF & Access Rules — Interview Questions
  • Spring Security — Passwords, Filter Chain, Sessions & Debugging — Interview Questions

Apache Kafka

  • Kafka Architecture, Topics & ZooKeeper vs KRaft — Interview Questions
  • Kafka Producers, Consumers, Reliability & Streams — Interview Questions
  • Kafka Security, Connect & Core Scenarios — Interview Questions
  • Kafka Production Scenarios — Interview Questions

Git, Maven & Gradle (Level II)

  • Git Workflows, Rebase & Conflict Handling — Interview Questions
  • Git Recovery, Hooks, Tags & Collaboration — Interview Questions
  • Maven Builds, Multi-Module Projects & Dependency Resolution — Interview Questions
  • Maven Profiles, settings.xml, Plugins & Quality Gates — Interview Questions
  • Gradle Fundamentals, Migration & Dependencies — Interview Questions
  • Gradle Performance, Plugins, Testing & Publishing — Interview Questions

Deployment & CI/CD

  • Sessions, CI/CD Pipelines, Rollbacks & Secrets — Interview Questions
  • Migrations, Zero-Downtime Releases, Containers & Monitoring — Interview Questions

JUnit 5 & Mockito

  • JUnit 5 — Interview Questions
  • Mockito Basics — Interview Questions
  • Mockito Advanced & Tricky Questions — Interview Questions
HomeLearnJava Interview PrepJava Interview Prep: 2–5 YearsGit, Maven & Gradle (Level II)
✓ FreeIntermediate· 7 min read

Gradle Performance, Plugins, Testing & Publishing — Interview Questions

Adding third-party libraries, transitive dependencies and how to control them, speeding up Gradle builds, unit testing with JUnit 5, the build cache, publishing to a remote repository, automated code-quality checks, one version across many modules, writing a Gradle plugin, and why the Gradle Wrapper matters.

Published September 25, 2026


How to use this lesson

The questions here are about making Gradle fast, consistent and shareable across many modules and teams. The key modern answers: version catalogs and platforms for consistency, convention plugins for sharing, and build cache plus configuration cache for speed.

Q1. Scenario: you need to integrate a third-party library into a Gradle project. What steps do you follow?

Short answer:

  1. Vet the library: licence, maintenance activity, known vulnerabilities, and transitive footprint.
  2. Add it to the version catalog, and reference it with the right configuration (implementation, api, runtimeOnly).
  3. Make sure the repository is configured (Maven Central or the company proxy). JCenter is gone.
  4. Check the resolved graph (./gradlew dependencies --configuration runtimeClasspath) for conflicts, and align with BOMs if needed.
  5. Wrap it behind your own interface if it's a significant external dependency, and add tests around the integration.
  6. Let Renovate or Dependabot keep it updated.
# gradle/libs.versions.toml
[versions]
resilience4j = "2.2.0"
[libraries]
resilience4j-spring-boot3 = { module = "io.github.resilience4j:resilience4j-spring-boot3", version.ref = "resilience4j" }

Q2. How does Gradle handle transitive dependencies, and how can you customise that behaviour?

Short answer: Gradle resolves the full graph, and when several versions of a module appear, it chooses the highest version by default (unlike Maven's nearest-wins). Gradle Module Metadata adds variants and capabilities, so the right flavour of a dependency is chosen. You can customise this with:

  • Exclusions, per dependency or per configuration.
  • Dependency constraints, to require a minimum or exact version, with a reason.
  • Platforms (BOMs), to align related modules.
  • resolutionStrategy: force, failOnVersionConflict(), dependency substitution, cache policies.
  • Capabilities conflict resolution, for two libraries providing the same functionality (for example, two logging bindings).
  • Dependency locking, for reproducible builds.
dependencies {
    implementation("com.example:sdk:3.1.0") {
        exclude(group = "commons-logging", module = "commons-logging")
    }
    constraints {
        implementation("com.fasterxml.jackson.core:jackson-databind:2.17.2") { because("CVE fix, aligned with Boot") }
    }
}

Q3. Scenario: you want to improve Gradle build performance. What do you do?

Short answer: Measure first with a build scan (--scan) or --profile, then:

  • Enable the build cache (org.gradle.caching=true), local and remote (shared by CI and developers).
  • Enable the configuration cache (org.gradle.configuration-cache=true).
  • Use parallel execution (org.gradle.parallel=true) and a healthy module graph.
  • Keep the daemon (the default) and give it enough heap (org.gradle.jvmargs=-Xmx4g).
  • Use lazy task APIs (tasks.register, providers), and avoid work at configuration time.
  • Speed up tests: maxParallelForks, test filtering, and moving slow integration tests out of the default check.
  • Upgrade Gradle and its plugins regularly, because performance improvements land often.

Q4. How do you implement unit tests in a Gradle project?

Short answer: Put the tests in src/test/java, add JUnit 5, and tell Gradle to use the JUnit Platform:

dependencies {
    testImplementation(platform("org.junit:junit-bom:5.11.0"))
    testImplementation("org.junit.jupiter:junit-jupiter")
    testImplementation("org.mockito:mockito-junit-jupiter:5.12.0")
    testImplementation("org.assertj:assertj-core:3.26.0")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
tasks.test {
    useJUnitPlatform()
    maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1)
    testLogging { events("failed"); exceptionFormat = TestExceptionFormat.FULL }
}

Run them with ./gradlew test. The reports end up in build/reports/tests/test.

Common trap: JUnit 4 (junit:junit:4.12) examples. Without useJUnitPlatform(), JUnit 5 tests silently don't run. Use the JVM Test Suite plugin for separate integration-test suites.

Q5. How do you use Gradle's build cache, and what are the benefits?

Short answer: Enable it with org.gradle.caching=true. Cacheable tasks (compilation, tests, code generation) store their outputs keyed by a hash of their inputs. Any later build, on any branch or machine, with the same inputs reuses the outputs (FROM-CACHE) instead of running the task. A remote cache (Develocity, or a cache node) lets CI populate the cache and developers consume it.

// settings.gradle.kts
buildCache {
    local { isEnabled = true }
    remote<HttpBuildCache> {
        url = uri("https://gradle-cache.acme.internal/cache/")
        isPush = System.getenv("CI") != null            // only CI writes; developers read
    }
}

Key points to cover:

  • Its effectiveness depends on reproducible, well-declared task inputs. Absolute paths or timestamps in the inputs cause cache misses.

Q6. Scenario: configure a Gradle project to publish artifacts to a remote repository.

Short answer: Apply maven-publish, define a publication (the component, plus the sources and Javadoc JARs), and a repository, with credentials from the environment. Then run ./gradlew publish.

plugins { `java-library`; `maven-publish` }
java { withSourcesJar(); withJavadocJar() }

publishing {
    publications { create<MavenPublication>("lib") { from(components["java"]) } }
    repositories {
        maven {
            name = "company"
            url = uri(if (version.toString().endsWith("SNAPSHOT"))
                          "https://nexus.acme.internal/repository/snapshots/"
                      else "https://nexus.acme.internal/repository/releases/")
            credentials(PasswordCredentials::class)       // reads companyUsername / companyPassword properties
        }
    }
}

Key points to cover:

  • Add signing for public releases (Maven Central requires it).
  • Release versions are immutable. Automate versioning and publishing in CI from tags.

Q7. How do you automate code-quality checks in a Gradle build?

Short answer: Apply the quality plugins (Spotless, Checkstyle, PMD, SpotBugs, JaCoCo with coverage verification, Error Prone, and OWASP Dependency-Check), preferably in a convention plugin, so every module gets them. Wire them into check, so ./gradlew build enforces them, and fail on violations. Report to SonarQube from CI.

plugins { checkstyle; jacoco; id("com.diffplug.spotless"); id("com.github.spotbugs") }
tasks.check { dependsOn(tasks.jacocoTestCoverageVerification) }
tasks.jacocoTestCoverageVerification { violationRules { rule { limit { minimum = "0.80".toBigDecimal() } } } }
spotless { java { googleJavaFormat() } }

Q8. Scenario: many modules must all use the same version of a dependency. How do you manage that?

Short answer: Centralise the version, not the dependency itself:

  • A version catalog (libs.versions.toml), so every module references libs.jackson.databind with one version.
  • A platform, either an imported BOM or your own java-platform project with constraints, to align families of libraries.
  • Dependency locking and failOnVersionConflict(), to detect drift.

Each module still declares only the dependencies it uses.

Common trap: declaring the dependency inside subprojects { dependencies { implementation(...) } }. That forces the library into every module, whether it needs it or not, and cross-project configuration is discouraged anyway.

Q9. How do you create a Gradle plugin, and what is it used for?

Short answer: Implement Plugin<Project>, and in apply(), apply other plugins, register tasks and extensions (the configurable DSL). The simplest form is a precompiled script plugin: a acme.java-conventions.gradle.kts file in build-logic/src/main/kotlin. For distribution across repositories, build a standalone plugin with java-gradle-plugin, test it with TestKit, and publish it to the company repository (or the Gradle Plugin Portal).

class ServiceConventionsPlugin : Plugin<Project> {
    override fun apply(project: Project) = with(project) {
        pluginManager.apply("java")
        extensions.configure<JavaPluginExtension> { toolchain.languageVersion.set(JavaLanguageVersion.of(21)) }
        tasks.withType<Test>().configureEach { useJUnitPlatform() }
    }
}

Use cases: company-wide conventions (the Java version, quality checks, publishing), code generation, deployment tasks, and integrating internal tools.

Q10. What does the Gradle Wrapper give you over a global Gradle installation?

Short answer: The Wrapper (gradlew plus gradle/wrapper/gradle-wrapper.properties) pins the Gradle version per project, and downloads it automatically. Every developer and CI agent builds with exactly the same version, with no installation and no "works with my Gradle" problems. Upgrades are a reviewed change (./gradlew wrapper --gradle-version 8.10).

Key points to cover:

  • Commit the wrapper files, including gradle-wrapper.jar, and verify the distribution checksum (distributionSha256Sum) for supply-chain safety.

Follow-up questions this topic invites — and their answers

Q: What are Gradle's three build phases? A: Initialisation (read settings.gradle, determine the projects), configuration (evaluate the build scripts, build the task graph) and execution (run the selected tasks). Keeping configuration cheap, and cacheable, is key to performance.

Q: What's the difference between tasks.register and tasks.create? A: register is lazy: the task is configured only if it's actually needed in this build. create configures it eagerly, which slows every build.

Q: How do you run a single test class? A: ./gradlew test --tests "com.acme.orders.CheckoutServiceTest", where wildcards and method names are supported.

Q: What is Develocity (formerly Gradle Enterprise)? A: A commercial platform for build scans, remote build caching, predictive test selection and build analytics, for both Gradle and Maven.

Previous

Gradle Fundamentals, Migration & Dependencies — Interview Questions

Next

Sessions, CI/CD Pipelines, Rollbacks & Secrets — Interview Questions

AI Tutor

Lesson: Gradle Performance, Plugins, Testing & Publishing — Interview Questions

Quick actions

AI responses can be inaccurate. Verify critical information.