This is a modern GitHub template repository for Java projects. Use this template to create a new Java application with a standardized structure, automated tooling, and best practices built-in.
- β Modern Java: Java 25 LTS via a Gradle toolchain, so local builds and CI compile against the exact same JDK.
- π Gradle with the Kotlin DSL: Type-safe build scripts, a committed wrapper, and all dependency versions declared once in a version catalog.
- π Bug Detection at Compile Time: Error Prone plus NullAway turn whole classes of runtime failures β
including
NullPointerExceptionβ into compile errors. - π¨ Zero-Debate Formatting: Spotless with
palantir-java-formatformats Java, Gradle, and misc files. - π§ͺ Tests and Coverage: JUnit 5 with AssertJ assertions, and JaCoCo enforcing a coverage floor as part
of
check. - π§ Modern Tooling: Pre-configured with mise for tool and task management, Lefthook for Git hooks, Cocogitto for Conventional Commits, and act for local CI simulation.
- π¦ Single-File Distribution: A shaded, runnable
bin/app.jarbuilt by the Shadow plugin.
- mise - A multi-language version manager and task runner.
- Java - JDK 25 (managed by mise).
- act - Run your GitHub Actions locally.
-
Clone the repository:
git clone https://github.com/tabmadi/java-template.git cd java-template -
Setup environment:
# Install all required tools using mise mise install # Set up the project (download dependencies and install git hooks) mise run setup
Instructions on how to run the project.
# Run the application directly (development)
mise run run
# Build and run the production jar
mise run build
java -jar bin/app.jar| Script | Description |
|---|---|
mise run setup |
Set up the project dependencies |
mise run clean |
Clean build artifacts |
mise run format |
Format the code (Spotless) |
mise run lint |
Run Spotless checks and compile with Error Prone |
mise run test |
Run tests and verify coverage |
mise run check |
Format, lint, and test |
mise run build |
Build the shaded jar into bin/app.jar |
mise run run |
Run the application |
mise run start |
Build, then run the jar |
mise run act |
Simulate CI locally with act |
Formatting is handled by Spotless, and correctness by Error Prone + NullAway, which run as part of every
compilation. Warnings are errors (-Xlint:all -Werror), so the build fails on anything the compiler flags.
# Check formatting and compile with all static analysis enabled
mise run lint
# Auto-format the code
mise run formatTests use JUnit 5 with AssertJ assertions. JaCoCo enforces a line coverage floor of 80% (excluding the
entry point); the HTML report lands in build/reports/jacoco/test/html/index.html.
mise run testThis project uses Lefthook for Git hooks and follows Conventional Commits.
- Pre-commit: Formats code and runs the linters.
- Commit-msg: Validates commit message format.
- Pre-push: Final Conventional Commits check on the whole branch.
# β
Valid commit messages
git commit -m "feat: add user authentication"
git commit -m "fix: resolve memory leak".
βββ src/
β βββ main/
β β βββ java/ # Application code
β β βββ resources/ # application.conf, logback.xml
β βββ test/java/ # Tests
βββ gradle/
β βββ libs.versions.toml # Dependency version catalog
β βββ wrapper/ # Gradle wrapper
βββ scripts/ # Helper scripts
βββ bin/ # Built jar (created by build)
βββ .github/ # GitHub Actions and act configuration
βββ build.gradle.kts # Build configuration
βββ mise.toml # Mise configuration
βββ README.md # You are here! π
| File | Purpose | Key Features |
|---|---|---|
| mise.toml | Mise task runner | Tool versions, task definitions |
| build.gradle.kts | Gradle build | Toolchain, Spotless, Error Prone, NullAway, JaCoCo, Shadow |
| gradle/libs.versions.toml | Version catalog | Single source of truth for dependency versions |
| .lefthook.yml | Git hooks | Pre-commit linting, automated quality checks |
| src/main/resources/application.conf | App config | HOCON defaults with environment variable overrides |
Application settings are read with Typesafe Config into a typed AppConfig
record. Every key in application.conf can be overridden by an environment variable β see .env.example.
Contributions are welcome! Please follow these steps:
- Fork the project
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (Conventional Commits)
- Push to the branch
- Open a Pull Request
Please see SECURITY.md for our security policy and how to report security vulnerabilities.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- Temurin for the JDK builds
- Gradle for the build system
- Spotless and palantir-java-format for formatting
- Error Prone and NullAway for compile-time bug detection
- mise for tool and task management
- Lefthook for fast and reliable Git hooks
- act for local CI simulation
Happy coding! π If you find this template useful, please give it a βοΈ