Skip to content

Repository files navigation

l-java

A learning Java project with production-grade tooling.

Tooling

ToolPurpose
Gradle 9 + Kotlin DSLBuild system with version catalog
Spotless + Palantir formatterOpinionated code formatting
Checkstyle 10Style and complexity rules
Error ProneCompile-time bug detection
NullAway (JSpecify mode)Null-safety enforced at compile time
NopenEvery class must be final, abstract, or @Open
SpotBugsBytecode-level bug detection
JUnit 5 + MockitoTesting
JaCoCoCoverage, gated at a 70% line floor (overridable per module)
Qodana (qodana-jvm-community)IntelliJ data-flow analysis via the LJava severity-laddered inspection profile

Running

./gradlew build # compile + test
./gradlew spotlessApply # auto-format code
./gradlew checkstyleMain # run checkstyle
./gradlew dependencyUpdates # check for newer dependency versions

CI gates

What fails the build:

  • Compile-Werror (all lint categories except processing, serial, classfile).
  • Tests — JUnit 5, run via ./gradlew test.
  • Checkstyle — zero warnings allowed (maxWarnings = 0).
  • SpotBugs — advisory by default (ignoreFailures = true); a module opts into a hard gate by setting extra["strictSpotbugs"] = true.
  • Coverage — JaCoCo line-coverage floor, 70% by default (see table above).
  • QodanaERROR-tier inspections only (.idea/inspectionProfiles/LJava.xml via qodana.yaml); findings also land in the GitHub Security tab as SARIF.
  • CodeQL — default query suite, java-kotlin, on push/PR to main plus a weekly scan.
  • Dependency review — fails a PR that introduces a high-or-worse severity vulnerability.

Portability note (2026-07-31): CodeQL and Dependency review are GitHub-hosted Actions (github/codeql-action, actions/dependency-review-action) and don't work as-is on a self-hosted Forgejo runner that can't execute GitHub Marketplace uses: steps (confirmed against scircle/stock-analysis's Forgejo CI, which had to replace even actions/setup-java with inline installs for this reason). If backporting this repo's CI gates to a Forgejo-hosted repo, use an inline-installed equivalent instead — e.g. stock-analysis's supply-chain.yml runs a curl-downloaded Trivy fs scan plus Renovate via docker run, no marketplace actions at all.

Key Concepts

Closed-world classes (Nopen)

Every class must declare its extensibility intent:

  • final class — cannot be subclassed (default for everything)
  • abstract class — designed for extension
  • @Open class — explicitly open (needed for CGLIB proxying, etc.)

Null safety (NullAway + JSpecify)

The @NullMarked annotation on package-info.java means all reference types in the package are non-null by default. Annotate with @Nullable only where null is genuinely part of the contract.

Money as a value object

Money demonstrates: immutability, value-based equality, defensive validation, and arithmetic with proper rounding (banker's rounding / HALF_EVEN).

About

Sample Java Project

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages