Step 9 · Ubuntu · Independent

Java build tools: Maven and Gradle

javac is fine until your project needs a third-party library, a test framework, or more than a handful of files. Then you want a build tool. These are the two you will meet.

This step stands alone — but it needs a JDK

Step 5 gives you javac, java and jshell, which is everything you need to compile and run source files. Come here when a project has a pom.xml or a build.gradle. Install step 5 first — both of these are useless without a JDK. This step is not part of the install_all.sh run.

Run this

$ curl -fsSL https://aikaryashala.com/system_setup/scripts/install_maven_gradle.sh | bash

Only want one of them?

$ curl -fsSL https://aikaryashala.com/system_setup/scripts/install_maven_gradle.sh | SKIP_GRADLE=1 bash
$ curl -fsSL https://aikaryashala.com/system_setup/scripts/install_maven_gradle.sh | SKIP_MAVEN=1 bash

Which one?

MavenGradle
Configurationpom.xml — XMLbuild.gradle.kts — Kotlin or Groovy code
StyleDeclarative, rigid, very predictableProgrammable, flexible, more to learn
SpeedSteadyFaster on repeat builds — it caches aggressively
Best whenYou want convention and no surprisesYou have a big project, or an Android one

If you have no preference and no existing project, start with Maven. Its rigidity is a feature while you are learning.

Where these come from

Maven comes from Ubuntu's own packages. Gradle does not — Ubuntu's build is usually several major versions behind, so the script asks services.gradle.org what the current release is and installs that into /opt/gradle, with a stable current symlink so later upgrades do not touch your PATH.

A Maven project

Maven expects a fixed directory layout and describes the build in pom.xml.

$ mvn archetype:generate \
    -DgroupId=com.example \
    -DartifactId=myapp \
    -DarchetypeArtifactId=maven-archetype-quickstart \
    -DinteractiveMode=false

$ cd myapp
$ mvn compile
$ mvn test
$ mvn package
$ java -cp target/myapp-1.0-SNAPSHOT.jar com.example.App
The first Maven build is slow

Maven downloads its own plugins on first use, into ~/.m2. Expect a few minutes and a lot of scrolling once. Later builds are fast.

A Gradle project

$ mkdir myapp && cd myapp
$ gradle init --type java-application --dsl kotlin \
    --test-framework junit-jupiter --project-name myapp --package com.example

$ ./gradlew build
$ ./gradlew run
$ ./gradlew test
Use ./gradlew, not gradle

gradle init generates a wrapper script, gradlew, pinned to the exact Gradle version the project needs. Using it means everyone building the project gets the same Gradle, whatever they have installed. Commit it; call gradle directly only when creating a project.

Adding a library

This is the reason to reach for a build tool at all. In Maven:

<dependencies>
  <dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.11.0</version>
  </dependency>
</dependencies>

And in Gradle:

dependencies {
    implementation("com.google.code.gson:gson:2.11.0")
}

Either way the tool downloads the library and everything it depends on, and puts it on the classpath for you — the job you would otherwise be doing by hand with javac -cp.

Check it worked

$ mvn -version
$ gradle --version
$ echo $JAVA_HOME
“JAVA_HOME is not set”

Both tools need a JDK. Run step 5, then source ~/.bashrc so JAVA_HOME is set in your current shell.