From 65501a08ef0502da390ad3d17b3690cb10db65cf Mon Sep 17 00:00:00 2001 From: Danish Nawab Date: Wed, 16 Sep 2026 10:32:20 +0200 Subject: [PATCH 1/2] Oracle OpenJDK: pick up release status changes of known packages Oracle serves release candidates from the final GA location on download.java.net, so filename and download link of a build do not change when jdk.java.net switches the page from "Release-Candidate" to GA. The incremental update skipped every known filename/link pair and therefore never re-evaluated the release status, leaving the GA build labelled as early access (JDK 27 build 35 is reported as 27-ea+35, see #162). The check now also compares the release status, computed with the same rules the package would be stored with (GA link, release candidate page, GA date not reached yet), and re-emits the package when it differs. The pkg id is the MD5 of the download link, so the existing record is updated in place. --- .../foojay/api/distribution/OracleOpenJDK.java | 9 ++++++--- src/main/java/io/foojay/api/util/Helper.java | 17 +++++++++-------- .../java/io/foojay/api/util/HelperTest.java | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/main/java/io/foojay/api/distribution/OracleOpenJDK.java b/src/main/java/io/foojay/api/distribution/OracleOpenJDK.java index 750d958..dcc10ea 100644 --- a/src/main/java/io/foojay/api/distribution/OracleOpenJDK.java +++ b/src/main/java/io/foojay/api/distribution/OracleOpenJDK.java @@ -972,13 +972,16 @@ private List extractPackagesFromHtml(final String html, final boolean isRel ArchiveType archiveType = Helper.getFileEnding(filename); TermOfSupport termOfSupport = Helper.getTermOfSupport(versionNumber); ReleaseStatus releaseStatus = (href.contains("/GA/") || href.contains("/ga/")) ? ReleaseStatus.GA : ReleaseStatus.EA; - if (isReleaseCandidate) { releaseStatus = EA; } + if (isReleaseCandidate || Helper.isTooEarlyForGA(versionNumber.getFeature().getAsInt())) { releaseStatus = EA; } String downloadLink = href.replaceAll("\"", "").replace("href=", ""); - String checksumUri = Helper.isUriValid(downloadLink + ".sha256") ? downloadLink + ".sha256" : ""; + // Oracle serves release candidates from the final GA location, so filename and download link + // stay the same when the build becomes GA. Only skip a known pkg if its release status is unchanged too. if (onlyNewPkgs) { - if (CacheManager.INSTANCE.pkgCache.getPkgs().stream().filter(p -> p.getFilename().equals(filename)).filter(p -> p.getDirectDownloadUri().equals(downloadLink)).count() > 0) { continue; } + final ReleaseStatus statusFound = releaseStatus; + if (CacheManager.INSTANCE.pkgCache.getPkgs().stream().filter(p -> p.getFilename().equals(filename)).filter(p -> p.getDirectDownloadUri().equals(downloadLink)).anyMatch(p -> p.getReleaseStatus() == statusFound)) { continue; } } + String checksumUri = Helper.isUriValid(downloadLink + ".sha256") ? downloadLink + ".sha256" : ""; BUILD_NUMBER_MATCHER.reset(downloadLink); while(BUILD_NUMBER_MATCHER.find()) { diff --git a/src/main/java/io/foojay/api/util/Helper.java b/src/main/java/io/foojay/api/util/Helper.java index b5fcde0..f732219 100644 --- a/src/main/java/io/foojay/api/util/Helper.java +++ b/src/main/java/io/foojay/api/util/Helper.java @@ -857,15 +857,16 @@ public static final String getReleaseDetailsUrl(final Semver semver) { return releaseDetailsUrl; } + public static final boolean isTooEarlyForGA(final int featureVersion) { + final LocalDate gaDate = Constants.GA_RELEASE_DATES.get(featureVersion); + return null != gaDate && gaDate.isAfter(LocalDate.now()); + } + public static final void checkPkgsForTooEarlyGA(final List pkgs) { - final LocalDate now = LocalDate.now(); - Constants.GA_RELEASE_DATES.entrySet() - .stream() - .filter(entry -> entry.getValue().isAfter(now)) - .forEach(entry -> pkgs.stream() - .filter(pkg -> pkg.getMajorVersion().getAsInt() == entry.getKey()) - .filter(pkg -> pkg.getReleaseStatus() == ReleaseStatus.GA) - .forEach(pkg -> pkg.setReleaseStatus(ReleaseStatus.EA))); + pkgs.stream() + .filter(pkg -> pkg.getReleaseStatus() == ReleaseStatus.GA) + .filter(pkg -> isTooEarlyForGA(pkg.getMajorVersion().getAsInt())) + .forEach(pkg -> pkg.setReleaseStatus(ReleaseStatus.EA)); } public static final Optional getMaxVersionNumber(final BuildScope buildScope, final Integer jdkVersion, final boolean includeEa) { diff --git a/src/test/java/io/foojay/api/util/HelperTest.java b/src/test/java/io/foojay/api/util/HelperTest.java index ef93406..e1beb00 100644 --- a/src/test/java/io/foojay/api/util/HelperTest.java +++ b/src/test/java/io/foojay/api/util/HelperTest.java @@ -22,6 +22,7 @@ import eu.hansolo.jdktools.PackageType; import org.junit.jupiter.api.Test; +import java.time.LocalDate; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -170,4 +171,21 @@ public void isPositiveIntegerTest() { final String numberString3 = "text"; assert !Helper.isPositiveInteger(numberString3); } + + @Test + public void tooEarlyForGATest() { + final int futureVersion = 9001; + final int pastVersion = 9002; + final int unknownVersion = 9003; + Constants.GA_RELEASE_DATES.put(futureVersion, LocalDate.now().plusDays(1)); + Constants.GA_RELEASE_DATES.put(pastVersion, LocalDate.now()); + try { + assert Helper.isTooEarlyForGA(futureVersion); + assert !Helper.isTooEarlyForGA(pastVersion); + assert !Helper.isTooEarlyForGA(unknownVersion); + } finally { + Constants.GA_RELEASE_DATES.remove(futureVersion); + Constants.GA_RELEASE_DATES.remove(pastVersion); + } + } } From 7021e6add54c8b1e509d4daa261f61d574a352ed Mon Sep 17 00:00:00 2001 From: Danish Nawab Date: Wed, 16 Sep 2026 10:42:15 +0200 Subject: [PATCH 2/2] Keep checksumUri in place, tighten comment, format the dedupe chain --- .../java/io/foojay/api/distribution/OracleOpenJDK.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/foojay/api/distribution/OracleOpenJDK.java b/src/main/java/io/foojay/api/distribution/OracleOpenJDK.java index dcc10ea..3938124 100644 --- a/src/main/java/io/foojay/api/distribution/OracleOpenJDK.java +++ b/src/main/java/io/foojay/api/distribution/OracleOpenJDK.java @@ -974,14 +974,16 @@ private List extractPackagesFromHtml(final String html, final boolean isRel ReleaseStatus releaseStatus = (href.contains("/GA/") || href.contains("/ga/")) ? ReleaseStatus.GA : ReleaseStatus.EA; if (isReleaseCandidate || Helper.isTooEarlyForGA(versionNumber.getFeature().getAsInt())) { releaseStatus = EA; } String downloadLink = href.replaceAll("\"", "").replace("href=", ""); + String checksumUri = Helper.isUriValid(downloadLink + ".sha256") ? downloadLink + ".sha256" : ""; - // Oracle serves release candidates from the final GA location, so filename and download link - // stay the same when the build becomes GA. Only skip a known pkg if its release status is unchanged too. + // Oracle keeps filename and download link when a release candidate becomes GA, only the release status changes if (onlyNewPkgs) { final ReleaseStatus statusFound = releaseStatus; - if (CacheManager.INSTANCE.pkgCache.getPkgs().stream().filter(p -> p.getFilename().equals(filename)).filter(p -> p.getDirectDownloadUri().equals(downloadLink)).anyMatch(p -> p.getReleaseStatus() == statusFound)) { continue; } + if (CacheManager.INSTANCE.pkgCache.getPkgs().stream() + .filter(p -> p.getFilename().equals(filename)) + .filter(p -> p.getDirectDownloadUri().equals(downloadLink)) + .anyMatch(p -> p.getReleaseStatus() == statusFound)) { continue; } } - String checksumUri = Helper.isUriValid(downloadLink + ".sha256") ? downloadLink + ".sha256" : ""; BUILD_NUMBER_MATCHER.reset(downloadLink); while(BUILD_NUMBER_MATCHER.find()) {