A build tool makes compilation, testing, packaging, and dependency resolution repeatable. Maven describes a project mainly through pom.xml and a conventional lifecycle. Gradle describes tasks with a Groovy or Kotlin build script. Both can manage Java projects; learning one thoroughly is more useful than memorizing two command lists without understanding the resulting build. This lesson builds a small Maven project and compares the corresponding Gradle ideas without requiring you to configure both tools at once.
Follow a predictable project layout
Maven's conventional source directory is src/main/java, and tests belong in src/test/java. Resources have their own neighboring directories. The build writes generated output under target, keeping compiled classes and packaged JARs separate from authored source. Following these conventions avoids extra configuration and makes projects recognizable to collaborators and editors. A source file placed in an arbitrary directory may not be compiled unless you change the configured source roots.
Read the coordinates in a POM
groupId, artifactId, and version identify an artifact. Dependencies use those coordinates to select libraries from repositories. Your project's coordinates do not automatically declare its Java package names, although organizations often keep them related. A dependency version should be explicit or managed through a documented parent or dependency-management section. Avoid assuming that changing artifactId renames every class or package; the build identity and source namespace serve different roles.
Understand the Maven lifecycle
mvn compile runs the steps necessary to compile main source. mvn test includes compilation and executes configured tests. mvn package continues through testing and creates the configured artifact, commonly a JAR. mvn clean removes generated build output before another lifecycle action. Commands can be combined, such as mvn clean package. Tests are not a cosmetic step to skip whenever inconvenient; a failed test should be understood before publishing the resulting application.
Set the Java release explicitly
A build should state its platform target instead of relying on whichever default happens to be installed. The Maven Compiler Plugin's release setting targets Java 17 in the sample configuration. Maven itself also runs on a selected Java installation, which mvn -version reports. A JDK capable of the configured release is still required. The release setting does not download a missing compiler or make a Java 17 runtime execute unsupported newer bytecode.
Let dependencies enter both build phases
Maven resolves declared dependencies into a local repository and constructs appropriate classpaths. A dependency with test scope is available to tests but not normally packaged as a runtime requirement. Runtime packaging still depends on the chosen artifact strategy: an ordinary JAR does not automatically bundle all dependencies into one executable file. Distinguish a plain library JAR, an executable JAR with manifest configuration, and a distribution including dependency JARs.
Compare the Gradle model
Gradle's Java plugin supplies tasks such as compileJava, test, and jar. A Java toolchain and source compatibility configuration control its compiler selection and platform target. The Gradle wrapper lets collaborators invoke a project-selected Gradle version through gradlew rather than depending solely on a machine-wide install. Maven has a wrapper too. Commit wrapper files according to the tool's guidance, but keep downloaded caches and generated target or build directories out of version control.
Practice tasks and checks
Create the displayed directory layout, save the POM and BuildLabel source, and run the package command from the root containing pom.xml. Inspect target/classes and the generated JAR before launching it. Change the artifact version and predict the new filename; do not assume the Java class name changes too. Add a deliberately invalid Java statement and confirm the build fails before packaging a new successful artifact. Restore the source and rebuild. Finally, write a README with the required Java release, build command, and exact launch command. If using Gradle instead, document the equivalent wrapper tasks and resulting JAR location. A collaborator should be able to build from authored files without receiving your target directory.
Java Summary
- Keep authored source separate from generated target or build output.
- Declare the Java release and dependency versions in the build.
- Packaging a plain JAR does not automatically create an executable manifest.
- Continue with JUnit tests when these examples are clear.
Java Examples
Each example shows the code, the output it produces and what each part does.
Define a minimal Maven build
Use the following xml commands or configuration.
What to expect: mvn package creates target/label-app-1.0.0.jar after a successful build.
Save this configuration as pom.xml at the project root. The artifact filename derives from artifactId and version. The compiler plugin reads the release property, and UTF-8 gives source decoding a stated convention. Place the Java source in src/main/java before building. The XML does not define an executable main-class manifest, so java -jar is not automatically the correct launch command for this plain JAR.
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>label-app</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build><plugins><plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version>
</plugin></plugins></build>
</project>Add source in the conventional location
Save this program as BuildLabel.java. Compile it with javac BuildLabel.java and run it with java BuildLabel.
Expected output:
For the Maven project, save this source as src/main/java/BuildLabel.java. The same small program also compiles directly with javac, which helps separate Java logic from build configuration. After mvn package, run java -cp target/label-app-1.0.0.jar BuildLabel. The JAR supplies the classpath entry, and BuildLabel supplies the entry point. An IDE can invoke the same build, but the terminal command remains a repeatable reference.
public class BuildLabel {
public static void main(String[] args) {
System.out.println("Build verified");
}
}Build verifiedRun and inspect the build
Use the following shell commands or configuration.
What to expect: The build succeeds, then the application prints Build verified.
mvn -version reveals both Maven and the Java installation Maven uses. clean removes prior generated output, reducing confusion from stale class files. package rebuilds and assembles the JAR. The final command launches its class through an explicit classpath rather than depending on an unstated manifest. Dependency and plugin downloads require repository access on the first uncached build; later runs may use the local cache.
mvn -version
mvn clean package
java -cp target/label-app-1.0.0.jar BuildLabelJava FAQ
Does Maven include a JDK?
No. Maven needs a suitable Java installation and compiler for Java builds. Check mvn -version and the configured release rather than assuming installing the build tool installs every required JDK.
Should target or build be committed?
Normally no. These directories contain generated output that the build can recreate. Commit source, build configuration, necessary wrapper files, and documented inputs; exclude generated output and caches with suitable ignore rules.
Should I learn Maven or Gradle first?
Either is fine; the concepts of dependencies, tasks and the standard folder layout carry over. Maven's XML is very predictable and common in enterprise projects, while Gradle is the standard for Android and popular for new projects. Learn whichever your course, job or chosen framework uses.
What are mvnw and gradlew?
They are wrapper scripts committed to the project. Running ./mvnw test or ./gradlew test downloads the exact build tool version the project expects, so everyone, including the CI server, builds with the same version without installing it separately.
Where are downloaded dependencies stored?
Maven keeps them in a local repository, normally .m2/repository in your home folder, and Gradle uses .gradle/caches. Libraries are downloaded once and shared by all your projects, which is why the first build is slower than the next ones.
Java Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Where does Maven normally compile main Java source from?
Which lifecycle phase creates the configured artifact?
Java Quiz
2 questions to check what you learned.
What does a test-scoped dependency describe?
- A library needed for test compilation and execution
- A guaranteed production runtime dependency
- An operating-system installer
Why use a project wrapper?
- To invoke a documented build-tool version
- To remove the need for Java
- To include all source in one class