Build Tools & Best Practices

Beyond single files, real Java projects use a build tool to compile code, download libraries, run tests and package the result. This lesson introduces Maven and Gradle, the standard project layout, how to run a packaged application — and the habits that make Java code clean and maintainable.

Standard project layout

TXT layout
my-shop/
├── pom.xml (or build.gradle.kts)
└── src/
    ├── main/
    │   ├── java/com/example/shop/App.java
    │   └── resources/application.properties
    └── test/
        └── java/com/example/shop/AppTest.java

Both Maven and Gradle use this layout: application code in src/main/java, non-code files in src/main/resources, and tests in src/test/java. IDEs understand it automatically.

Maven

TXT pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>my-shop</artifactId>
  <version>1.0.0</version>

  <properties>
    <maven.compiler.release>25</maven.compiler.release>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>5.13.4</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
$
mvn compile      # compile main code
mvn test         # compile and run tests
mvn package      # build target/my-shop-1.0.0.jar

Maven describes a project in an XML file, pom.xml. Each dependency is identified by group, artifact and version, and downloaded automatically from Maven Central along with everything it depends on.

Gradle

TXT build.gradle.kts
plugins {
    application
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter:5.13.4")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

java {
    toolchain { languageVersion = JavaLanguageVersion.of(25) }
}

application {
    mainClass = "com.example.shop.App"
}

tasks.test { useJUnitPlatform() }
$
./gradlew build   # compile, test and package
./gradlew run     # run the application

Gradle uses a Kotlin (or Groovy) build script, is fast thanks to incremental builds and caching, and is the default for Android. The gradlew "wrapper" script downloads the right Gradle version, so everyone builds the same way. Use whichever your team uses — the concepts are the same. Library versions above are examples; check for current ones when you start a project.

Running a JAR

$
java -jar target/my-shop-1.0.0.jar
java -cp target/classes com.example.shop.App

A JAR (Java ARchive) is a zip file of compiled classes and resources. Frameworks like Spring Boot package everything, including dependencies, into a single runnable JAR; container images and native compilation (GraalVM) are other common deployment options.

Popular libraries and frameworks

NeedCommon choices
Web applications and APIsSpring Boot, Quarkus, Micronaut, Helidon, Javalin
DatabasesJDBC, Spring Data JPA / Hibernate, jOOQ, Flyway or Liquibase for migrations
JSONJackson, Gson
TestingJUnit, AssertJ, Mockito, Testcontainers
LoggingSLF4J with Logback or Log4j 2
HTTP clientThe built-in java.net.http.HttpClient

Writing good Java

  • Name things clearly and follow the conventions from lesson 4.
  • Keep methods small and focused on one job; keep classes cohesive.
  • Prefer immutability: final fields, records, List.of, List.copyOf.
  • Program to interfaces (List, not ArrayList) and inject dependencies.
  • Favour composition over inheritance.
  • Avoid null in return values; use empty collections and Optional.
  • Validate early and throw meaningful exceptions; never swallow them.
  • Close resources with try-with-resources.
  • Use the standard library before writing your own utilities.
  • Write tests, and let formatting and static analysis tools (Checkstyle, SpotBugs, Error Prone, your IDE's inspections) catch problems early.
  • Stay on a supported LTS version and keep dependencies updated.

Try it yourself

Code you'd typically organise into separate files — a record, a service and an entry point — written in one file here. Run it, then try splitting it into Product.java, Catalog.java and Main.java in one folder and running java Main.java again.

Try it yourself · Main.java
Edit the code, copy it into Main.java and run java Main.java (Java 25+). How to set up Java
Output
Ceramic Mug
not found