Skip to content

Commit 007e56c

Browse files
committed
fix(java): resolve the bundled JDK via Adoptium /binary/version (the /assets/version endpoint 404s)
ensure_jdk resolved the Temurin JVM through the Adoptium /assets/version/{release} endpoint, which now returns 404 for pinned releases (e.g. jdk-21.0.5+11) even though the release exists — so the first Java analysis on a clean machine failed before it started. Resolve via /binary/version/... instead (capture the 307 redirect to the GitHub asset without downloading the binary) and read the checksum from the asset's adjacent .sha256.txt. Verified end-to-end: download + checksum + extract yields a JAVA_HOME with bin/java and jmods (openjdk 21.0.5).
1 parent 53aa1fd commit 007e56c

2 files changed

Lines changed: 38 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7777
to `2.4.0` (adds the Neo4j graph emitter).
7878
- Optional `neo4j` extra (`pip install cldk[neo4j]`) for the Neo4j Python driver.
7979

80+
### Fixed
81+
- **Bundled JDK download for the Java backend.** `ensure_jdk` resolved the Temurin JVM via the
82+
Adoptium `/assets/version/{release}` endpoint, which now returns 404 for pinned releases (e.g.
83+
`jdk-21.0.5+11`) — so the first Java analysis on a clean machine failed before it started. It now
84+
resolves via the `/binary/version/...` endpoint (following the redirect to the GitHub asset) and
85+
reads the checksum from the asset's `.sha256.txt`.
86+
8087
## [v1.0.7] - 2026-02-14
8188

8289
### Added

cldk/analysis/java/codeanalyzer/_jdk.py

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,13 @@
3636
from __future__ import annotations
3737

3838
import hashlib
39-
import json
4039
import logging
4140
import os
4241
import platform
4342
import stat
4443
import tarfile
44+
import urllib.error
45+
import urllib.parse
4546
import urllib.request
4647
import zipfile
4748
from pathlib import Path
@@ -70,20 +71,36 @@ def _os_arch(cls) -> tuple[str, str]:
7071

7172
@classmethod
7273
def _resolve_asset(cls) -> tuple[str, str]:
73-
"""Return ``(download_url, sha256)`` for the pinned JDK binary."""
74+
"""Return ``(download_url, sha256)`` for the pinned JDK binary.
75+
76+
Resolves via the Adoptium ``/binary/version`` endpoint, which 307-redirects to the
77+
GitHub release asset; the checksum comes from the asset's adjacent ``.sha256.txt``. The
78+
older ``/assets/version/{release}`` query endpoint is not used: it returns 404 for pinned
79+
releases (e.g. ``jdk-21.0.5+11``), even though the release exists.
80+
"""
7481
os_, arch = cls._os_arch()
75-
url = (
76-
f"{cls._API}/assets/version/{JDK_RELEASE}"
77-
f"?os={os_}&architecture={arch}&image_type=jdk"
78-
f"&jvm_impl=hotspot&heap_size=normal&vendor=eclipse"
79-
)
80-
req = urllib.request.Request(url, headers={"User-Agent": "cldk"})
81-
with urllib.request.urlopen(req, timeout=30) as resp:
82-
data = json.load(resp)
83-
if not data:
84-
raise RuntimeError(f"No Temurin {JDK_RELEASE} build for {os_}/{arch}")
85-
pkg = data[0]["binaries"][0]["package"]
86-
return pkg["link"], pkg["checksum"]
82+
release = urllib.parse.quote(JDK_RELEASE, safe="") # encode the '+' in the path
83+
binary_url = f"{cls._API}/binary/version/{release}/{os_}/{arch}/jdk/hotspot/normal/eclipse"
84+
85+
# Capture the redirect target (the GitHub asset URL) without downloading the binary.
86+
class _NoRedirect(urllib.request.HTTPRedirectHandler):
87+
def redirect_request(self, *args, **kwargs):
88+
return None
89+
90+
opener = urllib.request.build_opener(_NoRedirect)
91+
req = urllib.request.Request(binary_url, headers={"User-Agent": "cldk"})
92+
try:
93+
opener.open(req, timeout=30)
94+
raise RuntimeError(f"Expected a redirect to the Temurin {JDK_RELEASE} asset from {binary_url}")
95+
except urllib.error.HTTPError as exc:
96+
if exc.code not in (301, 302, 303, 307, 308) or not exc.headers.get("Location"):
97+
raise RuntimeError(f"No Temurin {JDK_RELEASE} build for {os_}/{arch} (HTTP {exc.code})") from exc
98+
asset_url = exc.headers["Location"]
99+
100+
sha_req = urllib.request.Request(asset_url + ".sha256.txt", headers={"User-Agent": "cldk"})
101+
with urllib.request.urlopen(sha_req, timeout=30) as resp:
102+
sha = resp.read().decode().split()[0]
103+
return asset_url, sha
87104

88105
@classmethod
89106
def _java_home(cls, root: Path) -> Path:

0 commit comments

Comments
 (0)