Skip to content

Lesson 01 · Maven ​

Beyond the 1Z0-830 exam

Maven is the build tool these labs use — mvn -f labs/pom.xml test is how every example in this course is verified. Knowing the POM, the lifecycle, and dependency scopes is day-one developer knowledge, even though it's nowhere on the exam.

Objectives

After this lesson you will be able to:

  • Read a pom.xml: coordinates, dependencies, plugins, properties.
  • Explain the build lifecycle and why phases are cumulative.
  • Choose the right dependency scope and understand <scope>test</scope>.
  • Run and skip tests, and build a jar.

The POM and coordinates ​

A Maven project is described by a pom.xml. Every artifact is identified by three coordinates:

xml
<groupId>com.jse21</groupId>      <!-- who/namespace -->
<artifactId>jse21-labs</artifactId> <!-- the project name -->
<version>0.1.0</version>           <!-- this build's version -->

A dependency is just another artifact's coordinates:

xml
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter</artifactId>
  <version>5.11.3</version>
  <scope>test</scope>
</dependency>

Maven downloads it (and its transitive dependencies) from a repository — Maven Central by default — into your local ~/.m2/repository cache.

The build lifecycle and phases ​

The default lifecycle is an ordered list of phases. The common ones:

validate → compile → test → package → verify → install → deploy

The key rule: invoking a phase runs every phase before it. So mvn package first runs validate, compile, and test. You rarely call compile directly — you call the phase you want the result of.

CommandDoes
mvn compilecompile src/main/java
mvn testcompile + run unit tests (Surefire)
mvn packagethe above + build the jar into target/
mvn verify+ run integration tests / checks
mvn install+ copy the artifact into your local ~/.m2 cache
mvn cleandelete target/ (a different lifecycle, often chained: mvn clean test)

Gotcha

mvn test already compiled your code — there is no need to run mvn compile first. And mvn clean on its own only deletes target/; the build you want is usually mvn clean package.

Dependency scopes ​

Scope controls which classpath a dependency is on and whether it's packaged:

ScopeOn main classpath?On test classpath?Packaged?Example
compile (default)✅✅✅a library you call in src/main
test❌✅❌JUnit, Mockito, AssertJ
provided✅ (compile only)✅❌a servlet API supplied by the container
runtime❌ (compile) ✅ (run)✅✅a JDBC driver

test scope is why JUnit is available to your tests but doesn't leak into the shipped jar.

Plugins do the work ​

Phases are bound to plugin goals. The compiler plugin compiles; the Surefire plugin runs tests. This repo pins the Java release and the test runner:

xml
<properties>
  <maven.compiler.release>21</maven.compiler.release> <!-- compile to Java 21 even on a newer JDK -->
</properties>
<plugin>
  <artifactId>maven-surefire-plugin</artifactId>       <!-- runs JUnit tests in the test phase -->
  <version>3.5.2</version>
</plugin>

maven.compiler.release=21 is the modern replacement for separate source/target — it also prevents accidentally using APIs newer than Java 21.

Running the labs ​

bash
mvn -f labs/pom.xml test           # compile + run all lab tests
mvn -f labs/pom.xml test -Dtest=DesignTest   # one test class
mvn -f labs/pom.xml package -DskipTests       # build the jar, skip tests
mvn -f labs/pom.xml clean test     # fresh build

SDET note

-Dtest=... (Surefire) selects which tests run — handy for a fast local loop. In CI you'll instead use profiles or tags to split fast unit tests from slow integration tests (Modules 15 & 20), so the quick suite gates every push and the slow one runs less often.

Key Takeaways ​

  • An artifact = groupId:artifactId:version; dependencies are other artifacts, fetched from a repository (Maven Central) into ~/.m2.
  • Lifecycle phases are cumulative: mvn package runs validate→compile→test→package.
  • test scope = test classpath only, not packaged (JUnit, Mockito); runtime = needed to run but not compile (JDBC drivers).
  • Phases run plugin goals; pin Java with maven.compiler.release=21.
  • Run the labs with mvn -f labs/pom.xml test; -DskipTests to skip, -Dtest=Class to narrow.

Lesson Quiz ​

Lesson Quiz · Maven0 / 5
  1. What does `mvn package` execute before packaging?

    • ANothing — phases are independent
    • Bvalidate, compile, and test (all preceding phases)
    • COnly compile
    • Ddeploy
  2. JUnit is declared with <scope>test</scope>. What does that mean?

    • AIt's on the main and test classpaths and packaged
    • BIt's on the test classpath only and not packaged into the artifact
    • CIt's downloaded but never used
    • DIt's provided by the JDK
  3. Which three coordinates uniquely identify a Maven artifact?

    • Aname, author, license
    • BgroupId, artifactId, version
    • Cpackage, class, method
    • Drepo, branch, tag
  4. Why set maven.compiler.release=21?

    • AIt speeds up the build
    • BIt compiles to Java 21 bytecode AND rejects APIs newer than 21, even on a newer JDK
    • CIt is required for JUnit
    • DIt enables Gradle
  5. A JDBC driver is needed to run but not to compile your code. Best scope?

    • Acompile
    • Btest
    • Cprovided
    • Druntime

Next: Gradle (basics). This module's lab is in labs/src/main/java/com/jse21/m13_build/.