Why Build Tools?
Why Build Tools?
You already know how to write Java — classes, generics, streams, concurrency, JDBC. But knowing the language is only part of the picture. The moment a project grows beyond a handful of source files, three problems compound each other: compilation at scale, dependency management, and packaging for deployment. Build tools exist to solve all three, reliably and repeatably.
The Limits of Bare javac
The Java compiler javac is perfectly capable for learning exercises. In a real project it quickly becomes unwieldy.
Imagine a modest service with 40 source files spread across packages, a logging library, a JSON parser, an HTTP client, and a database driver. Compiling it manually looks something like this:
That command must be re-assembled every time a file or dependency changes. You also have to manually download each .jar, track its version, and find its transitive dependencies — the libraries that your libraries themselves depend on. This is the dependency-hell that build tools eliminate.
NoSuchMethodError or ClassNotFoundException at runtime — hours after the code compiled cleanly.
What a Build Tool Actually Does
A build tool is a program that reads a declarative description of your project — what it depends on, how it should be compiled, and what artefact it should produce — and then executes those steps deterministically. The key responsibilities are:
- Dependency resolution. You declare what you need (e.g., Jackson 2.15.2). The tool fetches the jar and all its transitive dependencies from a central repository, caches them locally, and puts them on the classpath automatically.
- Compilation orchestration. The tool discovers all source files, compiles them in the correct order, and only recompiles what has actually changed (incremental builds).
- Testing. Build tools integrate with JUnit 5 and other test frameworks.
mvn testorgradle testcompiles test sources, runs all tests, and produces a report — one command, no manual setup. - Packaging. The tool assembles compiled classes, resources, and dependencies into a deployable artefact — a
.jar, a.warfor app servers, or a fat/uber-jar with all dependencies bundled inside. - Lifecycle management. Steps are ordered: clean → compile → test → package → install → deploy. Skipping or misordering them is not possible by accident.
Reproducibility and the Build as Code
Perhaps the most important property of a build tool is reproducibility. The build descriptor — pom.xml for Maven, build.gradle for Gradle — is committed to version control. Any developer on any machine runs the same command and gets the same output.
Compare the two approaches side by side:
- Manual javac: no dependency record, manual jar downloads, classpath assembled by hand, steps documented in a README that quickly drifts from reality.
- Maven / Gradle: all dependencies declared with exact versions, fetched automatically, build steps defined in code, same output on every machine in every environment.
Packaging: From Classes to a Runnable Artefact
Compiling produces .class files scattered across directories. Shipping those files to a server is impractical. Build tools automate packaging into a single deployable unit.
The most common artefact types:
- Thin jar — contains only your compiled classes and resources. The runtime classpath must supply all dependencies separately. Used inside application servers and frameworks that manage the classpath themselves.
- Fat jar / uber-jar — all dependencies are embedded. You ship one self-contained file:
java -jar myapp.jar. The Spring Boot and Quarkus default. Simple to deploy but larger in size. - WAR — a web application archive for deployment into a servlet container (Tomcat, Jetty). Dependencies go inside
WEB-INF/lib/.
Building a runnable fat jar with Maven is as simple as adding the maven-shade-plugin to the POM and running one command:
The Two Dominant Tools: Maven and Gradle
The Java ecosystem has two mature build tools. You will encounter both in professional projects.
- Maven — convention over configuration, XML-based POM, strict lifecycle phases, enormous plugin ecosystem, the industry standard for enterprise Java for two decades. Excellent for teams that want predictable, boring builds.
- Gradle — Groovy or Kotlin DSL, highly flexible, incremental and cached builds, the default for Android and increasingly for large multi-module server projects. Faster at scale, more expressive, and requires more discipline to keep consistent.
Summary
Raw javac scales poorly beyond trivial projects. Build tools solve the three core problems of professional Java development: dependency management (fetch and resolve libraries automatically), compilation (incremental, ordered, classpath-correct), and packaging (produce a deployable artefact). They also make builds reproducible — the same descriptor produces the same output on every machine, which is the foundation of CI/CD, team collaboration, and production deployments. The next lessons explore Maven and Gradle in depth.