Side-by-side comparison of five Java HTTP clients (HttpURLConnection, java.net.http.HttpClient, Apache HttpClient 5, OkHttp, Retrofit) and four JSON-parsing approaches (tree model, simple data binding, full-schema data binding, path queries). Every implementation calls NASA's Near-Earth Objects (NEO) API with the same request and asserts the same response, so library trade-offs — ergonomics, dependency footprint, async support, schema handling — are directly visible.
flowchart LR
App["Example main() classes<br/>Java 25"]
NEO[("NASA NEO API<br/>api.nasa.gov")]
subgraph HTTPC["HTTP Clients"]
direction TB
HC1["HttpURLConnection (JDK)"]
HC2["java.net.http.HttpClient (JDK 11+)"]
HC3["Apache HttpClient 5.6.1"]
HC4["OkHttp 5.3.2"]
HC5["Retrofit 3.0.0"]
end
subgraph JSONP["JSON Parsers"]
direction TB
JP1["Jackson 3.1.3 (tree + databind)"]
JP2["Gson 2.14.0 (tree + databind)"]
JP3["JsonPath 3.0.0"]
JP4["Jackson JsonPointer 3.1.3"]
end
App --> HTTPC
HTTPC -->|"GET /neo/rest/v1/feed"| NEO
NEO -->|"JSON"| JSONP
JSONP --> App
Each main() class under src/main/java/ issues the same GET /neo/rest/v1/feed request via one of the five HTTP clients, then deserializes the response via one of the four JSON-parsing approaches. The grid lets you compare ergonomics, dependency footprint, async support, and schema handling side-by-side against an unchanging upstream call. Container labels carry library versions so the diagram tracks the Tech Stack table below.
| Component | Technology |
|---|---|
| Language | Java 25 LTS (Temurin via mise) |
| Build | Maven 3.9.15 (pinned via .mise.toml; enforcer allows 3.6.3+) |
| Tests | JUnit Jupiter 6.0.3 (unit) + WireMock 3.13.1 (integration via Failsafe *IT.java) |
| Coverage | JaCoCo (70% instruction + branch) |
| HTTP clients | java.net.HttpURLConnection, java.net.http.HttpClient, Apache HttpClient 5 5.6.1, OkHttp 5.3.2, Retrofit 3.0.0 |
| JSON | Jackson 3.1.3 (tools.jackson.core), Gson 2.14.0, JsonPath 3.0.0 |
| Formatting | google-java-format |
| Security | gitleaks, Trivy, OWASP dependency-check |
| CI | GitHub Actions; local replay via act |
| Automation | Renovate (platform automerge) |
make deps # auto-install mise + Java/Maven pinned in .mise.toml
make build # build the project
make test # run all tests
make ci # or run the full CI pipeline (static-check, test, coverage-check, build)| Tool | Version | Purpose |
|---|---|---|
| GNU Make | 3.81+ | Build orchestration |
| Git | 2.0+ | Version control, releases |
| JDK | 25+ | Java runtime and compiler (source: .java-version) |
| Maven | 3.6.3+ | Build and dependency management (3.9.15 pinned in .mise.toml) |
| mise | latest | Java/Maven version manager (auto-installed by make deps) |
| Docker | latest | Required by act for local CI |
| act | 0.2.87+ | Local CI runner for make ci-run (installed via make deps-act) |
Install everything:
make depsTwo independent module areas under src/main/java/:
| Implementation | Package | Notes |
|---|---|---|
| HttpURLConnection | java.net |
Core JDK, low-level |
| java.net.http.HttpClient | java.net.http |
Modern JDK (Java 11+), async-capable |
| Apache HttpClient 5 | org.apache.httpcomponents.client5 |
Long-standing library, fluent API |
| OkHttp | com.squareup.okhttp3 |
Square's HTTP stack |
| Retrofit | com.squareup.retrofit2 |
Type-safe REST over OkHttp, Gson converter |
Shared models live under http/client/model/.
| Approach | Package | Library |
|---|---|---|
| Tree model | jsonparse/treemodels/ |
Jackson JsonNode, Gson JsonElement |
| Data binding — simple | jsonparse/databinding/simple/ |
Jackson + Gson POJO mapping |
| Data binding — complex | jsonparse/databinding/complex/ |
Generated model classes (jackson/generated/, gson/generated/) |
| Path queries | jsonparse/pathqueries/ |
JsonPath + Jackson JsonPointer |
Each HTTP client and JSON-parsing approach has a matching *Test.java (Surefire, unit) and — where applicable — an *IT.java (Failsafe, WireMock-stubbed):
# run a single unit test
mvn -B test -Dtest=OkHttpDemoTest -Ddependency-check.skip=true
# run all WireMock-stubbed integration tests
make integration-testmake cve-check scans dependencies for known vulnerabilities using two data sources:
- NVD — NIST National Vulnerability Database. Without an API key, requests are rate-limited and the scan may fail with a 429 error.
- OSS Index — Sonatype's vulnerability database; provides additional coverage beyond NVD. Authentication is required — without credentials the analyzer is skipped.
export NVD_API_KEY=<nvd-api-key>
export OSS_INDEX_USER=<ossindex-account-email>
export OSS_INDEX_TOKEN=<ossindex-api-token>
make cve-checkBoth the NVD API key and OSS Index credentials are written to ~/.m2/settings.xml by the maven-settings-ossindex prerequisite of cve-check, then referenced by id (-DnvdApiServerId=nvd) — secret values never enter Maven's argv (visible to local users via ps -ef).
Listed below; make help prints the same list.
| Target | Description |
|---|---|
make build |
Build project (skips tests and OWASP dependency-check) |
make clean |
Cleanup |
| Target | Description |
|---|---|
make test |
Run project tests (unit, fast) |
make integration-test |
Run integration tests (WireMock-stubbed HTTP clients; *IT.java) |
make coverage-generate |
Generate JaCoCo coverage report |
make coverage-check |
Verify code coverage meets 70% threshold |
make coverage-open |
Open code coverage report |
| Target | Description |
|---|---|
make lint |
Validate project configuration and check compiler warnings |
make format |
Format Java sources with google-java-format |
make format-check |
Verify Java sources are formatted |
make secrets |
Scan repository for hardcoded secrets (gitleaks) |
make trivy-fs |
Filesystem vulnerability/secret/misconfig scan |
make mermaid-lint |
Validate Mermaid diagrams in Markdown (requires Docker) |
make static-check |
Composite fast quality gate (format-check + lint + secrets + trivy-fs + mermaid-lint + deps-prune-check) |
make cve-check |
Run OWASP dependency vulnerability scan |
make vulncheck |
Alias for cve-check |
| Target | Description |
|---|---|
make ci |
Run full CI pipeline (static-check, test, coverage-check, build) |
make ci-run |
Run GitHub Actions workflow locally using act |
| Target | Description |
|---|---|
make deps |
Check tools; auto-install mise (no root) and mise-pinned Java/Maven |
make deps-install |
Install Java and Maven via mise (reads .mise.toml) |
make deps-maven |
Install Maven into ~/.local (CI fallback) |
make deps-act |
Install act into ~/.local/bin |
make deps-gitleaks |
Install gitleaks into ~/.local/bin |
make deps-trivy |
Install trivy into ~/.local/bin |
make deps-docker |
Verify Docker is available (internal helper for mermaid-lint; skipped under act) |
make deps-check |
Show required tools and installation status |
make deps-prune |
Analyze declared-but-unused / used-but-undeclared dependencies |
make deps-prune-check |
Fail build on declared-but-unused dependencies |
| Target | Description |
|---|---|
make release VERSION=x.y.z |
Tag and push a release |
make maven-settings-ossindex |
Create Maven settings for OSS Index credentials |
make renovate-bootstrap |
Install mise + Node for Renovate |
make renovate-validate |
Validate Renovate configuration |
make help |
List available tasks |
GitHub Actions runs on every push to main, tags v*, pull requests, a weekly schedule (Monday 06:00 UTC for cve-check), and manual dispatch. The workflow also exposes workflow_call for reuse.
| Job | Triggers | Runs |
|---|---|---|
changes |
every event | dorny/paths-filter detector — gates heavy jobs so doc-only changes skip CI without deadlocking the ci-pass required check |
static-check |
after changes (when code changes) |
make static-check (format-check + lint + gitleaks + Trivy filesystem scan + mermaid-lint + deps-prune-check) |
test |
after changes + static-check |
make coverage-generate (tests + jacoco:report) then make coverage-check (70% threshold); uploads coverage-report artifact |
integration-test |
after changes + static-check |
make integration-test (WireMock-stubbed HTTP client tests) |
build |
after changes + static-check |
make build |
cve-check |
tags v*, weekly schedule, manual dispatch |
make cve-check with cached NVD database (uploads cve-report artifact) |
ci-pass |
after all of the above | Single gate for branch protection |
Pipeline: changes → static-check → test + integration-test + build (parallel); cve-check runs on release tags, the weekly schedule, and manual dispatch. ci-pass aggregates every required job so branch protection needs only one check, and treats skipped jobs (doc-only PRs) as success.
| Secret | Required by | Purpose |
|---|---|---|
NVD_API_KEY |
cve-check |
Avoid NVD rate limits — request one |
OSS_INDEX_USER |
cve-check |
OSS Index account email — register |
OSS_INDEX_TOKEN |
cve-check |
OSS Index API token from account settings |
Set secrets via Settings > Secrets and variables > Actions > New repository secret.
Renovate keeps dependencies up to date with platform automerge enabled.
Contributions welcome — open a PR. Review routing is configured via CODEOWNERS.
Released under the MIT License.