Build Systems — Maven & Gradle

Java-র build system — Maven ও Gradle

Read: ~30 min Intermediate 5 practice problems Build concepts

1. What Is a Build System?

A build system takes your source code, a list of dependencies, and a few rules — and produces a runnable artifact: a JAR, a WAR, a Docker image, whatever. It compiles, runs tests, packages, and if you like, deploys. In the Java world, two tools dominate: Maven (declarative XML, convention-driven) and Gradle (programmable DSL, performance-tuned).

Build system আপনার source code, dependency-র তালিকা ও কিছু rule নেয়, এবং তৈরি করে একটি চলনসই artifact — JAR, WAR, Docker image বা অন্য কিছু। Compile, test, package, এমনকি deploy পর্যন্ত করে। Java-তে প্রধান দুটি টুল — Maven (XML-ভিত্তিক declarative) ও Gradle (Kotlin/Groovy DSL, দ্রুত)।

2. Maven — pom.xml as a Contract

Maven's core idea is convention over configuration. Put code in src/main/java, tests in src/test/java, declare dependencies in a pom.xml, and everything just works. A single file describes the whole project.

Maven-এর মূল ধারণা convention over configuration। কোড src/main/java-তে, test src/test/java-তে রাখবেন, dependency pom.xml-এ ঘোষণা করবেন — বাকিটা Maven নিজেই সামলাবে। একটি ফাইলেই পুরো project-এর description।
pom.xml
<!-- Minimal pom.xml for a Java 21 project -->
<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.abcltech</groupId>
  <artifactId>bkash-demo</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>

  <properties>
    <maven.compiler.source>21</maven.compiler.source>
    <maven.compiler.target>21</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>5.10.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Common commands (run in the project directory):

CommandDoesবাংলায়
mvn compileCompile src/main/java.Main source compile করে।
mvn testCompile + run all tests.Compile করে সব test চালায়।
mvn packageProduce the .jar (or .war).JAR বা WAR তৈরি করে।
mvn installInstall into your local Maven repo (~/.m2).Local Maven repo-তে install করে।
mvn cleanDelete the target/ folder.target/ folder মুছে দেয়।

3. Maven Build Lifecycle

Maven Default Lifecycle — Phases Run in Order validatecheck pom compilemain sources testrun JUnit packagebuild JAR verifyintegration install→ ~/.m2 Each phase implies all preceding ones. mvn install runs everything to its left. Figure 44.1 — Maven-এর default lifecycle। একটি phase চালালে তার আগের সব phase একসাথে চলে।
Maven-এর lifecycle শেখার সবচেয়ে বড় টিপস — আপনি mvn install চালালে আগের সব phase (validate → compile → test → package → verify) স্বয়ংক্রিয়ভাবে চলে। তাই আলাদা-আলাদা chain করার দরকার নেই।

4. Gradle — Code as Configuration

Where Maven is declarative XML, Gradle is a real programming language (Groovy originally, Kotlin today). Build logic becomes expressive — you can write conditionals, loops, and functions in the build script. Gradle is also much faster than Maven on incremental builds, thanks to build caching.

Maven যেখানে XML-এ declarative, Gradle সেখানে একটি পূর্ণাঙ্গ programming language (আগে Groovy, এখন Kotlin)। Build logic-এ if/loop/function লেখা যায়। Gradle build cache-এর কারণে incremental build-এ অনেক দ্রুত।
build.gradle.kts
// Gradle build in Kotlin DSL
plugins {
    java
    application
}

group = "com.abcltech"
version = "1.0.0"

java {
    toolchain { languageVersion.set(JavaLanguageVersion.of(21)) }
}

repositories { mavenCentral() }

dependencies {
    implementation("com.google.guava:guava:33.0.0-jre")
    testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
}

application {
    mainClass.set("com.abcltech.bkash.Main")
}

tasks.test { useJUnitPlatform() }

Typical commands:

CommandDoesবাংলায়
./gradlew buildCompile + test + package.Compile, test, package — একসাথে।
./gradlew runRun the app's main class.App-এর main class চালায়।
./gradlew testRun just the tests.শুধু test চালায়।
./gradlew tasksList every available task.সব available task দেখায়।

5. Dependency Scopes (dependency-র ধরন)

Not every dependency belongs at runtime. Scopes let the build system decide where each dependency should appear: on the compile classpath, the test classpath, the runtime classpath, or all three.

Maven scopeGradle keywordWhen visible
compile (default)implementationCompile + runtime. Most libraries.
providedcompileOnlyCompile only — container provides at runtime (e.g. Servlet API).
runtimeruntimeOnlyRuntime only — JDBC drivers, logging backends.
testtestImplementationTest classpath only — JUnit, Mockito.
A healthy production project in Bangladeshi fintech will have one Maven or Gradle file per microservice, with carefully managed scopes — this is how you keep a deploy under 30 MB and free of leaked test code.

বাংলাদেশের একটি সুস্থ fintech microservice project-এ প্রতিটি service-এর জন্য একটি Maven/Gradle ফাইল থাকে, scope সঠিকভাবে পরিচালিত — তাই deploy আকার ছোট থাকে এবং test কোড ভুল করে production-এ যায় না।

6. When to Choose Which?

✅ Pick Maven When…

  • The team wants predictability & convention
  • Spring Boot starter templates (default is Maven)
  • Simple apps, small teams, no custom build logic
  • Legacy enterprise environments

⚡ Pick Gradle When…

  • You need fast incremental/parallel builds
  • Custom build logic (code generation, packaging, etc.)
  • Android projects — Gradle is mandatory
  • Multi-language projects (Java + Kotlin + Scala)

7. Vocabulary

TermMeaningবাংলায়
ArtifactOutput of a build — a JAR, WAR, or ZIP.Build-এর output — JAR, WAR ইত্যাদি।
CoordinategroupId:artifactId:version — unique address of a library.একটি library-র unique address।
Transitive depA dep pulled in indirectly through another.পরোক্ষভাবে আসা dependency।
Local repoYour machine's cached JARs — ~/.m2 or ~/.gradle.আপনার মেশিনের cached JAR।
CentralMaven Central — the world's shared Java library server.Maven Central — পৃথিবীর shared Java library server।
Wrappermvnw / gradlew — reproducible tool version per project.প্রতি project-এ নির্দিষ্ট build-tool সংস্করণ।

8. Practice Problems

Most answers are text or configuration — some are runnable Java demos of the underlying concept.

কিছু প্রশ্নের উত্তর configuration-নির্ভর, কিছু runnable Java demo।
  1. Write a Java program that prints the three parts of a Maven coordinate given a combined string like "com.google.guava:guava:33.0.0-jre".
    "com.google.guava:guava:33.0.0-jre"-এর মতো string থেকে groupId, artifactId, version আলাদা করে প্রিন্ট করুন।
    ✨ Show Answer
    Main.java
    class Main {
        public static void main(String[] args) {
            String coord = "com.google.guava:guava:33.0.0-jre";
            String[] parts = coord.split(":");
            System.out.println("groupId    = " + parts[0]);
            System.out.println("artifactId = " + parts[1]);
            System.out.println("version    = " + parts[2]);
        }
    }
  2. What does mvn install do that mvn package doesn't?
    mvn install যা করে কিন্তু mvn package করে না — সেটি কী?
    ✨ Show Answer

    Answer: mvn package builds the JAR/WAR in target/. mvn install does everything package does AND then copies the artifact into your local Maven cache at ~/.m2/repository, so that other local projects on your machine can resolve it by coordinate.

    mvn package শুধু target/-এ JAR/WAR তৈরি করে; mvn install সেটিকে আরো local Maven cache (~/.m2/repository)-এ copy করে — যাতে একই মেশিনের অন্য project সেটিকে dependency হিসেবে পায়।

  3. Write a Java program that simulates a tiny "build" — it prints the phases compile → test → package → install in order, skipping any phase named as a command-line argument.
    একটি ছোট "build" simulator বানান — compile → test → package → install প্রিন্ট করবে, কিন্তু command-line-এ যে phase দেওয়া হবে সেটি skip করবে।
    ✨ Show Answer
    Main.java
    class Main {
        public static void main(String[] args) {
            String[] phases = {"compile", "test", "package", "install"};
            String skip = args.length > 0 ? args[0] : "";
            for (String p : phases) {
                if (p.equals(skip)) { System.out.println("[SKIP] " + p); continue; }
                System.out.println("[RUN ] " + p);
            }
        }
    }
  4. Which scope would you use for (a) JUnit, (b) a PostgreSQL JDBC driver, (c) the Servlet API (Tomcat provides it)?
    কোন scope লাগবে — (ক) JUnit, (খ) PostgreSQL JDBC driver, (গ) Servlet API (Tomcat দেবে)?
    ✨ Show Answer

    Answer: (a) test / testImplementation — JUnit only exists during tests. (b) runtime / runtimeOnly — you never import a driver class in your code; it is loaded reflectively at runtime. (c) provided / compileOnly — you need it to compile your servlet but the container provides it, so shipping it in your WAR would conflict.

  5. Explain "transitive dependency" and why version conflicts are possible.
    "Transitive dependency" কী, এবং কেন version conflict হতে পারে — ব্যাখ্যা করুন।
    ✨ Show Answer

    Answer: If your project depends on A, and A depends on B, then B is a transitive dependency — you did not name it, but it arrives on your classpath anyway. Version conflicts happen when two direct dependencies pull in different versions of the same transitive dep (Maven picks "nearest" in the dependency tree; Gradle picks "highest" by default). Resolve with the dependencyManagement section in Maven or a Gradle resolutionStrategy to force a version.

Summary — Module 44

Maven gives you convention, predictability, and XML. Gradle gives you programmable, fast, incremental builds. Both share the same mental model: source → compile → test → package → install. Pick one, master its lifecycle, and keep your pom.xml or build.gradle.kts clean — it is the contract between your code and the rest of the team.

Maven দেয় convention ও predictability, Gradle দেয় গতি ও programmability। দুটিরই একই মডেল — source → compile → test → package → install। যেটিই বাছুন, তার lifecycle ভালো করে শিখে নিন।

Next Module → Design Patterns in Java — Gang of Four-এর ২৩টি pattern, বাস্তব ব্যবহার।