14 - Anatomy of a Java OSS Repo¶
What this session is¶
About 45 minutes. Walk through the file layout of a real Java OSS project, file by file. By the end you can predict where things live in any project.
Typical small Java project layout¶
.
├── README.md
├── LICENSE
├── CONTRIBUTING.md
├── CODE_OF_CONDUCT.md
├── pom.xml (Maven) or build.gradle.kts (Gradle)
├── mvnw / mvnw.cmd (Maven Wrapper - bundled mvn launcher)
├── .gitignore
├── .github/
│ ├── workflows/
│ ├── ISSUE_TEMPLATE/
│ └── PULL_REQUEST_TEMPLATE.md
├── src/
│ ├── main/
│ │ ├── java/com/example/myapp/
│ │ │ ├── App.java
│ │ │ ├── core/
│ │ │ └── util/
│ │ └── resources/
│ │ ├── application.yml
│ │ └── log4j2.xml
│ └── test/
│ ├── java/com/example/myapp/
│ │ ├── AppTest.java
│ │ └── core/
│ └── resources/
└── target/ (Maven build output - gitignored)
Not every project has every piece. The roles are consistent.
What each piece is for¶
Root-level files¶
README.md- homepage. One-line description, install/usage, smallest example.LICENSE- Apache 2.0, MIT, GPL, BSD most common in Java OSS.CONTRIBUTING.md- most important file for you. Conventions, PR process, dev setup.CODE_OF_CONDUCT.md- community standards.pom.xml(Maven) orbuild.gradle.kts(Gradle) - build manifest.mvnw/mvnw.cmd- Maven Wrapper. Use./mvnwinstead ofmvnto use the project's pinned Maven version.gradlew/gradlew.bat- Gradle Wrapper, same idea..editorconfig- editor settings (tabs/spaces, line endings)..gitignore- files git should ignore (target/,.idea/,*.class).
.github/¶
workflows/*.yml- GitHub Actions CI. Reading them tells you exactly what your PR will be measured against.ISSUE_TEMPLATE/- issue templates.PULL_REQUEST_TEMPLATE.md- what GitHub pre-fills in PR description.
src/main/java/¶
The production code. Subfolders match package structure (com.example.myapp → com/example/myapp/).
src/main/resources/¶
Non-Java files bundled with the artifact: config files (application.yml, application.properties), templates, static assets, log config (log4j2.xml).
src/test/java/¶
Tests, mirroring main's package structure. JUnit picks them up automatically; Maven runs them during mvn test.
src/test/resources/¶
Test-only resources: fixture files, mock data, test config.
target/¶
Build output. JARs, compiled classes, generated sources, reports. Always gitignored.
Worked walkthrough: a hypothetical small library¶
Imagine a project string-utils you've just cloned. Five-minute orientation:
- README.md -
string-utils provides a few string helpers Apache Commons doesn't include. pom.xml- open it: No third-party runtime deps - quality signal.src/main/java/- find it:Public API:src/main/java/com/example/strings/ ├── package-info.java ├── Pluralizer.java ├── Titlecase.java └── internal/ └── Helpers.javaPluralizer,Titlecase. Internal:Helpers(package-private or in aninternalpackage).src/test/java/- same structure, withTestsuffix:.github/workflows/- open one: So CI runs./mvnw verify- that's the command to replicate locally.
Five minutes; you have a map.
Conventions from CONTRIBUTING.md¶
Open the file. Look for:
- Setup instructions. Usually
mvn installor./mvnw install. - Tests. Usually
mvn testor./mvnw test. - Code style. Often "run
mvn spotless:apply" to auto-format. Or "use the supplied IntelliJ config in.editorconfig". - Commit message format. Some require Conventional Commits; most don't.
- PR template. Address every checkbox.
- DCO / CLA. Some projects need signed commits (
git commit -s) or CLA signing. - Branch naming. Some require
fix/issue-123, etc.
Follow them. The maintainers will be relieved.
CI configuration: what your PR will be measured against¶
Open a workflow under .github/workflows/. A typical Java CI:
name: CI
on: [push, pull_request]
jobs:
test:
strategy:
matrix:
java: [17, 21]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: ${{ matrix.java }}
- run: ./mvnw verify
Read it:
- Runs on every push and PR.
- Tests on Java 17 and 21.
- Setup: Temurin JDK.
- Command: ./mvnw verify (verify = compile + test + sanity checks).
Run ./mvnw verify locally. If it passes, your PR will (probably) pass CI.
Common helper tools¶
You'll see these in real Java projects:
- Spotless - auto-formatting (Google Java Format, Palantir Java Format, Eclipse Code Style).
mvn spotless:applyformats;mvn spotless:checkfails CI on unformatted code. - Checkstyle / PMD - style/correctness checkers.
- SpotBugs - finds bugs via static analysis.
- Jacoco - code coverage reports.
- Maven Enforcer - fails the build on rule violations (e.g., banned dependencies, wrong Java version).
The CI workflow will mention which are used.
Exercise¶
Use the project you picked in page 13.
- Clone locally.
- Walk the layout. Map each file/folder to the categories above.
- Read
CONTRIBUTING.mdend to end. - Open one CI workflow YAML. Identify the commands.
- Run those commands locally:
- Open the issue you tentatively picked. Identify the three files most likely involved (use
grepand your guess).
Now you're ready to actually make a change.
What you might wonder¶
"What if a project uses Gradle, not Maven?"
./gradlew build or ./gradlew test. Same idea, different syntax in the build file.
"What's a bom artifact?"
Bill of Materials - a POM whose only job is to declare versions of related artifacts. You import it in <dependencyManagement>; then you can list dependencies without versions (they come from the BOM). Common in Spring (spring-boot-dependencies), Jackson (jackson-bom).
"What's module-info.java if I see it?"
JPMS module descriptor (page 11). Recognize it; rarely needs editing for a first contribution.
Done¶
- Recognize the typical Java project layout.
- Locate every common file/folder by role.
- Read CONTRIBUTING.md and CI workflows.
- Make a confident guess at which files a change will touch.
Next: Your first contribution →