Introduction to Maven and Gradle for Java Projects
Introduction
Compiling a few classes with
(Note - What a build tool automates is described in Compiling and Running Java Programs with javac and javaClick to read tutorial: Compiling and Running Java Programs with javac and java.) What does a build tool do?
Our application is the same for both tools. It uses Google's Gson library to turn a record into JSON -
Building with Maven
Apache Maven describes a project in an XML file,
Explanation of the pom.xml
OUTPUT of the above commands
Explanation of the commands
Building with Gradle
Gradle describes a build in code rather than XML - a Groovy script,
Explanation of the build.gradle
OUTPUT of the above command
The
OUTPUT of the above command
Gson 2.11.0 itself depends on Google's
Maven vs Gradle
javac is easy. A real project, though, has hundreds of source files, tests, third-party libraries - each with its own dependencies - and has to be packaged the same way on every developer's machine and every build server. Build tools automate all of this, and in the Java world there are two main ones: Maven and Gradle. This tutorial is an introduction to Maven and Gradle for Java projects. We will start with what a build tool does, and the standard project layout both tools use. We will then build the same small application - which uses the Gson library - with Maven and with Gradle. Next we will understand dependencies and where they come from, and the commands you will use every day. Lastly, we will compare the two tools.(Note - What a build tool automates is described in Compiling and Running Java Programs with javac and javaClick to read tutorial: Compiling and Running Java Programs with javac and java.) What does a build tool do?
- Dependency management: you list the libraries you need, by name and version; the tool downloads them - and the libraries they need - from a repository such as Maven Central, and puts them on the classpath.
- A standard build lifecycle: compile, run the tests, package a JAR, and more, with one command.
- Reproducible builds: the build is described in a file kept with the code, so it works the same everywhere - on every machine, in CI, and in your IDE, which imports the project directly from that file.
- Plugins: code formatting, test coverage, JavadocClick to read tutorial: Writing Javadoc Comments in Java with Examples generation, Docker images and much more.
greeter/
pom.xml (Maven) or build.gradle + settings.gradle (Gradle)
src/
main/
java/ application source code, in package folders
com/javabrahman/greeter/App.java
resources/ configuration files, copied into the JAR
test/
java/ test code - see the JUnit 5 tutorial
resources/
target/ (Maven) or build/ (Gradle) generated output - never edit or commit it
src/main/java/com/javabrahman/greeter/App.java
package com.javabrahman.greeter;
import com.google.gson.Gson;
public class App {
record Greeting(String name, String message, int year) { }
public static void main(String[] args) {
Greeting greeting = new Greeting("Tom", "Hello from a build tool!", 2026);
String json = new Gson().toJson(greeting);
System.out.println(json);
}
}
pom.xml - the Project Object Model.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javabrahman</groupId>
<artifactId>greeter</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.release>21</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
</project>
groupId,artifactIdandversion- the coordinates which identify this project, just as they identify every library in Maven Central.maven.compiler.release- compiles for Java 21, likejavac --release 21.<dependencies>- the libraries the project needs, by their coordinates. Maven downloads Gson 2.11.0, and any libraries Gson itself depends on.
validate, compile, test, package, verify, install, deploy. Running a phase runs every phase before it, so mvn package compiles, runs the tests and creates the JAR. Here we also copy the dependencies into target/dependency, so that we can run the application with plain java -
mvn -q clean package dependency:copy-dependencies dir /b target java -cp "target/classes;target/dependency/*" com.javabrahman.greeter.App
classes
dependency
generated-sources
greeter-1.0.jar
maven-archiver
maven-status
{"name":"Tom","message":"Hello from a build tool!","year":2026}
-q(quiet) shows only errors; without it, Maven prints every phase and plugin it runs.cleandeletestargetfirst, for a fresh build.targetnow holds the compiled classes, the JARgreeter-1.0.jar, and the copiedgsonJAR independency.- On macOS and Linux, use
ls target, and:instead of;in the classpath. On Java 24 and later, Maven 3.9 may print a warning aboutsun.misc.Unsafe; it comes from a library inside Maven, and does not affect the build.
build.gradle, or a Kotlin script, build.gradle.kts - and uses tasks instead of a fixed lifecycle. It is the standard build tool for Android, and is also widely used for server applications.
settings.gradle
rootProject.name = 'greeter'
build.gradle
plugins {
id 'application'
}
group = 'com.javabrahman'
version = '1.0'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(24)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'com.google.code.gson:gson:2.11.0'
}
application {
mainClass = 'com.javabrahman.greeter.App'
}
- The
applicationplugin adds tasks to compile, test, package andruna Java application whose main class is set in theapplicationblock. - The toolchain asks for Java 24 - Gradle finds a matching JDK on the machine, so everyone builds with the same Java version.
implementation '...'declares the same Gson dependency, in the shortgroup:artifact:versionform, andmavenCentral()says where to download it from.
run task compiles the code and runs it with the dependencies on the classpath, in one step -
gradle -q run
{"name":"Tom","message":"Hello from a build tool!","year":2026}
dependencies task shows the full tree of libraries the project uses, including those pulled in by Gson -
gradle -q dependencies --configuration runtimeClasspath
------------------------------------------------------------
Root project 'greeter'
------------------------------------------------------------
runtimeClasspath - Runtime classpath of source set 'main'.
\--- com.google.code.gson:gson:2.11.0
\--- com.google.errorprone:error_prone_annotations:2.27.0
A web-based, searchable dependency report is available by adding the --scan option.
error_prone_annotations, which Gradle resolved automatically - a transitive dependency. Maven does exactly the same; mvn dependency:tree prints the equivalent tree.
Where dependencies come from - and wrappers
- Libraries are downloaded once, from Maven Central, into a local cache -
~/.m2/repositoryfor Maven,~/.gradle/cachesfor Gradle - and reused by every project. - Dependency scopes say where a library is needed: compile-and-run (Maven's default
compilescope, Gradle'simplementation), tests only (test/testImplementation), and others. - Wrappers -
mvnwandgradlewscripts committed to the project - download the exact Maven or Gradle version the project needs, so contributors do not have to install the tool at all. Most real projects use them:./gradlew buildor./mvnw package. - Search Maven Central at central.sonatype.com to find a library's coordinates and latest version.
| Task | Maven | Gradle |
| Compile | mvn compile | gradle compileJava |
| Run the tests | mvn test | gradle test |
| Build the JAR | mvn package | gradle build |
| Delete build output | mvn clean | gradle clean |
| Dependency tree | mvn dependency:tree | gradle dependencies |
| Install to local repository | mvn install | gradle publishToMavenLocal (with the maven-publish plugin) |
- Maven: declarative XML and a fixed lifecycle. Every Maven project looks the same, which makes it predictable and easy to learn. Very common in enterprise and Spring projects.
- Gradle: build scripts in Groovy or Kotlin, flexible custom tasks, and fast incremental builds with a build cache and a background daemon. The standard for Android, and popular for large multi-project builds.
- Both use the same repositories and dependency coordinates, and both are fully supported by IntelliJ IDEA, Eclipse and VS Code. Learn whichever your team uses - the concepts carry over.
src/main/java layout. We then built a small application which uses Gson with Maven, through its pom.xml and lifecycle phases, and with Gradle, through build.gradle and the run task. Next we looked at the dependency tree and transitive dependencies, local caches, scopes and wrappers. Lastly, we compared everyday commands and the two tools. In the next tutorial, we will write automated tests with JUnit 5Click to read tutorial: Unit Testing Basics with JUnit 5 in Java.Core Java Tutorials
Debugging Java Programs in Your IDE and with jdbClick to read tutorial: Debugging Java Programs in Your IDE and with jdb Unit Testing Basics with JUnit 5 in JavaClick to read tutorial: Unit Testing Basics with JUnit 5 in Java Java Naming Conventions and Code Style GuideClick to read tutorial: Java Naming Conventions and Code Style Guide Writing Javadoc Comments in Java with ExamplesClick to read tutorial: Writing Javadoc Comments in Java with Examples Stack vs Heap Memory in Java and Object ReferencesClick to read tutorial: Stack vs Heap Memory in Java and Object References
Debugging Java Programs in Your IDE and with jdbClick to read tutorial: Debugging Java Programs in Your IDE and with jdb Unit Testing Basics with JUnit 5 in JavaClick to read tutorial: Unit Testing Basics with JUnit 5 in Java Java Naming Conventions and Code Style GuideClick to read tutorial: Java Naming Conventions and Code Style Guide Writing Javadoc Comments in Java with ExamplesClick to read tutorial: Writing Javadoc Comments in Java with Examples Stack vs Heap Memory in Java and Object ReferencesClick to read tutorial: Stack vs Heap Memory in Java and Object References