diff --git a/README.md b/README.md index e90b36d..087909e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Java plugin for [vfox](https://vfox.dev/). -It installs JDKs from 18 distributions, among them Temurin, Zulu, Liberica, Corretto, Microsoft and GraalVM, looked up through [Foojay](https://foojay.io/). On Linux loong64 it installs from the Loongnix archive instead. +It installs JDKs from 31 distributions, among them Temurin, Zulu, Liberica, Corretto, Microsoft and GraalVM, looked up through [Foojay](https://foojay.io/). On Linux loong64 it installs from the Loongnix archive instead. ## Install @@ -32,6 +32,8 @@ java -version `vfox search java tem` lists the Temurin releases, and in an interactive terminal it lets you pick one and installs it. +Behavior that only exists on `main` and not in the latest release is marked "Unreleased" in the pages below. [docs/changes.md](docs/changes.md) lists it, and [docs/install-from-source.md](docs/install-from-source.md) gets you `main`. + ## Versions and names A version is `-`, such as `21.0.8-tem`, with `-fx` after it for JavaFX. Without a distribution you get OpenJDK from jdk.java.net, which has nothing newer than 17.0.2 for 17 and 21.0.2 for 21. See [docs/versions.md](docs/versions.md) for details. @@ -58,13 +60,23 @@ A version is `-`, such as `21.0.8-tem`, with `-fx` after | `mandrel` | Mandrel (Red Hat) | | `jb` | JetBrains Runtime | | `trava` | TravaOpenJDK | +| `adpt`, `adptj9` | AdoptOpenJDK with HotSpot, with OpenJ9 | +| `eliya` | Eliya JDK (Asymm Systems) | +| `ojdkbld` | OJDKBuild | +| `opnlgc` | OpenLogic OpenJDK | +| `rdht` | Red Hat build of OpenJDK | +| `semcrt` | Semeru, certified edition (IBM) | +| `gln` | Gluon GraalVM | +| `grl8`, `grl11`, `grl16`, `grl17`, `grl19` | GraalVM CE for JDK 8 to 19 | | `lnxabi1`, `lnxabi2` | Loongnix, Linux loong64 only | -See [docs/distributions.md](docs/distributions.md) for what each one is, and [docs/loongnix.md](docs/loongnix.md) for the last row. +Unreleased: release 0.6.2 has the rows up to `trava`, and the Loongnix one. + +The short names follow SDKMAN's identifiers, with a few differences: SDKMAN calls JetBrains Runtime `jbr`, and it wrote the virtual machine or JDK of AdoptOpenJDK and GraalVM CE into the version (`11.0.10.j9-adpt`, `22.3.3.r17-grl`), where the plugin has a name for each (`adptj9`, `grl17`). Eliya, OJDKBuild, OpenLogic, Red Hat and Semeru certified have no SDKMAN identifier, so their short names are the plugin's own. See [docs/distributions.md](docs/distributions.md) for all the differences and for what each distribution is, and [docs/loongnix.md](docs/loongnix.md) for the last row. ## Platforms -Not every distribution has builds for arm64, Alpine or Windows on ARM. Only Temurin, Zulu, Liberica, Microsoft and JetBrains Runtime have Windows ARM64 builds, 10 of the 18 have Alpine x64 builds and 7 have Alpine arm64. GraalVM has neither Windows ARM64 nor Alpine. See [docs/platforms.md](docs/platforms.md) for the table. +Not every distribution has builds for arm64, Alpine or Windows on ARM. Only Temurin, Zulu, Liberica, Microsoft and JetBrains Runtime have Windows ARM64 builds, 11 of the 31 have Alpine x64 builds and 7 have Alpine arm64. GraalVM has neither Windows ARM64 nor Alpine. See [docs/platforms.md](docs/platforms.md) for the table. ## JavaFX diff --git a/README_CN.md b/README_CN.md index ddfac6b..f4f530c 100644 --- a/README_CN.md +++ b/README_CN.md @@ -4,7 +4,7 @@ [vfox](https://vfox.dev/) 的 Java 插件。 -它通过 [Foojay](https://foojay.io/) 查找并安装 18 个发行版的 JDK,包括 Temurin、Zulu、Liberica、Corretto、Microsoft、GraalVM 等。在 Linux loong64 上,则改从 Loongnix 归档安装。 +它通过 [Foojay](https://foojay.io/) 查找并安装 31 个发行版的 JDK,包括 Temurin、Zulu、Liberica、Corretto、Microsoft、GraalVM 等。在 Linux loong64 上,则改从 Loongnix 归档安装。 ## 安装 @@ -32,6 +32,8 @@ java -version `vfox search java tem` 会列出 Temurin 的各个版本,在交互式终端里还可以直接选一个并安装。 +只存在于 `main`、还没进入最新发布版的行为,在下面各页里标有“未发布”。完整列表见 [docs/zh-CN/changes.md](docs/zh-CN/changes.md),想直接用上 `main`,见 [docs/zh-CN/install-from-source.md](docs/zh-CN/install-from-source.md)。 + ## 版本与命名 版本写成 `<版本>-<发行版>`,例如 `21.0.8-tem`,后面加 `-fx` 表示带 JavaFX。不写发行版时得到的是 jdk.java.net 上的 OpenJDK,它的 17 只到 17.0.2,21 只到 21.0.2。详见 [docs/zh-CN/versions.md](docs/zh-CN/versions.md)。 @@ -58,13 +60,23 @@ java -version | `mandrel` | Mandrel(Red Hat) | | `jb` | JetBrains Runtime | | `trava` | TravaOpenJDK | +| `adpt`、`adptj9` | AdoptOpenJDK,HotSpot 版和 OpenJ9 版 | +| `eliya` | Eliya JDK(Asymm Systems) | +| `ojdkbld` | OJDKBuild | +| `opnlgc` | OpenLogic OpenJDK | +| `rdht` | Red Hat build of OpenJDK | +| `semcrt` | Semeru 认证版(IBM) | +| `gln` | Gluon GraalVM | +| `grl8`、`grl11`、`grl16`、`grl17`、`grl19` | 基于 JDK 8 到 19 的 GraalVM CE | | `lnxabi1`、`lnxabi2` | Loongnix,仅限 Linux loong64 | -每个发行版是什么,见 [docs/zh-CN/distributions.md](docs/zh-CN/distributions.md);最后一行见 [docs/zh-CN/loongnix.md](docs/zh-CN/loongnix.md)。 +未发布:0.6.2 只有到 `trava` 为止的那些行,以及 Loongnix 那一行。 + +简称沿用 SDKMAN 的标识符,有几处不同:JetBrains Runtime 在 SDKMAN 里叫 `jbr`;AdoptOpenJDK 和 GraalVM CE 的虚拟机或 JDK 版本,SDKMAN 当时写在版本号里(`11.0.10.j9-adpt`、`22.3.3.r17-grl`),插件则给每种各起一个简称(`adptj9`、`grl17`)。Eliya、OJDKBuild、OpenLogic、Red Hat 和 Semeru 认证版在 SDKMAN 里没有标识符,简称是插件自己起的。全部差别以及每个发行版是什么,见 [docs/zh-CN/distributions.md](docs/zh-CN/distributions.md);最后一行见 [docs/zh-CN/loongnix.md](docs/zh-CN/loongnix.md)。 ## 平台 -并非每个发行版都有 arm64、Alpine 或 Windows ARM 的构建。只有 Temurin、Zulu、Liberica、Microsoft 和 JetBrains Runtime 有 Windows ARM64 的构建,18 个发行版里有 10 个有 Alpine x64 的构建,7 个有 Alpine arm64 的构建。GraalVM 既没有 Windows ARM64,也没有 Alpine。完整的表格见 [docs/zh-CN/platforms.md](docs/zh-CN/platforms.md)。 +并非每个发行版都有 arm64、Alpine 或 Windows ARM 的构建。只有 Temurin、Zulu、Liberica、Microsoft 和 JetBrains Runtime 有 Windows ARM64 的构建,31 个发行版里有 11 个有 Alpine x64 的构建,7 个有 Alpine arm64 的构建。GraalVM 既没有 Windows ARM64,也没有 Alpine。完整的表格见 [docs/zh-CN/platforms.md](docs/zh-CN/platforms.md)。 ## JavaFX diff --git a/docs/changes.md b/docs/changes.md index 1439f38..9088d2f 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -2,7 +2,11 @@ [中文](zh-CN/changes.md) | [English](changes.md) -What changed in each release, as a user notices it. GitHub's release pages list the pull requests. +What changed in each release, as a user notices it. GitHub's release pages list the pull requests. The newest release at the time of writing is 0.6.2, and `main` is ahead of it by everything under "Unreleased". [install-from-source.md](install-from-source.md) gets you those changes now. + +## Unreleased + +- 13 more distributions, the rest of what Foojay lists: AdoptOpenJDK (`adpt`, `adptj9`), Eliya (`eliya`), OJDKBuild (`ojdkbld`), OpenLogic (`opnlgc`), Red Hat (`rdht`), Semeru certified (`semcrt`), Gluon GraalVM (`gln`) and GraalVM CE for JDK 8 to 19 (`grl8`, `grl11`, `grl16`, `grl17`, `grl19`). Red Hat installs from tar.xz, and OJDKBuild on Linux, OpenLogic on macOS and Gluon GraalVM before 22.1 from zips. A `.sdkmanrc` takes SDKMAN's old identifiers for them, such as `11.0.10.j9-adpt` and `22.3.3.r17-grl`. See [distributions.md](distributions.md). ## 0.6.2 (2026-10-18) diff --git a/docs/development.md b/docs/development.md index 7346abb..5897cbd 100644 --- a/docs/development.md +++ b/docs/development.md @@ -13,7 +13,7 @@ hooks/env_keys.lua JAVA_HOME and PATH hooks/pre_use.lua vfox use: map what was typed to an installed name hooks/parse_legacy_file.lua .sdkmanrc lib/distribution_version.lua distribution names, parsing of specs, GraalVM feature releases -lib/foojay.lua the Foojay request +lib/foojay.lua the Foojay request, and fixes to what it answers lib/installed_version.lua matching against installed names lib/loongnix.lua the Loongnix archive tests/*_test.lua offline hook tests @@ -46,13 +46,15 @@ A few contracts that cost time to find: Installed names are `[-][-fx]`, with no short name for OpenJDK ([versions.md](versions.md#installed-names)). `lib/distribution_version.lua` reads a spec into a version, a distribution and the JavaFX flag, in either order (`21-tem`, `tem-21`). `lib/installed_version.lua` turns a version the user typed into an installed name: the name itself first. A bare major then takes the newest installed release of it, and any other version takes the release itself or its newest build. `PreUse` stops there. `ParseLegacyFile` goes one step further and falls back to the newest installed release of the major. -SDKMAN spells some things differently (`jbr`, `21.0.12.fx-zulu`, `21.0.12-fx+1.1-librca`, `28.0.0+ea.19-open`), and `plugin_spelling` in `hooks/parse_legacy_file.lua` rewrites them into the plugin's before parsing. `installed_version.unpad` drops the zeros SDKMAN pads releases with (`27.0.0+36` is `27+36`). The plugin's short names are SDKMAN's, except `jb`. +SDKMAN spells some things differently (`jbr`, `21.0.12.fx-zulu`, `21.0.12-fx+1.1-librca`, `28.0.0+ea.19-open`), and `plugin_spelling` in `hooks/parse_legacy_file.lua` rewrites them into the plugin's before parsing. For the distributions SDKMAN no longer lists, `sdkman_flavours` there turns the virtual machine or JDK in SDKMAN's version into the short name (`22.3.3.r17-grl` is `22.3.3-grl17`). `installed_version.unpad` drops the zeros SDKMAN pads releases with (`27.0.0+36` is `27+36`). Where the short names differ from SDKMAN's is in [distributions.md](distributions.md#short-names-and-sdkman). ## Foojay - A `+` in a query has to be percent-encoded. Foojay reads a bare one as a space and drops the build, so `21.0.5+63130` would match every 21.0.5 build. - `version=21` is the GA build `21+35`. A bare major adds `latest=available` to get the newest 21.x. - Windows asks for `zip` and `tar.gz` in one request. JetBrains Runtime ships Windows zips for its newer builds only. `PreInstall` takes the zip when a version has both. +- Elsewhere `other_archive_type` in `lib/foojay.lua` adds one archive type for the distributions that ship no tar.gz there for some or all releases: `tar.xz` for Red Hat, `zip` for OJDKBuild, OpenLogic and Gluon GraalVM. vfox unpacks both, and the zips carry their Unix permissions, so `bin/java` stays executable. +- `fixes` in `lib/foojay.lua` drops packages before the hooks see them: the JREs, installer bundles and RHEL 6 builds that Foojay lists among OJDKBuild's Windows JDKs, and the JDK 11 builds of Gluon GraalVM's 22.x releases, which share their version with the JDK 17 ones. For a bare major `latest=available` answers with one package per archive type, which can be one the fix drops, so for these two the plugin then asks for that release in full. - `Available` lists a name once where Foojay has two records for it. - Foojay marks GraalVM's monthly feature releases (`25.1.3` and on) as LTS. `is_feature_release` in `lib/distribution_version.lua` recognises them, by the minor number, and `Available` drops the note. It is for `graal` and `graalce` only: Mandrel and Liberica NIK numbered their releases after themselves up to 24 (`mandrel` `23.1.12` is LTS) and follow the JDK from 25 on. - For a bare major of Oracle GraalVM (`graal`) only, `PreInstall` skips the feature releases, so the 25.0 line is installed. A major that has nothing but feature releases keeps them. GraalVM Community is not filtered, because its feature releases are what it still ships. @@ -70,7 +72,7 @@ go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/loongnix_test.lua go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/post_install_test.lua ``` -Run them from the repository root. All five load `tests/support.lua`, which stubs `vfox.strings`, and `tests/pre_install_test.lua` and `tests/loongnix_test.lua` stub `http` and `json` themselves. `tests/pre_install_test.lua` keeps Foojay's answers in a table at the top, keyed by ` [] []`, with `windows` in front for Windows. Add the answer a new case needs there, and note the day you observed it. Lint, license headers and the container tests are in [e2e.md](e2e.md#local-checks). +Run them from the repository root. All five load `tests/support.lua`, which stubs `vfox.strings`, and `tests/pre_install_test.lua` and `tests/loongnix_test.lua` stub `http` and `json` themselves. `tests/pre_install_test.lua` keeps Foojay's answers in a table at the top, keyed by ` [] []`, with `windows` or `macos` in front for those systems. Add the answer a new case needs there, and note the day you observed it. Lint, license headers and the container tests are in [e2e.md](e2e.md#local-checks). To call a single hook against the real Foojay, vfox 1.0.13 and later has `vfox plugin run`. It does not register the plugin, and `--os` and `--arch` answer for another platform: @@ -85,40 +87,46 @@ vfox plugin run . ParseLegacyFile --input '{"filename":".sdkmanrc","filepath":"/ ## Adding a distribution 1. Find its id in Foojay ([foojay.md](foojay.md)), and check that it has packages for the platforms you care about. -2. Add `[""] = ""` to `short_name` in `lib/distribution_version.lua`. Use SDKMAN's identifier when SDKMAN has the distribution. If SDKMAN spells it differently, map it in `plugin_spelling` in `hooks/parse_legacy_file.lua`. -3. If its version numbers or its LTS marks need special care, as GraalVM's do, handle that in `hooks/available.lua` and `hooks/pre_install.lua`. +2. Add `[""] = ""` to `short_name` in `lib/distribution_version.lua`. Use SDKMAN's identifier when SDKMAN has or had the distribution. Otherwise make one the way SDKMAN does: keep a short vendor name whole, and cut a longer one down, mostly by dropping vowels (`opnlgc`). If SDKMAN spells it differently, map it in `plugin_spelling` in `hooks/parse_legacy_file.lua`, and add the difference to [distributions.md](distributions.md#short-names-and-sdkman). +3. If its version numbers or its LTS marks need special care, as GraalVM's do, handle that in `hooks/available.lua` and `hooks/pre_install.lua`. If it ships no tar.gz outside Windows, add its archive type to `other_archive_type` in `lib/foojay.lua`, and if Foojay lists packages of it that do not install as they are, add a fix to `fixes` there. 4. Add a case to `tests/pre_install_test.lua`. 5. Update the tables in `README.md`, [distributions.md](distributions.md) and [platforms.md](platforms.md), and their translations in `README_CN.md` and `docs/zh-CN`. -6. For a new code path, also add it to the e2e matrix ([e2e.md](e2e.md)). Distributions outside the matrix still run every check except the `java.vendor` assertion and the asdf-style `PreUse` spelling. +6. For a new code path, also add it to the e2e matrix ([e2e.md](e2e.md)). Distributions outside the matrix still run every check except the `java.vendor` assertion and the asdf-style `PreUse` spelling. One that only brings a name goes into `nameOnly` in `tests/e2e/common/common.go` instead, with the runner platforms Foojay has it for. ## Refreshing the platform table -[platforms.md](platforms.md) was taken from Foojay. This prints, for each platform, which distributions have a build there, in 8 requests: +[platforms.md](platforms.md) was taken from Foojay. This prints, for each platform, which distributions have a build there, in 14 requests. Outside Windows a second request per platform asks for the archive types that Red Hat, OJDKBuild, OpenLogic and Gluon GraalVM ship there besides tar.gz, as the plugin does: ```bash base='https://api.foojay.io/disco/v3.0/packages/jdks?directly_downloadable=true&latest=per_distro' while read -r name query; do printf '%-14s ' "$name" - curl -s "$base&$query" | jq -r '.result[].distribution' | sort -u | tr '\n' ' '; echo + { + curl -s "$base&$query&archive_type=tar.gz" | jq -r '.result[].distribution' + case $name in windows-*) ;; *) + curl -s "$base&$query&archive_type=tar.xz&archive_type=zip" | jq -r '.result[].distribution + | select(. == "redhat" or . == "ojdk_build" or . == "openlogic" or . == "gluon_graalvm")' ;; + esac + } | sort -u | tr '\n' ' '; echo done <<'EOF' -linux-x64 architecture=amd64&operating_system=linux&lib_c_type=glibc&archive_type=tar.gz -linux-arm64 architecture=aarch64&operating_system=linux&lib_c_type=glibc&archive_type=tar.gz -alpine-x64 architecture=amd64&operating_system=linux&lib_c_type=musl&archive_type=tar.gz -alpine-arm64 architecture=aarch64&operating_system=linux&lib_c_type=musl&archive_type=tar.gz -macos-intel architecture=amd64&operating_system=macos&archive_type=tar.gz -macos-arm64 architecture=aarch64&operating_system=macos&archive_type=tar.gz -windows-x64 architecture=x64&operating_system=windows&archive_type=zip&archive_type=tar.gz -windows-arm64 architecture=aarch64&operating_system=windows&archive_type=zip&archive_type=tar.gz +linux-x64 architecture=amd64&operating_system=linux&lib_c_type=glibc +linux-arm64 architecture=aarch64&operating_system=linux&lib_c_type=glibc +alpine-x64 architecture=amd64&operating_system=linux&lib_c_type=musl +alpine-arm64 architecture=aarch64&operating_system=linux&lib_c_type=musl +macos-intel architecture=amd64&operating_system=macos +macos-arm64 architecture=aarch64&operating_system=macos +windows-x64 architecture=x64&operating_system=windows&archive_type=zip +windows-arm64 architecture=aarch64&operating_system=windows&archive_type=zip EOF ``` -The ids are Foojay's (`oracle_open_jdk` is `open`). The notes under "Only some releases" need one query per distribution and platform without `latest`, grouped by `major_version`. +The ids are Foojay's (`oracle_open_jdk` is `open`). It prints `redhat` for Linux arm64 and Windows x64 too, which the table leaves out, as those downloads answer 404. The notes under "Only some releases" need one query per distribution and platform without `latest`, grouped by `major_version`. ## Known gaps - Downloads are not verified, see above. - `vfox search` lists GA releases only. Early-access builds install by name. -- Foojay distributions without a short name ([distributions.md](distributions.md#foojay-distributions-the-plugin-does-not-offer)), and JRE packages, are not offered. +- JRE packages are not offered, and neither are the JDK 11 builds of Gluon GraalVM's 22.x releases. - Only Linux loong64 has a source besides Foojay. ## Releasing diff --git a/docs/distributions.md b/docs/distributions.md index 4719c32..fd925a4 100644 --- a/docs/distributions.md +++ b/docs/distributions.md @@ -2,33 +2,56 @@ [中文](zh-CN/distributions.md) | [English](distributions.md) -The plugin gets the releases and download links of these 18 distributions from [Foojay](foojay.md). The short name or the long name goes wherever a distribution does: `21-tem`, `21-temurin`, `temurin-21`, `vfox search java tem`. +The plugin gets the releases and download links of these 31 distributions from [Foojay](foojay.md), all that Foojay listed on 2026-10-20. The short name or the long name goes wherever a distribution does: `21-tem`, `21-temurin`, `temurin-21`, `vfox search java tem`. + +Unreleased: release 0.6.2 lacks `adpt`, `adptj9`, `eliya`, `gln`, `grl8`, `grl11`, `grl16`, `grl17`, `grl19`, `ojdkbld`, `opnlgc`, `rdht` and `semcrt`. For those its `vfox install` stops with `Could not extract a valid distribution` and `vfox search` with `Unsupported distribution`. | Short name | Long name | Distribution | Maintained by | | --- | --- | --- | --- | -| `open` | `openjdk` | OpenJDK builds from jdk.java.net | Oracle, for the OpenJDK project | -| `tem` | `temurin` | Temurin | Eclipse Adoptium | -| `zulu` | `zulu` | Zulu | Azul | -| `librca` | `liberica` | Liberica | BellSoft | -| `amzn` | `corretto` | Corretto | Amazon | -| `ms` | `microsoft` | Microsoft Build of OpenJDK | Microsoft | -| `oracle` | `oracle` | Oracle JDK | Oracle | -| `sem` | `semeru` | Semeru Runtimes, open edition | IBM | -| `sapmchn` | `sap_machine` | SapMachine | SAP | -| `kona` | `kona` | Tencent Kona JDK | Tencent | +| `adpt` | `aoj` | AdoptOpenJDK with HotSpot | AdoptOpenJDK | +| `adptj9` | `aoj_openj9` | AdoptOpenJDK with OpenJ9 | AdoptOpenJDK | | `albba` | `dragonwell` | Alibaba Dragonwell | Alibaba | +| `amzn` | `corretto` | Corretto | Amazon | | `bsg` | `bisheng` | BiSheng JDK | Huawei | +| `eliya` | `eliya` | Eliya JDK | Asymm Systems | +| `gln` | `gluon_graalvm` | Gluon GraalVM | Gluon | | `graal` | `graalvm` | Oracle GraalVM | Oracle | | `graalce` | `graalvm_community` | GraalVM Community Edition | GraalVM project | -| `nik` | `liberica_native` | Liberica Native Image Kit | BellSoft | -| `mandrel` | `mandrel` | Mandrel | Red Hat | +| `grl8` | `graalvm_ce8` | GraalVM CE for JDK 8 | GraalVM project | +| `grl11` | `graalvm_ce11` | GraalVM CE for JDK 11 | GraalVM project | +| `grl16` | `graalvm_ce16` | GraalVM CE for JDK 16 | GraalVM project | +| `grl17` | `graalvm_ce17` | GraalVM CE for JDK 17 | GraalVM project | +| `grl19` | `graalvm_ce19` | GraalVM CE for JDK 19 | GraalVM project | | `jb` | `jetbrains` | JetBrains Runtime | JetBrains | +| `kona` | `kona` | Tencent Kona JDK | Tencent | +| `librca` | `liberica` | Liberica | BellSoft | +| `mandrel` | `mandrel` | Mandrel | Red Hat | +| `ms` | `microsoft` | Microsoft Build of OpenJDK | Microsoft | +| `nik` | `liberica_native` | Liberica Native Image Kit | BellSoft | +| `ojdkbld` | `ojdk_build` | OJDKBuild | community | +| `open` | `openjdk` | OpenJDK builds from jdk.java.net | Oracle, for the OpenJDK project | +| `opnlgc` | `openlogic` | OpenLogic OpenJDK | OpenLogic | +| `oracle` | `oracle` | Oracle JDK | Oracle | +| `rdht` | `redhat` | Red Hat build of OpenJDK | Red Hat | +| `sapmchn` | `sap_machine` | SapMachine | SAP | +| `sem` | `semeru` | Semeru Runtimes, open edition | IBM | +| `semcrt` | `semeru_certified` | Semeru Runtimes, certified edition | IBM | +| `tem` | `temurin` | Temurin | Eclipse Adoptium | | `trava` | `trava` | TravaOpenJDK | community | +| `zulu` | `zulu` | Zulu | Azul | -The long names are the distribution names Foojay takes, except `openjdk`, which Foojay lists as Oracle OpenJDK and accepts as a synonym. The short names are SDKMAN's, except `jb`, which SDKMAN calls `jbr`. A `.sdkmanrc` accepts `jbr` as well as `jb`, see [sdkmanrc.md](sdkmanrc.md). `lnxabi1` and `lnxabi2` are not in the table because they do not come from Foojay, see [loongnix.md](loongnix.md). +The long names are the distribution names Foojay takes, except `openjdk`, which Foojay lists as Oracle OpenJDK and accepts as a synonym. `lnxabi1` and `lnxabi2` are not in the table because they do not come from Foojay, see [loongnix.md](loongnix.md). Which operating systems and CPUs each distribution covers is in [platforms.md](platforms.md). `vfox search java ` lists what exists for the machine you run it on. Installed names carry the short name, except for OpenJDK, which has none (see [versions.md](versions.md)). +## Short names and SDKMAN + +The short names follow the identifiers of [SDKMAN](https://sdkman.io/), where Temurin 21.0.8 is `21.0.8-tem` too. These are the differences, against SDKMAN's list of 2026-10-20: + +- JetBrains Runtime is `jb`, which SDKMAN calls `jbr`, and BiSheng is `bsg`, which SDKMAN calls `bisheng`, the plugin's long name for it. A `.sdkmanrc` takes SDKMAN's spellings, see [sdkmanrc.md](sdkmanrc.md). +- SDKMAN no longer lists Dragonwell, TravaOpenJDK, AdoptOpenJDK, Gluon GraalVM or the GraalVM CE builds numbered after GraalVM. It called the last three `adpt`, `gln` and `grl`, and wrote the virtual machine or the JDK into the version: `11.0.10.hs-adpt` with HotSpot, `11.0.10.j9-adpt` with OpenJ9, `22.3.3.r17-grl` on JDK 17. Here each Foojay distribution has a name of its own, so that part moved into the name: `11.0.10-adpt`, `11.0.10-adptj9`, `22.3.3-grl17`. A `.sdkmanrc` with SDKMAN's spelling selects them. +- SDKMAN has no identifier for Eliya, OJDKBuild, OpenLogic, Red Hat or Semeru certified. Their short names are the plugin's own, made the way SDKMAN makes its names: a short vendor name stays whole (`eliya`, like `zulu`), and a longer one is cut down, mostly by dropping vowels (`ojdkbld`, `opnlgc`, `rdht`, like `librca` and `sapmchn`). `semcrt` is SDKMAN's `sem` with certified. Eliya's own install instructions give `sdk install java 25.0.3-eliya`, and its site says the SDKMAN registration is in progress, but SDKMAN did not list it. + ## OpenJDK builds ### OpenJDK (`open`) @@ -61,7 +84,7 @@ The builds of the [Eclipse Adoptium](https://adoptium.net/temurin/releases) proj ### Semeru (`sem`) -[IBM's](https://developer.ibm.com/languages/java/semeru-runtimes/) runtimes: the OpenJDK class library on the Eclipse OpenJ9 virtual machine instead of HotSpot. Only the open edition is offered, not Foojay's `semeru_certified`. +[IBM's](https://developer.ibm.com/languages/java/semeru-runtimes/) runtimes: the OpenJDK class library on the Eclipse OpenJ9 virtual machine instead of HotSpot. This is the open edition. The certified edition is `semcrt`, see [below](#semeru-certified-semcrt). ### SapMachine (`sapmchn`) @@ -79,6 +102,30 @@ The builds of the [Eclipse Adoptium](https://adoptium.net/temurin/releases) proj [Huawei's](https://www.hikunpeng.com/developer/devkit/compilation_debugging?data=JDK) build of OpenJDK, aimed at ARM servers. Java 8, 11, 17, 21 and 25, for Linux only. +### AdoptOpenJDK (`adpt`, `adptj9`) + +The builds of the [AdoptOpenJDK](https://adoptopenjdk.net/) project from before it moved to the Eclipse Foundation, with the HotSpot virtual machine (`adpt`) or with Eclipse OpenJ9 (`adptj9`). Java 8 to 16, up to 2021. Foojay marks both as no longer maintained. Temurin (`tem`) carries on the HotSpot builds and Semeru (`sem`) the OpenJ9 ones. + +### Eliya (`eliya`) + +[Asymm Systems'](https://asymm.systems/product/eliya) build of OpenJDK 25, whose `-XX:EliyaProfile=Production` turns on production settings such as a heap dump on `OutOfMemoryError`. Foojay lists one release, 25.0.3, for Linux x64 and arm64. + +### OJDKBuild (`ojdkbld`) + +The builds of the [ojdkbuild](https://github.com/ojdkbuild/ojdkbuild) project: Java 8 to 15 and 17 for Windows x64, and 8 and 11 for Linux x64, which come as zips. The project stopped in 2022, with 17.0.3. Among its Windows JDKs Foojay also lists JREs, installer bundles and RHEL 6 builds for Linux, which the plugin leaves out. + +### OpenLogic (`opnlgc`) + +[OpenLogic's](https://www.openlogic.com/openjdk-downloads) builds of OpenJDK. Java 8, 11, 17, 21, 22 and 25, for Linux x64, macOS Intel and Windows x64. The macOS builds come as zips. + +### Red Hat build of OpenJDK (`rdht`) + +[Red Hat's](https://developers.redhat.com/products/openjdk/overview) portable builds. Java 8, 11, 17 and 21 for Linux x64, as tar.xz. Foojay has 21.0.8 (July 2025) as the newest. It lists builds for Linux arm64 and one for Windows as well, but their downloads answer 404 (`source file not found`), and so do 11.0.15 and 11.0.16 for Linux x64. + +### Semeru certified (`semcrt`) + +IBM Semeru Runtime Certified Edition: Semeru's OpenJ9 runtimes, certified against the Java Compatibility Kit (JCK) and released under an IBM licence, not an open-source one. Java 11, 17, 21 and 25. Foojay has no macOS or Windows build of it. + ## GraalVM family ### Oracle GraalVM (`graal`) @@ -99,6 +146,18 @@ The open-source edition of GraalVM, built on OpenJDK. Mandrel and Liberica NIK numbered their releases after themselves up to version 24 (Mandrel `23.1.12`), and number them after the JDK from 25 on (`25.0.4.1`). +### GraalVM CE 8 to 19 (`grl8`, `grl11`, `grl16`, `grl17`, `grl19`) + +GraalVM Community Edition up to 22.3, from before it numbered its releases after the JDK. Foojay has one distribution per JDK: `grl8` (GraalVM 19.3 to 21.3.1), `grl11` (19.3 to 22.3.3), `grl16` (21.1 and 21.2), `grl17` (21.3 to 22.3.3) and `grl19` (22.3 and 22.3.1). GraalVM Community (`graalce`) followed them. + +### Gluon GraalVM (`gln`) + +[Gluon's](https://docs.gluonhq.com/#_graalvm) build of GraalVM, for compiling JavaFX applications into native images. 21.1 and 21.2 run on JDK 11. The 22.x releases, 22 to 22.1.0.1, come for JDK 11 and for JDK 17 under one version, and the plugin installs the JDK 17 build. 23+25 is a development build on JDK 23. Linux x64, macOS and Windows x64, with Apple silicon from 22.1.0.1. + +### Versions numbered after GraalVM + +GraalVM CE 8 to 19, and Gluon GraalVM before 23, carry GraalVM's version numbers, not Java's: `22.3.3-grl17` is GraalVM 22.3.3 and runs Java 17.0.8, and `21.3.1-grl11` runs Java 11. For a bare major vfox takes the highest installed version that starts with it, from any distribution, so with `21.3.1-grl11` and `21.0.12.1+1-tem` installed, `vfox use java@21` selects `21.3.1-grl11`. Name the distribution, as in `java@21-tem`. + ### Behavior of Oracle GraalVM and GraalVM Community - Since 25.1 (June 2026) GraalVM puts out a feature release every month next to its 25.0 line: `25.1.3`, `25.2.4`, `25.3.4.1`, `25.4.4.1`. Each is replaced within about a month. Foojay marks them LTS because the JDK they build on is LTS, and `vfox search` leaves the LTS note off them. @@ -116,7 +175,3 @@ The [fork of OpenJDK](https://github.com/JetBrains/JetBrainsRuntime) that JetBra ### TravaOpenJDK (`trava`) [OpenJDK with DCEVM](https://github.com/TravaOpenJDK) and a bundled HotswapAgent, for replacing classes in a running program. Java 8 and 11. Foojay marks it as no longer maintained. It has no Apple silicon build and one for Linux arm64 (`11.0.10+6`). - -## Foojay distributions the plugin does not offer - -Foojay lists more than these 18: `aoj` and `aoj_openj9` (AdoptOpenJDK, succeeded by Temurin and Semeru), `eliya`, `gluon_graalvm`, `graalvm_ce8`, `graalvm_ce11`, `graalvm_ce16`, `graalvm_ce17`, `graalvm_ce19` (old GraalVM Community releases), `ojdk_build`, `openlogic`, `redhat` and `semeru_certified`. They have no short name here, so `vfox install java@21-openlogic` fails with `Could not extract a valid distribution`. [development.md](development.md#adding-a-distribution) describes how to add one. diff --git a/docs/e2e.md b/docs/e2e.md index c397c8f..da57ce9 100644 --- a/docs/e2e.md +++ b/docs/e2e.md @@ -85,7 +85,16 @@ JDK, so `java` can only come from what vfox installs: `vfox install` names the one `PreInstall` picked and nothing downloads. GA 25 is left out, as vfox would find `25-graal` itself installed without asking `PreInstall`. -4. The pinned release installs under the name `PreInstall` gives it: the +4. On the Temurin rows, which run on every runner, the distributions the + suite checks by name only (`adpt` to `semcrt`, `nameOnly` in + `tests/e2e/common`) go by their short names where Foojay has packages of + them for the runner: `vfox search java ` lists each, and once the + newest version it lists is faked as installed, + `vfox install java@-` (`22-grl17`) reports that version as + already installed, so nothing downloads. Before they had short names, the + two failed with `Unsupported distribution` and `Could not extract a valid + distribution`. +5. The pinned release installs under the name `PreInstall` gives it: the requested version plus the build number (`21.0.8-tem` installs as `21.0.8+9-tem`). `vfox search java ` (the `Available` hook) lists that same name as installed, noting JavaFX on `-fx` builds. For @@ -94,7 +103,7 @@ JDK, so `java` can only come from what vfox installs: marks them LTS, as the JDK they build on is; each lasts about a month. On Windows the list includes JetBrains Runtime 21.0.5, which ships only as tar.gz there. -5. Before any `vfox use`, a `.sdkmanrc` holding the SDKMAN identifier +6. Before any `vfox use`, a `.sdkmanrc` holding the SDKMAN identifier without the build number selects the JDK through `ParseLegacyFile`: `java=21.0.8-tem`, `java=21.0.5-jbr` (SDKMAN's name for JetBrains) or `java=25.0.4.fx-librca` (its spelling of JavaFX builds). So does one @@ -117,7 +126,7 @@ JDK, so `java` can only come from what vfox installs: weeks, so that install is faked: its `bin` holds a stand-in `java` that only prints the name. On Windows the file is written with CRLF line endings. -6. After `vfox use --global`, the JDK on `PATH` reports the requested +7. After `vfox use --global`, the JDK on `PATH` reports the requested `java.version`, the runner's `os.arch` (`amd64` / `aarch64`, which also catches an x64 JDK emulated on Windows ARM64) and the distribution's `java.vendor`. `JAVA_HOME` holds that same JDK, `javac` compiles a @@ -126,7 +135,7 @@ JDK, so `java` can only come from what vfox installs: `GRAALVM_HOME` set beforehand keeps its value, as users point it at a GraalVM of their own; for GraalVM, the plugin used to replace it with the JDK in use. -7. `PreUse` maps the spellings users type to the installed version without +8. `PreUse` maps the spellings users type to the installed version without another download: the bare major (`java@21`, left to vfox core's fuzzy matching), the spec the JDK was installed with (`java@21.0.8-tem`, whose build number `PreUse` finds among the installed versions) and the @@ -141,13 +150,13 @@ JDK, so `java` can only come from what vfox installs: The default matrix runs every distribution against both vfox channels (`latest`, `main`): -| Distribution | Release | Covers | amd64 | arm64 | -| ------------ | ------- | ---------------------------------------------------------------------------- | ----- | ----- | -| `open` | 25.0.2 | the default distribution, versions without a suffix | ✓ | | -| `tem` | 21.0.8 | the common path (tar.gz on Linux, zip on Windows) | ✓ | ✓ | -| `librca-fx` | 25.0.4 | JavaFX bundled builds (`-fx`) | ✓ | ✓ | -| `jb` | 21.0.5 | the tar.gz path on Windows, which has no zip for it | ✓ | ✓ | -| `graalce` | 25.0.2 | a `GRAALVM_HOME` set beforehand keeps its value; Oracle GraalVM's `25-graal` | ✓ | | +| Distribution | Release | Covers | amd64 | arm64 | +| ------------ | ------- | ---------------------------------------------------------------------------------------- | ----- | ----- | +| `open` | 25.0.2 | the default distribution, versions without a suffix | ✓ | | +| `tem` | 21.0.8 | the common path (tar.gz on Linux, zip on Windows); the distributions checked by name | ✓ | ✓ | +| `librca-fx` | 25.0.4 | JavaFX bundled builds (`-fx`) | ✓ | ✓ | +| `jb` | 21.0.5 | the tar.gz path on Windows, which has no zip for it | ✓ | ✓ | +| `graalce` | 25.0.2 | a `GRAALVM_HOME` set beforehand keeps its value; Oracle GraalVM's `25-graal` | ✓ | | Every pinned release is published through Foojay for each platform its row runs on. OpenJDK and GraalVM Community ship no `windows-aarch64` build, so diff --git a/docs/foojay.md b/docs/foojay.md index 7779447..e94d304 100644 --- a/docs/foojay.md +++ b/docs/foojay.md @@ -27,14 +27,14 @@ https://api.foojay.io/disco/v3.0/packages/jdks | `version` | empty for `vfox search`, else the version part of what you typed. A `+` is percent-encoded, because Foojay reads a bare one as a space and drops the build. `28.ea.19` becomes `28-ea+19` | | `architecture` | `aarch64` for arm64, `x64` on Windows x64, `amd64` for x64 elsewhere, and the name vfox reports for other CPUs | | `operating_system` | `linux`, `macos` or `windows` | -| `archive_type` | `tar.gz`, and `zip` plus `tar.gz` on Windows | +| `archive_type` | `tar.gz`, and `zip` plus `tar.gz` on Windows. Elsewhere `tar.xz` comes in for Red Hat, and `zip` for OJDKBuild, OpenLogic and Gluon GraalVM | | `lib_c_type` | `glibc` or `musl` on Linux, empty elsewhere | | `directly_downloadable` | always `true` | | `latest` | `available`, added only when the version is a bare major such as `21` | Without `latest=available`, `version=21` matches the 21 GA build only (`21+35`). With it Foojay picks the newest 21.x, which is what `java@21-tem` installs. Longer versions match as they are. -The answer is a list of packages. The plugin names a release after `java_version`, adds `-fx` where `javafx_bundled` is true, marks it LTS where `term_of_support` is `lts`, and prefers a `zip` over a `tar.gz` of the same version on Windows. For the install it then fetches the package's `links.pkg_info_uri` and downloads its `direct_download_uri`, which is a vendor's own server (GitHub Releases for Temurin). That record also holds a `checksum`. The plugin does not pass it on, so vfox prints `WARNING: Checksum is not provided, skip verify...` and does not verify the download. +The answer is a list of packages. The plugin names a release after `java_version`, adds `-fx` where `javafx_bundled` is true, marks it LTS where `term_of_support` is `lts`, and prefers a `zip` over a `tar.gz` of the same version on Windows. It leaves out the JREs, installer bundles and RHEL 6 builds that Foojay lists among OJDKBuild's Windows JDKs, and the JDK 11 builds of Gluon GraalVM's 22.x releases, see [distributions.md](distributions.md). For the install it then fetches the package's `links.pkg_info_uri` and downloads its `direct_download_uri`, which is a vendor's own server (GitHub Releases for Temurin). That record also holds a `checksum`. The plugin does not pass it on, so vfox prints `WARNING: Checksum is not provided, skip verify...` and does not verify the download. `vfox search` differs from the raw list in a few ways. It lists a name once where Foojay has two records for it, and it leaves the LTS note off GraalVM's feature releases (see [distributions.md](distributions.md#behavior-of-oracle-graalvm-and-graalvm-community)). It only lists GA releases. @@ -66,7 +66,7 @@ For another platform change the three parameters that name it. Linux needs `lib_ | macOS Intel | `architecture=amd64&operating_system=macos&archive_type=tar.gz` | | Windows x64 | `architecture=x64&operating_system=windows&archive_type=zip&archive_type=tar.gz` | -The answer includes distributions the plugin does not offer. [distributions.md](distributions.md#foojay-distributions-the-plugin-does-not-offer) lists them. +The names in the answer are the long names in [distributions.md](distributions.md), except `oracle_open_jdk`, which the plugin calls `openjdk` (`open`). With `archive_type=tar.gz` alone the answer misses Red Hat and OJDKBuild on Linux, and OpenLogic on macOS, which ship tar.xz or zip there. The plugin asks for those types for them, see the table above. ## Which distributions have a release for my platform diff --git a/docs/platforms.md b/docs/platforms.md index c72b4cf..bbbb7c7 100644 --- a/docs/platforms.md +++ b/docs/platforms.md @@ -8,28 +8,41 @@ The plugin asks Foojay for packages of the platform it runs on: the operating sy No JDK found for 21-bsg on darwin/arm64. Please check available versions with 'vfox search java' ``` -The table shows which platforms each distribution has packages for. It was taken from Foojay on 2026-10-18. A tick means Foojay lists at least one package the plugin can install there, a dash means none. +The table shows which platforms each distribution has packages for. It was taken from Foojay on 2026-10-18, and the rows from AdoptOpenJDK on were added on 2026-10-20. ✅ means Foojay lists at least one package the plugin can install there, ❌ means none. Unreleased: release 0.6.2 has the rows up to Trava only. | Distribution | Linux x64 | Linux arm64 | Alpine x64 | Alpine arm64 | macOS Intel | macOS Apple silicon | Windows x64 | Windows arm64 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| OpenJDK (`open`) | ✓ | ✓ | – | – | ✓ | ✓ | ✓ | – | -| Temurin (`tem`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Zulu (`zulu`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Liberica (`librca`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Corretto (`amzn`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – | -| Microsoft (`ms`) | ✓ | ✓ | ✓ | – | ✓ | ✓ | ✓ | ✓ | -| Oracle JDK (`oracle`) | ✓ | ✓ | – | – | ✓ | ✓ | ✓ | – | -| Semeru (`sem`) | ✓ | ✓ | – | – | ✓ | ✓ | ✓ | – | -| SapMachine (`sapmchn`) | ✓ | ✓ | ✓ | – | ✓ | ✓ | ✓ | – | -| Kona (`kona`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – | -| Dragonwell (`albba`) | ✓ | ✓ | ✓ | – | – | – | ✓ | – | -| BiSheng (`bsg`) | ✓ | ✓ | – | – | – | – | – | – | -| Oracle GraalVM (`graal`) | ✓ | ✓ | – | – | ✓ | ✓ | ✓ | – | -| GraalVM Community (`graalce`) | ✓ | ✓ | – | – | ✓ | ✓ | ✓ | – | -| Liberica NIK (`nik`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – | -| Mandrel (`mandrel`) | ✓ | ✓ | – | – | – | ✓ | ✓ | – | -| JetBrains Runtime (`jb`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Trava (`trava`) | ✓ | ✓ | – | – | ✓ | – | ✓ | – | +| OpenJDK (`open`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| Temurin (`tem`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Zulu (`zulu`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Liberica (`librca`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Corretto (`amzn`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| Microsoft (`ms`) | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | +| Oracle JDK (`oracle`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| Semeru (`sem`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| SapMachine (`sapmchn`) | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | +| Kona (`kona`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| Dragonwell (`albba`) | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | +| BiSheng (`bsg`) | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| Oracle GraalVM (`graal`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| GraalVM Community (`graalce`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| Liberica NIK (`nik`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| Mandrel (`mandrel`) | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | +| JetBrains Runtime (`jb`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Trava (`trava`) | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | +| AdoptOpenJDK (`adpt`) | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | +| AdoptOpenJDK OpenJ9 (`adptj9`) | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | +| Eliya (`eliya`) | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| OJDKBuild (`ojdkbld`) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | +| OpenLogic (`opnlgc`) | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | +| Red Hat (`rdht`) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| Semeru certified (`semcrt`) | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| Gluon GraalVM (`gln`) | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| GraalVM CE 8 (`grl8`) | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | +| GraalVM CE 11 (`grl11`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| GraalVM CE 16 (`grl16`) | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | +| GraalVM CE 17 (`grl17`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| GraalVM CE 19 (`grl19`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | "Alpine" stands for Linux with the musl C library. The plugin takes it as musl when `ldd --version` mentions it, and as glibc otherwise. Loongnix has its own page, [loongnix.md](loongnix.md). @@ -37,7 +50,7 @@ Foojay changes, and the table with it. To get the current one, ask Foojay the wa ## Only some releases -A tick does not mean every release is there. As of the same date: +A ✅ does not mean every release is there. As of the same date: - Windows on ARM64 has no Java 8 from anyone. Temurin has 21 and 23 there, Zulu 16 to 19, 21 and 25, Liberica 11 and 16 to 27, Microsoft 11, 16, 17, 21 and 25, and JetBrains Runtime 17, 21 and 25. - On Apple silicon Java 8 comes from Zulu, Liberica, Corretto and Kona. Temurin and Semeru have 11 and 17 to 27 there, and OpenJDK 17 to 27. Mandrel has 23 to 25, and Liberica NIK 22 to 25. @@ -46,25 +59,34 @@ A tick does not mean every release is there. As of the same date: - Trava has a single build for Linux arm64, 11.0.10+6. - JavaFX builds exist for fewer platforms than plain ones, see [javafx.md](javafx.md#where-javafx-builds-exist). +For the rows added on 2026-10-20, as of that date: + +- AdoptOpenJDK's Alpine x64 builds are Java 16 with HotSpot, and its OpenJ9 builds for Linux arm64 are 8, 11, 15 and 16. +- OJDKBuild has Java 8 and 11 for Linux. +- Red Hat's builds download for Linux x64 only, its one ✅ in the table. Foojay also lists a few for Linux arm64 and one for Windows, which `vfox search` shows, but their downloads answer 404. +- On Apple silicon Gluon GraalVM has 22.1.0.1 and 23+25, GraalVM CE 11 and 17 have GraalVM 22.1 to 22.3.1, and GraalVM CE 19 has 22.3 and 22.3.1. + ## Which are x64 only -Every distribution has Linux arm64 builds, and Trava has a single one (11.0.10+6). On macOS, Dragonwell and BiSheng have neither architecture, Trava has Intel only, and Mandrel has Apple silicon only. +Every distribution has Linux arm64 builds except OJDKBuild, OpenLogic, Red Hat, Gluon GraalVM and GraalVM CE 8, and Trava has a single one (11.0.10+6). On macOS, Dragonwell, BiSheng, Eliya, OJDKBuild, Red Hat and Semeru certified have neither architecture, Trava, AdoptOpenJDK, OpenLogic, GraalVM CE 8 and GraalVM CE 16 have Intel only, and Mandrel has Apple silicon only. -On Windows almost everything is x64 only. These have an arm64 build besides: Temurin, Zulu, Liberica, Microsoft and JetBrains Runtime. The others are x64 only, with BiSheng not there at all. +On Windows almost everything is x64 only. These have an arm64 build besides: Temurin, Zulu, Liberica, Microsoft and JetBrains Runtime. The others are x64 only, with BiSheng, Eliya, Red Hat and Semeru certified not there at all. ## GraalVM Oracle GraalVM and GraalVM Community have x64 and arm64 builds for Linux and macOS, and x64 only for Windows. They have no Alpine build. For Intel Macs the newest release is 25.0.1, and the monthly feature releases since 25.1 come for Apple silicon on macOS. The e2e suite skips GraalVM Community on arm64 only because its Windows arm64 job would have nothing to install. Linux arm64 has builds. +GraalVM CE 8 to 19 and Gluon GraalVM have no Alpine or Windows ARM64 build either. GraalVM CE has Linux arm64 builds from JDK 11 on, and Gluon GraalVM has none. + ## Other CPUs vfox ships binaries for 32-bit x86 and 32-bit ARM as well as x64, arm64 and loong64. The plugin passes the architecture name of the vfox binary to Foojay (`arm64` as `aarch64`, and `amd64` as `x64` on Windows), so what you get is what Foojay lists. None of this is covered by the e2e suite. -- 32-bit ARM Linux: Corretto, Liberica, Temurin and Zulu. -- 32-bit x86 Linux: Corretto, Liberica, Zulu and JetBrains Runtime. +- 32-bit ARM Linux: Corretto, Liberica, Temurin and Zulu, and AdoptOpenJDK with HotSpot. +- 32-bit x86 Linux: Corretto, Liberica, Zulu and JetBrains Runtime, and OpenLogic's Java 8. - loong64 is unknown to Foojay, and Linux loong64 uses Loongnix instead, see [loongnix.md](loongnix.md). -If you build vfox for riscv64, ppc64le or s390x, Foojay lists riscv64 packages for Dragonwell, Liberica and Temurin, ppc64le for Liberica, SapMachine, Semeru and Temurin, and s390x for Semeru and Temurin. +If you build vfox for riscv64, ppc64le or s390x, Foojay lists riscv64 packages for Dragonwell, Liberica and Temurin, ppc64le for Liberica, SapMachine, Semeru and Temurin, and s390x for Semeru and Temurin. Of the distributions added on 2026-10-20, AdoptOpenJDK, with HotSpot and with OpenJ9, and Semeru certified have ppc64le and s390x packages. Red Hat's ppc64le records answer 404. ## macOS Java home diff --git a/docs/sdkmanrc.md b/docs/sdkmanrc.md index 4978446..815ef78 100644 --- a/docs/sdkmanrc.md +++ b/docs/sdkmanrc.md @@ -55,6 +55,11 @@ It never crosses to another distribution, between a JavaFX build and a plain one | `21.0.8+1.1-tem` | Temurin 21.0.8, see below | | `27.0.0+36-librca`, `25.0.1.0+8-open` | `27+36-librca`, `25.0.1+8`: the zeros are dropped | | `28.ea.19-open`, `28.0.0+ea.19-open` | the early-access build `28-ea+19` | +| `11.0.10.hs-adpt`, `11.0.10.j9-adpt` | AdoptOpenJDK with HotSpot, `11.0.10-adpt`, and with OpenJ9, `11.0.10-adptj9` | +| `22.3.3.r17-grl` | GraalVM CE 22.3.3 for JDK 17, `22.3.3-grl17` | +| `22.1.0.1.r17-gln` | Gluon GraalVM 22.1.0.1, `22.1.0.1-gln` | + +The last three rows are SDKMAN's identifiers for distributions it no longer lists, with the virtual machine or the JDK in the version, see [distributions.md](distributions.md#short-names-and-sdkman). The plugin installs no JDK 11 build of Gluon GraalVM 22 and no AdoptOpenJDK upstream build, so `22.1.0.1.r11-gln` and `11.0.9.open-adpt` select nothing. Unreleased: release 0.6.2 selects nothing for any of the three. The number after `+` in SDKMAN's newer identifiers (`21.0.8+1.1-tem`) counts SDKMAN's own rebuilds. It is not a build number of the vendor, so the plugin does not look for one and takes the release. Foojay, and so the installed name, has no zero padding, which is why `27.0.0` means the release `27`. A `.0` padding in `sdk list java` is common (`25.0.1.0+8-open`, `21.0.9.0+116386-jbr`), and the plugin reads it as well. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 034cbf5..a1a637f 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -20,7 +20,7 @@ The spec holds a distribution and no version. `java@-tem`, `java@temurin-` and ` ### `Could not extract a valid distribution: 21-foo` -Neither part of the spec is the name of a distribution. Names are lower case and come from the table in [distributions.md](distributions.md). `java@21-openlogic` ends here too, because the plugin does not offer every distribution Foojay has. +Neither part of the spec is the name of a distribution. Names are lower case and come from the table in [distributions.md](distributions.md). Unreleased: release 0.6.2 ends here for the 13 distributions added after it, such as `java@21-opnlgc` and `java@21-openlogic`. ### `Unsupported distribution: foo` @@ -32,7 +32,7 @@ The request to Foojay failed. After `status_code =>` comes the HTTP status, othe ### `source file not found` -The download answered 404. Vendors take old builds down while Foojay keeps their records. Early-access builds are the common case (see [versions.md](versions.md#early-access-builds)). Pick a newer build. +The download answered 404. Vendors take old builds down while Foojay keeps their records. Early-access builds are the common case (see [versions.md](versions.md#early-access-builds)). Pick a newer build. Red Hat's builds for anything but Linux x64 all end here, see [distributions.md](distributions.md#red-hat-build-of-openjdk-rdht). ### `java@21-tem is not installed` @@ -66,6 +66,7 @@ While `proxy.enable` is `false`, the usual `HTTP_PROXY`, `HTTPS_PROXY` and `NO_P - **The installed name has a build number you did not type.** `java@21.0.8-tem` installs `21.0.8+9-tem`. The build is part of the name, see [versions.md](versions.md#installed-names). - **`vfox install java@21-tem` and `vfox install java tem` do different things.** The second one is two SDKs, `java` and `tem`. - **A `GRAALVM_HOME` you set is left alone.** The plugin sets `JAVA_HOME` and `PATH` only. +- **`vfox use java@21` selects `21.3.1-grl11`, which runs Java 11.** GraalVM CE 8 to 19 and Gluon GraalVM before 23 carry GraalVM's version numbers, and vfox matches a bare major against those, see [distributions.md](distributions.md#versions-numbered-after-graalvm). Write `java@21-tem`. ## Where the JDK is diff --git a/docs/versions.md b/docs/versions.md index d13d630..2e743fb 100644 --- a/docs/versions.md +++ b/docs/versions.md @@ -73,6 +73,8 @@ vfox uninstall java@21.0.8+9-tem If you name a build or a release, it does not cross over to another one (`21.0.12-tem` does not select `21.0.12.1+1-tem`). It does not cross to another distribution, between JavaFX and plain, or between early-access and GA either. A name that matches nothing is reported as `java@99-tem is not installed`. +vfox's own match for `21` goes by the version alone, so it also takes GraalVM CE 8 to 19 and Gluon GraalVM, whose versions are GraalVM's: `21.3.1-grl11` runs Java 11, and `vfox use java@21` selects it over `21.0.12.1+1-tem`. See [distributions.md](distributions.md#versions-numbered-after-graalvm). + Pick the scope with `vfox use`'s flags: `--global`, `--project` or `--session`, the default. In a shell without vfox's hook, Windows switches to the global scope with a warning, while Linux and macOS stop with `vfox requires hook support`. `--project` writes a `.vfox.toml` that holds the installed name (`java = "17.0.10+7-tem"`). A `.sdkmanrc` is read as well, see [sdkmanrc.md](sdkmanrc.md). ## Early-access builds @@ -91,7 +93,7 @@ The installed name uses Foojay's spelling, `28-ea+19`, and `vfox use java@28-ea+ ```bash vfox search java # OpenJDK, the default vfox search java tem # one distribution, short or long name -vfox search java all # every distribution, about 2,300 lines on Linux x64 +vfox search java all # every distribution, about 2,500 lines on Linux x64 ``` Each line is a name that can follow `java@`, newest first, with notes for LTS and JavaFX (see [javafx.md](javafx.md)) and a mark for versions that are installed: diff --git a/docs/zh-CN/changes.md b/docs/zh-CN/changes.md index 6182f40..d9d749a 100644 --- a/docs/zh-CN/changes.md +++ b/docs/zh-CN/changes.md @@ -2,7 +2,11 @@ [中文](changes.md) | [English](../changes.md) -按发布版本列出用户能感受到的变化。GitHub 的 Release 页面列出了对应的 PR。 +按发布版本列出用户能感受到的变化。GitHub 的 Release 页面列出了对应的 PR。写这篇文档时最新的发布版是 0.6.2,`main` 比它多出“未发布”下面的所有内容。想现在就用上这些变化,见 [install-from-source.md](install-from-source.md)。 + +## 未发布 + +- 新增 13 个发行版,Foojay 列出的发行版从此全都有了:AdoptOpenJDK(`adpt`、`adptj9`)、Eliya(`eliya`)、OJDKBuild(`ojdkbld`)、OpenLogic(`opnlgc`)、Red Hat(`rdht`)、Semeru 认证版(`semcrt`)、Gluon GraalVM(`gln`),以及基于 JDK 8 到 19 的 GraalVM CE(`grl8`、`grl11`、`grl16`、`grl17`、`grl19`)。Red Hat 从 tar.xz 包安装;Linux 上的 OJDKBuild、macOS 上的 OpenLogic 和 22.1 以前的 Gluon GraalVM 从 zip 包安装。`.sdkmanrc` 里写 SDKMAN 以前给它们的标识符也认,例如 `11.0.10.j9-adpt`、`22.3.3.r17-grl`。见 [distributions.md](distributions.md)。 ## 0.6.2(2026-10-18) diff --git a/docs/zh-CN/development.md b/docs/zh-CN/development.md index dd53847..799a0fb 100644 --- a/docs/zh-CN/development.md +++ b/docs/zh-CN/development.md @@ -13,7 +13,7 @@ hooks/env_keys.lua JAVA_HOME 和 PATH hooks/pre_use.lua vfox use:把输入映射到已安装的版本名 hooks/parse_legacy_file.lua .sdkmanrc lib/distribution_version.lua 发行版名称、版本写法的解析、GraalVM 特性版本的识别 -lib/foojay.lua 向 Foojay 发出的请求 +lib/foojay.lua 向 Foojay 发出的请求,以及对返回结果的修正 lib/installed_version.lua 与已安装的版本名做匹配 lib/loongnix.lua Loongnix 归档 tests/*_test.lua 离线的钩子测试 @@ -46,13 +46,15 @@ vfox 加载 `metadata.lua`,命令需要时调用相应的钩子,并向钩子 安装后的版本名是 `[-<简称>][-fx]`,OpenJDK 没有简称([versions.md](versions.md#安装后的版本名))。`lib/distribution_version.lua` 把一个写法解析成版本、发行版和 JavaFX 标志,两种顺序都接受(`21-tem`、`tem-21`)。`lib/installed_version.lua` 把用户输入的版本变成已安装的版本名:先看这个名字本身。只写大版本号时,取这个大版本里已安装的最新版本;其他写法则取这个版本本身,或它的最新构建。`PreUse` 到此为止。`ParseLegacyFile` 还会再退一步,取同一大版本里已安装的最新版本。 -SDKMAN 有些写法不同(`jbr`、`21.0.12.fx-zulu`、`21.0.12-fx+1.1-librca`、`28.0.0+ea.19-open`),`hooks/parse_legacy_file.lua` 里的 `plugin_spelling` 会在解析之前把它们改写成插件自己的写法。SDKMAN 给版本补的零由 `installed_version.unpad` 去掉(`27.0.0+36` 就是 `27+36`)。插件的简称沿用 SDKMAN 的,只有 `jb` 例外。 +SDKMAN 有些写法不同(`jbr`、`21.0.12.fx-zulu`、`21.0.12-fx+1.1-librca`、`28.0.0+ea.19-open`),`hooks/parse_legacy_file.lua` 里的 `plugin_spelling` 会在解析之前把它们改写成插件自己的写法。对 SDKMAN 已经不再提供的发行版,同一文件里的 `sdkman_flavours` 把 SDKMAN 写在版本号里的虚拟机或 JDK 版本换成简称(`22.3.3.r17-grl` 就是 `22.3.3-grl17`)。SDKMAN 给版本补的零由 `installed_version.unpad` 去掉(`27.0.0+36` 就是 `27+36`)。简称与 SDKMAN 不同的地方见 [distributions.md](distributions.md#简称与-sdkman-的不同)。 ## Foojay - 查询里的 `+` 必须做百分号编码。Foojay 会把没编码的 `+` 当成空格并丢掉构建号,`21.0.5+63130` 就会匹配 21.0.5 的所有构建。 - `version=21` 只是 GA 构建 `21+35`。只写大版本号时会加上 `latest=available`,才能拿到最新的 21.x。 - Windows 在同一次请求里同时要 `zip` 和 `tar.gz`。JetBrains Runtime 只为较新的构建提供 Windows 的 zip。同一版本两种都有时,`PreInstall` 取 zip。 +- 在其他系统上,有几个发行版的部分或全部版本没有 tar.gz,`lib/foojay.lua` 里的 `other_archive_type` 会为它们多要一种格式:Red Hat 要 `tar.xz`,OJDKBuild、OpenLogic 和 Gluon GraalVM 要 `zip`。这两种 vfox 都能解压,这些 zip 包也带着 Unix 权限,所以 `bin/java` 仍然可以执行。 +- `lib/foojay.lua` 里的 `fixes` 会在钩子拿到结果之前去掉一些包:Foojay 列在 OJDKBuild 的 Windows JDK 里的 JRE、installer bundle 包和 RHEL 6 构建,以及 Gluon GraalVM 22.x 的 JDK 11 构建,它们和 JDK 17 构建共用一个版本号。只写大版本号时,`latest=available` 每种格式只返回一个包,这个包可能正好是要去掉的,所以对这两个发行版,插件会再按那个版本完整地查一次。 - Foojay 里同一个名字有两条记录时,`Available` 只列一次。 - Foojay 把 GraalVM 每月发布的特性版本(`25.1.3` 起)标成 LTS。`lib/distribution_version.lua` 里的 `is_feature_release` 按次版本号识别它们,`Available` 去掉它们的备注。它只适用于 `graal` 和 `graalce`:Mandrel 和 Liberica NIK 在 24 及以前按自己的版本号编号(`mandrel` 的 `23.1.12` 就是 LTS),从 25 起沿用 JDK 的编号。 - 只有 Oracle GraalVM(`graal`)在只写大版本号时,`PreInstall` 才会跳过特性版本,所以装的是 25.0 系列。一个大版本里只有特性版本时,则保留它们。GraalVM 社区版不做这个过滤,因为特性版本就是它现在发布的全部。 @@ -70,7 +72,7 @@ go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/loongnix_test.lua go run github.com/yuin/gopher-lua/cmd/glua@v1.1.1 tests/post_install_test.lua ``` -请在仓库根目录运行。五个文件都会加载 `tests/support.lua`,它模拟 `vfox.strings`;`tests/pre_install_test.lua` 和 `tests/loongnix_test.lua` 还自己模拟了 `http` 和 `json`。`tests/pre_install_test.lua` 把 Foojay 的返回结果放在文件开头的一张表里,键是 `<发行版> [<版本>] []`,Windows 的前面再加 `windows`。新增用例需要的返回结果就加在那里,并注明观察到的日期。Lint、许可证头和容器测试见 [e2e.md](e2e.md#本地检查)。 +请在仓库根目录运行。五个文件都会加载 `tests/support.lua`,它模拟 `vfox.strings`;`tests/pre_install_test.lua` 和 `tests/loongnix_test.lua` 还自己模拟了 `http` 和 `json`。`tests/pre_install_test.lua` 把 Foojay 的返回结果放在文件开头的一张表里,键是 `<发行版> [<版本>] []`,Windows 和 macOS 的前面再分别加 `windows` 和 `macos`。新增用例需要的返回结果就加在那里,并注明观察到的日期。Lint、许可证头和容器测试见 [e2e.md](e2e.md#本地检查)。 想对着真实的 Foojay 调用单个钩子,可以用 vfox 1.0.13 及以后版本的 `vfox plugin run`。它不会注册插件,`--os` 和 `--arch` 可以模拟其他平台: @@ -85,40 +87,46 @@ vfox plugin run . ParseLegacyFile --input '{"filename":".sdkmanrc","filepath":"/ ## 添加发行版 1. 在 Foojay 里找到它的 id(见 [foojay.md](foojay.md)),并确认它在你关心的平台上有包。 -2. 在 `lib/distribution_version.lua` 的 `short_name` 里加一行 `["<简称>"] = ""`。SDKMAN 有这个发行版的话,用 SDKMAN 的标识符。SDKMAN 写法不同的话,在 `hooks/parse_legacy_file.lua` 的 `plugin_spelling` 里做映射。 -3. 如果它的版本号或 LTS 标记需要特殊处理,像 GraalVM 那样,就在 `hooks/available.lua` 和 `hooks/pre_install.lua` 里处理。 +2. 在 `lib/distribution_version.lua` 的 `short_name` 里加一行 `["<简称>"] = ""`。SDKMAN 现在或以前有这个发行版的话,用 SDKMAN 的标识符;没有的话,照 SDKMAN 的习惯起一个:短的厂商名保持原样,长的要缩短,多半是去掉元音(`opnlgc`)。SDKMAN 写法不同的话,在 `hooks/parse_legacy_file.lua` 的 `plugin_spelling` 里做映射,并把这个差别补进 [distributions.md](distributions.md#简称与-sdkman-的不同)。 +3. 如果它的版本号或 LTS 标记需要特殊处理,像 GraalVM 那样,就在 `hooks/available.lua` 和 `hooks/pre_install.lua` 里处理。如果它在 Windows 以外的系统上没有 tar.gz,就把它的格式加进 `lib/foojay.lua` 的 `other_archive_type`;如果 Foojay 给它列的包有的不能照原样安装,就在同一文件的 `fixes` 里加一条修正。 4. 在 `tests/pre_install_test.lua` 里加一个用例。 5. 更新 `README.md`、[distributions.md](distributions.md) 和 [platforms.md](platforms.md) 里的表,以及对应的中文版(`README_CN.md` 和 `docs/zh-CN/` 下的同名页面)。 -6. 如果引入了新的代码路径,也要加进 e2e 矩阵([e2e.md](e2e.md))。矩阵之外的发行版仍会运行所有检查,只是跳过 `java.vendor` 断言和 asdf 风格的 `PreUse` 写法。 +6. 如果引入了新的代码路径,也要加进 e2e 矩阵([e2e.md](e2e.md))。矩阵之外的发行版仍会运行所有检查,只是跳过 `java.vendor` 断言和 asdf 风格的 `PreUse` 写法。只新增名字、没有新代码路径的发行版,则改加进 `tests/e2e/common/common.go` 的 `nameOnly`,并写上 Foojay 有它的那些 runner 平台。 ## 更新平台表 -[platforms.md](platforms.md) 的数据取自 Foojay。下面的命令用 8 次请求,按平台打印有构建的发行版: +[platforms.md](platforms.md) 的数据取自 Foojay。下面的命令用 14 次请求,按平台打印有构建的发行版。在 Windows 以外的平台上,每个平台的第二次请求和插件一样,查 Red Hat、OJDKBuild、OpenLogic 和 Gluon GraalVM 在那里除 tar.gz 以外提供的格式: ```bash base='https://api.foojay.io/disco/v3.0/packages/jdks?directly_downloadable=true&latest=per_distro' while read -r name query; do printf '%-14s ' "$name" - curl -s "$base&$query" | jq -r '.result[].distribution' | sort -u | tr '\n' ' '; echo + { + curl -s "$base&$query&archive_type=tar.gz" | jq -r '.result[].distribution' + case $name in windows-*) ;; *) + curl -s "$base&$query&archive_type=tar.xz&archive_type=zip" | jq -r '.result[].distribution + | select(. == "redhat" or . == "ojdk_build" or . == "openlogic" or . == "gluon_graalvm")' ;; + esac + } | sort -u | tr '\n' ' '; echo done <<'EOF' -linux-x64 architecture=amd64&operating_system=linux&lib_c_type=glibc&archive_type=tar.gz -linux-arm64 architecture=aarch64&operating_system=linux&lib_c_type=glibc&archive_type=tar.gz -alpine-x64 architecture=amd64&operating_system=linux&lib_c_type=musl&archive_type=tar.gz -alpine-arm64 architecture=aarch64&operating_system=linux&lib_c_type=musl&archive_type=tar.gz -macos-intel architecture=amd64&operating_system=macos&archive_type=tar.gz -macos-arm64 architecture=aarch64&operating_system=macos&archive_type=tar.gz -windows-x64 architecture=x64&operating_system=windows&archive_type=zip&archive_type=tar.gz -windows-arm64 architecture=aarch64&operating_system=windows&archive_type=zip&archive_type=tar.gz +linux-x64 architecture=amd64&operating_system=linux&lib_c_type=glibc +linux-arm64 architecture=aarch64&operating_system=linux&lib_c_type=glibc +alpine-x64 architecture=amd64&operating_system=linux&lib_c_type=musl +alpine-arm64 architecture=aarch64&operating_system=linux&lib_c_type=musl +macos-intel architecture=amd64&operating_system=macos +macos-arm64 architecture=aarch64&operating_system=macos +windows-x64 architecture=x64&operating_system=windows&archive_type=zip +windows-arm64 architecture=aarch64&operating_system=windows&archive_type=zip EOF ``` -id 是 Foojay 的(`oracle_open_jdk` 对应 `open`)。“只有部分版本”一节里的说明,需要对每个发行版、每个平台单独查询,不带 `latest`,再按 `major_version` 分组。 +id 是 Foojay 的(`oracle_open_jdk` 对应 `open`)。这段命令在 Linux arm64 和 Windows x64 上也会打印 `redhat`,但这些下载都返回 404,所以表里没有算进去。“只有部分版本”一节里的说明,需要对每个发行版、每个平台单独查询,不带 `latest`,再按 `major_version` 分组。 ## 已知限制 - 下载内容没有校验,见上文。 - `vfox search` 只列 GA 版本。EA 构建要自己写出名字来安装。 -- 插件不提供没有简称的 Foojay 发行版([distributions.md](distributions.md#foojay-有但插件没有提供的发行版))和 JRE 包。 +- 插件不提供 JRE 包,也不提供 Gluon GraalVM 22.x 的 JDK 11 构建。 - 只有 Linux loong64 有 Foojay 以外的来源。 ## 发布 diff --git a/docs/zh-CN/distributions.md b/docs/zh-CN/distributions.md index 616eeb7..b874848 100644 --- a/docs/zh-CN/distributions.md +++ b/docs/zh-CN/distributions.md @@ -2,33 +2,56 @@ [中文](distributions.md) | [English](../distributions.md) -插件从 [Foojay](foojay.md) 获取下面 18 个发行版的版本列表和下载链接。凡是要写发行版的地方,简称和长名都可以:`21-tem`、`21-temurin`、`temurin-21`、`vfox search java tem`。 +插件从 [Foojay](foojay.md) 获取下面 31 个发行版的版本列表和下载链接,2026-10-20 时 Foojay 列出的发行版全在这里。凡是要写发行版的地方,简称和长名都可以:`21-tem`、`21-temurin`、`temurin-21`、`vfox search java tem`。 + +未发布:0.6.2 没有 `adpt`、`adptj9`、`eliya`、`gln`、`grl8`、`grl11`、`grl16`、`grl17`、`grl19`、`ojdkbld`、`opnlgc`、`rdht` 和 `semcrt`。对这些发行版,0.6.2 的 `vfox install` 会报 `Could not extract a valid distribution`,`vfox search` 会报 `Unsupported distribution`。 | 简称 | 长名 | 发行版 | 维护方 | | --- | --- | --- | --- | -| `open` | `openjdk` | jdk.java.net 上的 OpenJDK 构建 | Oracle,代表 OpenJDK 项目 | -| `tem` | `temurin` | Temurin | Eclipse Adoptium | -| `zulu` | `zulu` | Zulu | Azul | -| `librca` | `liberica` | Liberica | BellSoft | -| `amzn` | `corretto` | Corretto | Amazon | -| `ms` | `microsoft` | Microsoft Build of OpenJDK | Microsoft | -| `oracle` | `oracle` | Oracle JDK | Oracle | -| `sem` | `semeru` | Semeru Runtimes 开放版 | IBM | -| `sapmchn` | `sap_machine` | SapMachine | SAP | -| `kona` | `kona` | 腾讯 Kona JDK | 腾讯 | +| `adpt` | `aoj` | AdoptOpenJDK(HotSpot) | AdoptOpenJDK | +| `adptj9` | `aoj_openj9` | AdoptOpenJDK(OpenJ9) | AdoptOpenJDK | | `albba` | `dragonwell` | 阿里巴巴 Dragonwell | 阿里巴巴 | +| `amzn` | `corretto` | Corretto | Amazon | | `bsg` | `bisheng` | 毕昇 JDK(BiSheng) | 华为 | +| `eliya` | `eliya` | Eliya JDK | Asymm Systems | +| `gln` | `gluon_graalvm` | Gluon GraalVM | Gluon | | `graal` | `graalvm` | Oracle GraalVM | Oracle | | `graalce` | `graalvm_community` | GraalVM 社区版 | GraalVM 项目 | -| `nik` | `liberica_native` | Liberica Native Image Kit | BellSoft | -| `mandrel` | `mandrel` | Mandrel | Red Hat | +| `grl8` | `graalvm_ce8` | 基于 JDK 8 的 GraalVM CE | GraalVM 项目 | +| `grl11` | `graalvm_ce11` | 基于 JDK 11 的 GraalVM CE | GraalVM 项目 | +| `grl16` | `graalvm_ce16` | 基于 JDK 16 的 GraalVM CE | GraalVM 项目 | +| `grl17` | `graalvm_ce17` | 基于 JDK 17 的 GraalVM CE | GraalVM 项目 | +| `grl19` | `graalvm_ce19` | 基于 JDK 19 的 GraalVM CE | GraalVM 项目 | | `jb` | `jetbrains` | JetBrains Runtime | JetBrains | +| `kona` | `kona` | 腾讯 Kona JDK | 腾讯 | +| `librca` | `liberica` | Liberica | BellSoft | +| `mandrel` | `mandrel` | Mandrel | Red Hat | +| `ms` | `microsoft` | Microsoft Build of OpenJDK | Microsoft | +| `nik` | `liberica_native` | Liberica Native Image Kit | BellSoft | +| `ojdkbld` | `ojdk_build` | OJDKBuild | 社区 | +| `open` | `openjdk` | jdk.java.net 上的 OpenJDK 构建 | Oracle,代表 OpenJDK 项目 | +| `opnlgc` | `openlogic` | OpenLogic OpenJDK | OpenLogic | +| `oracle` | `oracle` | Oracle JDK | Oracle | +| `rdht` | `redhat` | Red Hat build of OpenJDK | Red Hat | +| `sapmchn` | `sap_machine` | SapMachine | SAP | +| `sem` | `semeru` | Semeru Runtimes 开放版 | IBM | +| `semcrt` | `semeru_certified` | Semeru Runtimes 认证版 | IBM | +| `tem` | `temurin` | Temurin | Eclipse Adoptium | | `trava` | `trava` | TravaOpenJDK | 社区 | +| `zulu` | `zulu` | Zulu | Azul | -长名就是 Foojay 接受的发行版名,只有 `openjdk` 例外:Foojay 里它叫 Oracle OpenJDK,`openjdk` 只是它认的同义词。简称沿用 SDKMAN 的,只有 `jb` 不同(SDKMAN 里叫 `jbr`);`.sdkmanrc` 里 `jbr` 和 `jb` 都认,见 [sdkmanrc.md](sdkmanrc.md)。`lnxabi1` 和 `lnxabi2` 不来自 Foojay,所以不在表里,见 [loongnix.md](loongnix.md)。 +长名就是 Foojay 接受的发行版名,只有 `openjdk` 例外:Foojay 里它叫 Oracle OpenJDK,`openjdk` 只是它认的同义词。`lnxabi1` 和 `lnxabi2` 不来自 Foojay,所以不在表里,见 [loongnix.md](loongnix.md)。 各发行版覆盖哪些操作系统和 CPU,见 [platforms.md](platforms.md)。`vfox search java <名字>` 列出的是你这台机器上能装的版本。安装后的版本名带简称,OpenJDK 例外,它没有后缀(见 [versions.md](versions.md))。 +## 简称与 SDKMAN 的不同 + +简称沿用 [SDKMAN](https://sdkman.io/) 的标识符,Temurin 21.0.8 在两边都写作 `21.0.8-tem`。下面是与 SDKMAN 不同的地方,对照的是 2026-10-20 的 SDKMAN 列表: + +- JetBrains Runtime 叫 `jb`,SDKMAN 里叫 `jbr`;毕昇 JDK 叫 `bsg`,SDKMAN 里叫 `bisheng`,也就是插件给它的长名。`.sdkmanrc` 里写 SDKMAN 的叫法也认,见 [sdkmanrc.md](sdkmanrc.md)。 +- Dragonwell、TravaOpenJDK、AdoptOpenJDK、Gluon GraalVM 和按 GraalVM 自身编号的 GraalVM CE,SDKMAN 都已经不再提供。后三个在 SDKMAN 里曾叫 `adpt`、`gln` 和 `grl`,当时把虚拟机或 JDK 版本写进版本号:HotSpot 版是 `11.0.10.hs-adpt`,OpenJ9 版是 `11.0.10.j9-adpt`,基于 JDK 17 的是 `22.3.3.r17-grl`。插件给 Foojay 的每个发行版各起一个名字,所以这部分挪进了简称:`11.0.10-adpt`、`11.0.10-adptj9`、`22.3.3-grl17`。`.sdkmanrc` 里用 SDKMAN 的旧写法也能选中它们。 +- Eliya、OJDKBuild、OpenLogic、Red Hat 和 Semeru 认证版在 SDKMAN 里没有标识符,简称是插件按 SDKMAN 的习惯起的:短的厂商名保持原样(`eliya`,类似 `zulu`),长的要缩短,多半是去掉元音(`ojdkbld`、`opnlgc`、`rdht`,类似 `librca`、`sapmchn`)。`semcrt` 是 SDKMAN 的 `sem` 加上 certified。Eliya 自己的安装说明里写着 `sdk install java 25.0.3-eliya`,它的网站也说正在向 SDKMAN 申请,但 SDKMAN 的列表里并没有它。 + ## OpenJDK 构建 ### OpenJDK(`open`) @@ -61,7 +84,7 @@ ### Semeru(`sem`) -[IBM](https://developer.ibm.com/languages/java/semeru-runtimes/) 的运行时:OpenJDK 类库搭配 Eclipse OpenJ9 虚拟机,不是 HotSpot。只提供开放版,不提供 Foojay 里的 `semeru_certified`。 +[IBM](https://developer.ibm.com/languages/java/semeru-runtimes/) 的运行时:OpenJDK 类库搭配 Eclipse OpenJ9 虚拟机,不是 HotSpot。这是开放版,认证版是 `semcrt`,见[下文](#semeru-认证版semcrt)。 ### SapMachine(`sapmchn`) @@ -79,6 +102,30 @@ [华为](https://www.hikunpeng.com/developer/devkit/compilation_debugging?data=JDK)的 OpenJDK 构建,面向 ARM 服务器。覆盖 Java 8、11、17、21 和 25,只有 Linux 版本。 +### AdoptOpenJDK(`adpt`、`adptj9`) + +[AdoptOpenJDK](https://adoptopenjdk.net/) 项目并入 Eclipse 基金会之前的构建,虚拟机用 HotSpot(`adpt`)或 Eclipse OpenJ9(`adptj9`)。覆盖 Java 8 到 16,到 2021 年为止。Foojay 把两者都标为不再维护。HotSpot 构建由 Temurin(`tem`)接替,OpenJ9 构建由 Semeru(`sem`)接替。 + +### Eliya(`eliya`) + +[Asymm Systems](https://asymm.systems/product/eliya) 的 OpenJDK 25 构建,加上 `-XX:EliyaProfile=Production` 会打开一组面向生产环境的设置,例如 `OutOfMemoryError` 时导出堆转储。Foojay 只列了一个版本 25.0.3,平台是 Linux x64 和 arm64。 + +### OJDKBuild(`ojdkbld`) + +[ojdkbuild](https://github.com/ojdkbuild/ojdkbuild) 项目的构建:Windows x64 上有 Java 8 到 15 和 17,Linux x64 上有 8 和 11,都是 zip 包。这个项目 2022 年发布 17.0.3 后就停止了。Foojay 在它的 Windows JDK 里还混着 JRE、installer bundle 包和给 Linux 的 RHEL 6 构建,插件会把这些排除掉。 + +### OpenLogic(`opnlgc`) + +[OpenLogic](https://www.openlogic.com/openjdk-downloads) 的 OpenJDK 构建。覆盖 Java 8、11、17、21、22 和 25,有 Linux x64、Intel Mac 和 Windows x64 的版本。macOS 版是 zip 包。 + +### Red Hat build of OpenJDK(`rdht`) + +[Red Hat](https://developers.redhat.com/products/openjdk/overview) 的便携版构建。Linux x64 上有 Java 8、11、17 和 21,是 tar.xz 包。Foojay 里最新的是 21.0.8(2025 年 7 月)。它也列了几个 Linux arm64 的构建和一个 Windows 的,但下载都返回 404(`source file not found`),Linux x64 的 11.0.15 和 11.0.16 也一样。 + +### Semeru 认证版(`semcrt`) + +IBM Semeru Runtime Certified Edition:Semeru 的 OpenJ9 运行时,通过了 Java 兼容性测试套件(JCK)认证,采用 IBM 的许可证,不是开源许可证。覆盖 Java 11、17、21 和 25。Foojay 里没有它的 macOS 和 Windows 版本。 + ## GraalVM 系列 ### Oracle GraalVM(`graal`) @@ -99,6 +146,18 @@ GraalVM 的开源版本,基于 OpenJDK。 Mandrel 和 Liberica NIK 在 24 及以前用自己的版本号体系(Mandrel 的 `23.1.12`),从 25 起沿用 JDK 的版本号(`25.0.4.1`)。 +### GraalVM CE 8 到 19(`grl8`、`grl11`、`grl16`、`grl17`、`grl19`) + +22.3 及以前的 GraalVM 社区版,那时它还没有改用 JDK 的版本号。Foojay 按 JDK 分成了几个发行版:`grl8`(GraalVM 19.3 到 21.3.1)、`grl11`(19.3 到 22.3.3)、`grl16`(21.1 和 21.2)、`grl17`(21.3 到 22.3.3)和 `grl19`(22.3 和 22.3.1)。之后接替它们的是 GraalVM 社区版(`graalce`)。 + +### Gluon GraalVM(`gln`) + +[Gluon](https://docs.gluonhq.com/#_graalvm) 的 GraalVM 构建,用来把 JavaFX 应用编译成原生镜像。21.1 和 21.2 基于 JDK 11。22.x(22 到 22.1.0.1)同一个版本号下有 JDK 11 和 JDK 17 两个构建,插件装的是 JDK 17 的。23+25 是基于 JDK 23 的开发构建。有 Linux x64、macOS 和 Windows x64 的版本,Apple Silicon 从 22.1.0.1 起才有。 + +### 按 GraalVM 编号的版本 + +GraalVM CE 8 到 19,以及 23 以前的 Gluon GraalVM,版本号是 GraalVM 自己的,不是 Java 的:`22.3.3-grl17` 是 GraalVM 22.3.3,运行的是 Java 17.0.8;`21.3.1-grl11` 运行的是 Java 11。对只写大版本号的写法,vfox 只按版本号匹配,不分发行版,取以它开头的最高已安装版本,所以同时装了 `21.3.1-grl11` 和 `21.0.12.1+1-tem` 时,`vfox use java@21` 选中的是 `21.3.1-grl11`。请写上发行版,比如 `java@21-tem`。 + ### Oracle GraalVM 与 GraalVM 社区版的行为 - 从 25.1(2026 年 6 月)起,GraalVM 在 25.0 系列之外每月发布一个特性版本(feature release):`25.1.3`、`25.2.4`、`25.3.4.1`、`25.4.4.1`,每个大约一个月后就被下一个取代。它们基于的 JDK 是 LTS,所以 Foojay 也把它们标成了 LTS,而 `vfox search` 不给它们加 LTS 备注。 @@ -116,7 +175,3 @@ JetBrains 各 IDE 运行所用的 [OpenJDK 分支](https://github.com/JetBrains/ ### TravaOpenJDK(`trava`) [带 DCEVM 的 OpenJDK](https://github.com/TravaOpenJDK),附带 HotswapAgent,用于在运行中的程序里替换类。覆盖 Java 8 和 11。Foojay 把它标为不再维护。它没有 Apple Silicon 的构建,Linux arm64 上只有一个(`11.0.10+6`)。 - -## Foojay 有但插件没有提供的发行版 - -Foojay 列出的发行版比上面这 18 个多:`aoj` 和 `aoj_openj9`(AdoptOpenJDK,已由 Temurin 和 Semeru 接替)、`eliya`、`gluon_graalvm`、`graalvm_ce8`、`graalvm_ce11`、`graalvm_ce16`、`graalvm_ce17`、`graalvm_ce19`(GraalVM 社区版的旧版本)、`ojdk_build`、`openlogic`、`redhat` 和 `semeru_certified`。它们在这里没有简称,所以 `vfox install java@21-openlogic` 会报 `Could not extract a valid distribution`。添加新发行版的方法见 [development.md](development.md#添加发行版)。 diff --git a/docs/zh-CN/e2e.md b/docs/zh-CN/e2e.md index c85b1d8..4852c27 100644 --- a/docs/zh-CN/e2e.md +++ b/docs/zh-CN/e2e.md @@ -33,23 +33,24 @@ Windows 容器的覆盖(`tests/e2e/windows`)无法在开发容器里运行 1. 从指定的渠道安装 vfox,要么是最新发布版(`latest`),要么从源码构建(`main`),然后从当前检出的代码注册本地的 `java` 插件。在 Windows 上,runner 会在 `latest` 组合运行期间把 `main` 构建一次,`main` 的容器由 e2e 镜像加上这个 `vfox.exe` 启动。 2. 只写发行版不写版本,无论单独写还是跟在空版本后面(`java@tem`、`java@-tem`),`vfox install` 和 `vfox use` 都应失败,并提示补上版本。以前,`java@tem` 会让钩子报 Lua 错误;`java@-tem` 则让 `PreInstall` 把空版本发给 Foojay,Foojay 列出所有版本,结果装上了最新的。没有任何发行版发布过的版本(`<大版本>.0.99`)应该安装失败,并且 `PreInstall` 要指出它搜索的平台(`linux/amd64`、`windows/arm64` 等),以此确认向 Foojay 查询的就是 runner 所在的平台。已固定版本里从未发布过的构建(`<版本>+99`,例如 `21.0.8+99-tem`)也一样,这证明查询保留了构建号:Foojay 会把没编码的 `+` 当成空格并丢掉构建号,于是会装上这个版本的最新构建。 3. 在 `graalce` 这一行里,Oracle GraalVM 只写大版本号的 `25-graal` 应该装 25.0 系列的最新构建(`25.0.4.1-graal`),也就是 Oracle 官方 `25/latest` 下载跟的那个系列,而不是 Foojay 列在它前面的某个每月特性版本(比如 `25.4.4.1-graal`)。`vfox search java graal` 列出的 25 的各构建会先被模拟成已安装,这样 `vfox install` 报出的就是 `PreInstall` 选中的那个,而且不会下载任何东西。GA 版本 25 不放进去,因为那样 vfox 会发现 `25-graal` 已安装,根本不会去问 `PreInstall`。 -4. 固定的版本按 `PreInstall` 给它起的名字安装:请求的版本加上构建号(`21.0.8-tem` 安装为 `21.0.8+9-tem`)。`vfox search java <发行版>`(`Available` 钩子)把同一个名字列为已安装,带 JavaFX 的构建会标注 JavaFX。对 GraalVM,它还必须列出自 25.1 起每月发布的特性版本(`25.4.4.1-graalce`),这些版本都不标 LTS(Foojay 标了,因为它们基于的 JDK 是 LTS);每个版本大约只存在一个月。在 Windows 上,列表里要包含 JetBrains Runtime 21.0.5,它在 Windows 上只有 tar.gz。 -5. 在执行任何 `vfox use` 之前,`.sdkmanrc` 要能通过 `ParseLegacyFile` 选中 JDK。测试时,`vfox list java` 里排在最前面的是另一个版本的空安装(`21.0.80+1-tem`,它的版本号以固定的版本开头;vfox 按字符串降序给已安装版本排序)。以前 `ParseLegacyFile` 会把它当成第一个以该版本开头的版本,对补零的版本(见下面第二条),则当成该大版本里最新的版本。要覆盖的写法有: +4. 在 `tem` 这几行里(这几行在每个 runner 上都会运行),只按名字检查的发行版(`adpt` 到 `semcrt`,即 `tests/e2e/common` 里的 `nameOnly`),只要 Foojay 在这个 runner 上有它的包,都要能用简称找到:`vfox search java <简称>` 能列出它;把它列出的最新版本模拟成已安装后,`vfox install java@<大版本>-<简称>`(`22-grl17`)要报告这个版本已经安装,所以不会下载任何东西。以前没有这些简称时,这两条命令分别报 `Unsupported distribution` 和 `Could not extract a valid distribution`。 +5. 固定的版本按 `PreInstall` 给它起的名字安装:请求的版本加上构建号(`21.0.8-tem` 安装为 `21.0.8+9-tem`)。`vfox search java <发行版>`(`Available` 钩子)把同一个名字列为已安装,带 JavaFX 的构建会标注 JavaFX。对 GraalVM,它还必须列出自 25.1 起每月发布的特性版本(`25.4.4.1-graalce`),这些版本都不标 LTS(Foojay 标了,因为它们基于的 JDK 是 LTS);每个版本大约只存在一个月。在 Windows 上,列表里要包含 JetBrains Runtime 21.0.5,它在 Windows 上只有 tar.gz。 +6. 在执行任何 `vfox use` 之前,`.sdkmanrc` 要能通过 `ParseLegacyFile` 选中 JDK。测试时,`vfox list java` 里排在最前面的是另一个版本的空安装(`21.0.80+1-tem`,它的版本号以固定的版本开头;vfox 按字符串降序给已安装版本排序)。以前 `ParseLegacyFile` 会把它当成第一个以该版本开头的版本,对补零的版本(见下面第二条),则当成该大版本里最新的版本。要覆盖的写法有: - 不含构建号的 SDKMAN 标识符:`java=21.0.8-tem`、`java=21.0.5-jbr`(SDKMAN 对 JetBrains 的叫法)、`java=25.0.4.fx-librca`(它对 JavaFX 构建的写法)。 - 补零的标识符,`sdk list java` 里有很多这样的:`java=21.0.8.0+9-tem`、`java=25.0.4.0-fx+9-librca`(Foojay 以及安装后的版本名里没有这个零)。 - 安装后的版本名:`java=21.0.8+9-tem`。 - EA 构建的标识符。固定大版本的 EA 构建,如果按 `sdk list java` 里 OpenJDK 的写法来写(`28.0.0.0+ea.20-open`),必须选中那个 EA 构建:`java=21.0.0.0+ea.1-tem` 要选中 `21-ea+1-tem`,不能选中 GA 版本。`ParseLegacyFile` 只认 SDKMAN 较旧的 `21.ea.1-tem` 写法时,选中的正是 GA 版本。安装后的版本名本身(`java=21-ea+1-tem`)也要能选中:`ParseLegacyFile` 以前解析不了它,什么也没选中,而 `vfox use` 是能选中的。 jdk.java.net 会在几周内撤掉每个 EA 构建,所以这个安装是模拟出来的:它的 `bin` 里放着一个只打印名字的替身 `java`。在 Windows 上,文件用 CRLF 换行写入。 -6. `vfox use --global` 之后,`PATH` 上的 JDK 要报告请求的 `java.version`、runner 的 `os.arch`(`amd64` / `aarch64`,这也能抓出在 Windows ARM64 上模拟运行的 x64 JDK)和这个发行版的 `java.vendor`。`JAVA_HOME` 指向同一个 JDK,`javac` 能编译一个程序,`java` 能运行它,模块列表恰好在 `-fx` 构建里含有 JavaFX,`vfox current java` 报告已安装的版本。事先设置的 `GRAALVM_HOME` 保持原值,因为用户会把它指向自己的 GraalVM;对 GraalVM,插件以前会把它替换成正在使用的 JDK。 -7. `PreUse` 把用户输入的各种写法映射到已安装的版本,不需要再次下载:只写大版本号(`java@21`,交给 vfox 核心做模糊匹配)、安装时用的写法(`java@21.0.8-tem`,`PreUse` 会在已安装的版本里找到它的构建号),以及 asdf 风格的 `<长名>-<版本>[-fx]`(`java@temurin-21.0.8+9` 改写成 `21.0.8+9-tem`;`java@openjdk-25.0.2+10` 改写成 `25.0.2+10`)。SDKMAN 那样补零的版本也一样(`java@21.0.8.0-tem`、`java@21.0.8.0+9-tem`),`vfox install` 必须先发现它们已经安装:`PreInstall` 把零原样交给了 Foojay,Foojay 会去掉它,而 `PreUse` 以前去找以补零版本开头的已安装版本,报告说没有安装。 +7. `vfox use --global` 之后,`PATH` 上的 JDK 要报告请求的 `java.version`、runner 的 `os.arch`(`amd64` / `aarch64`,这也能抓出在 Windows ARM64 上模拟运行的 x64 JDK)和这个发行版的 `java.vendor`。`JAVA_HOME` 指向同一个 JDK,`javac` 能编译一个程序,`java` 能运行它,模块列表恰好在 `-fx` 构建里含有 JavaFX,`vfox current java` 报告已安装的版本。事先设置的 `GRAALVM_HOME` 保持原值,因为用户会把它指向自己的 GraalVM;对 GraalVM,插件以前会把它替换成正在使用的 JDK。 +8. `PreUse` 把用户输入的各种写法映射到已安装的版本,不需要再次下载:只写大版本号(`java@21`,交给 vfox 核心做模糊匹配)、安装时用的写法(`java@21.0.8-tem`,`PreUse` 会在已安装的版本里找到它的构建号),以及 asdf 风格的 `<长名>-<版本>[-fx]`(`java@temurin-21.0.8+9` 改写成 `21.0.8+9-tem`;`java@openjdk-25.0.2+10` 改写成 `25.0.2+10`)。SDKMAN 那样补零的版本也一样(`java@21.0.8.0-tem`、`java@21.0.8.0+9-tem`),`vfox install` 必须先发现它们已经安装:`PreInstall` 把零原样交给了 Foojay,Foojay 会去掉它,而 `PreUse` 以前去找以补零版本开头的已安装版本,报告说没有安装。 默认矩阵对每个发行版都跑两个 vfox 渠道(`latest`、`main`): | 发行版 | 版本 | 覆盖内容 | amd64 | arm64 | | ------------ | ------- | ---------------------------------------------------------------------------- | ----- | ----- | | `open` | 25.0.2 | 默认发行版,版本不带后缀 | ✓ | | -| `tem` | 21.0.8 | 常规路径(Linux 上是 tar.gz,Windows 上是 zip) | ✓ | ✓ | +| `tem` | 21.0.8 | 常规路径(Linux 上是 tar.gz,Windows 上是 zip);只按名字检查的那些发行版 | ✓ | ✓ | | `librca-fx` | 25.0.4 | 带 JavaFX 的构建(`-fx`) | ✓ | ✓ | | `jb` | 21.0.5 | Windows 上走 tar.gz 的路径,那里没有 zip | ✓ | ✓ | | `graalce` | 25.0.2 | 事先设置的 `GRAALVM_HOME` 保持原值;Oracle GraalVM 的 `25-graal` | ✓ | | diff --git a/docs/zh-CN/foojay.md b/docs/zh-CN/foojay.md index 250684b..b0a4d72 100644 --- a/docs/zh-CN/foojay.md +++ b/docs/zh-CN/foojay.md @@ -27,14 +27,14 @@ https://api.foojay.io/disco/v3.0/packages/jdks | `version` | `vfox search` 时为空,否则是你输入内容里的版本部分。`+` 会做百分号编码,因为 Foojay 会把没编码的 `+` 当成空格,进而丢掉构建号。`28.ea.19` 会变成 `28-ea+19` | | `architecture` | arm64 用 `aarch64`,Windows x64 用 `x64`,其他系统的 x64 用 `amd64`,其他 CPU 用 vfox 报告的名字 | | `operating_system` | `linux`、`macos` 或 `windows` | -| `archive_type` | `tar.gz`;Windows 上是 `zip` 加 `tar.gz` | +| `archive_type` | `tar.gz`;Windows 上是 `zip` 加 `tar.gz`。其他系统上,Red Hat 还要 `tar.xz`,OJDKBuild、OpenLogic 和 Gluon GraalVM 还要 `zip` | | `lib_c_type` | Linux 上是 `glibc` 或 `musl`,其他系统为空 | | `directly_downloadable` | 始终是 `true` | | `latest` | `available`,仅当版本只有大版本号(如 `21`)时才加 | 不加 `latest=available` 时,`version=21` 只匹配 21 的 GA 构建(`21+35`);加上之后,Foojay 会挑出最新的 21.x,`java@21-tem` 装的就是它。更具体的版本则按原样匹配。 -返回的是一个包列表。插件用 `java_version` 给版本命名;`javafx_bundled` 为真时加上 `-fx`;`term_of_support` 是 `lts` 时标注 LTS;在 Windows 上,同一版本既有 `zip` 又有 `tar.gz` 时优先用 `zip`。安装时,插件再取这个包的 `links.pkg_info_uri`,并从其中的 `direct_download_uri` 下载,那是厂商自己的服务器(Temurin 是 GitHub Releases)。这条记录里还有 `checksum`,但插件没有把它交给 vfox,所以 vfox 会打印 `WARNING: Checksum is not provided, skip verify...`,下载内容不做校验。 +返回的是一个包列表。插件用 `java_version` 给版本命名;`javafx_bundled` 为真时加上 `-fx`;`term_of_support` 是 `lts` 时标注 LTS;在 Windows 上,同一版本既有 `zip` 又有 `tar.gz` 时优先用 `zip`。Foojay 混在 OJDKBuild 的 Windows JDK 里的 JRE、installer bundle 包和 RHEL 6 构建,以及 Gluon GraalVM 22.x 的 JDK 11 构建,插件都会略过,见 [distributions.md](distributions.md)。安装时,插件再取这个包的 `links.pkg_info_uri`,并从其中的 `direct_download_uri` 下载,那是厂商自己的服务器(Temurin 是 GitHub Releases)。这条记录里还有 `checksum`,但插件没有把它交给 vfox,所以 vfox 会打印 `WARNING: Checksum is not provided, skip verify...`,下载内容不做校验。 `vfox search` 与原始列表有几处不同:Foojay 里同一个名字有两条记录时,它只列一次;不给 GraalVM 的特性版本加 LTS 备注(见 [distributions.md](distributions.md#oracle-graalvm-与-graalvm-社区版的行为));只列 GA 版本。 @@ -66,7 +66,7 @@ zulu | macOS Intel | `architecture=amd64&operating_system=macos&archive_type=tar.gz` | | Windows x64 | `architecture=x64&operating_system=windows&archive_type=zip&archive_type=tar.gz` | -返回结果里包含插件没有提供的发行版,名单见 [distributions.md](distributions.md#foojay-有但插件没有提供的发行版)。 +返回结果里的名字就是 [distributions.md](distributions.md) 里的长名,只有 `oracle_open_jdk` 例外,插件里叫它 `openjdk`(`open`)。只写 `archive_type=tar.gz` 时,结果里会缺 Linux 上的 Red Hat 和 OJDKBuild、macOS 上的 OpenLogic,因为它们在那里提供的是 tar.xz 或 zip 包。插件会为它们额外请求这些格式,见上面的表。 ## 我的平台上哪些发行版有某个版本 diff --git a/docs/zh-CN/platforms.md b/docs/zh-CN/platforms.md index 97d58de..6645f04 100644 --- a/docs/zh-CN/platforms.md +++ b/docs/zh-CN/platforms.md @@ -8,28 +8,41 @@ No JDK found for 21-bsg on darwin/arm64. Please check available versions with 'vfox search java' ``` -下表列出各发行版有哪些平台的包,数据取自 2026-10-18 的 Foojay。打勾表示 Foojay 在这个平台上至少列有一个插件能安装的包,短横线表示一个也没有。 +下表列出各发行版有哪些平台的包,数据取自 2026-10-18 的 Foojay,从 AdoptOpenJDK 起的各行是 2026-10-20 补上的。✅ 表示 Foojay 在这个平台上至少列有一个插件能安装的包,❌ 表示一个也没有。未发布:0.6.2 只有到 Trava 为止的那些行。 | 发行版 | Linux x64 | Linux arm64 | Alpine x64 | Alpine arm64 | macOS Intel | macOS Apple Silicon | Windows x64 | Windows arm64 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| OpenJDK(`open`) | ✓ | ✓ | – | – | ✓ | ✓ | ✓ | – | -| Temurin(`tem`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Zulu(`zulu`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Liberica(`librca`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Corretto(`amzn`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – | -| Microsoft(`ms`) | ✓ | ✓ | ✓ | – | ✓ | ✓ | ✓ | ✓ | -| Oracle JDK(`oracle`) | ✓ | ✓ | – | – | ✓ | ✓ | ✓ | – | -| Semeru(`sem`) | ✓ | ✓ | – | – | ✓ | ✓ | ✓ | – | -| SapMachine(`sapmchn`) | ✓ | ✓ | ✓ | – | ✓ | ✓ | ✓ | – | -| Kona(`kona`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – | -| Dragonwell(`albba`) | ✓ | ✓ | ✓ | – | – | – | ✓ | – | -| 毕昇 JDK(`bsg`) | ✓ | ✓ | – | – | – | – | – | – | -| Oracle GraalVM(`graal`) | ✓ | ✓ | – | – | ✓ | ✓ | ✓ | – | -| GraalVM 社区版(`graalce`) | ✓ | ✓ | – | – | ✓ | ✓ | ✓ | – | -| Liberica NIK(`nik`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – | -| Mandrel(`mandrel`) | ✓ | ✓ | – | – | – | ✓ | ✓ | – | -| JetBrains Runtime(`jb`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Trava(`trava`) | ✓ | ✓ | – | – | ✓ | – | ✓ | – | +| OpenJDK(`open`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| Temurin(`tem`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Zulu(`zulu`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Liberica(`librca`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Corretto(`amzn`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| Microsoft(`ms`) | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | +| Oracle JDK(`oracle`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| Semeru(`sem`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| SapMachine(`sapmchn`) | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | +| Kona(`kona`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| Dragonwell(`albba`) | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | +| 毕昇 JDK(`bsg`) | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| Oracle GraalVM(`graal`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| GraalVM 社区版(`graalce`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| Liberica NIK(`nik`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| Mandrel(`mandrel`) | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | +| JetBrains Runtime(`jb`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Trava(`trava`) | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | +| AdoptOpenJDK(`adpt`) | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | +| AdoptOpenJDK OpenJ9(`adptj9`) | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | +| Eliya(`eliya`) | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| OJDKBuild(`ojdkbld`) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | +| OpenLogic(`opnlgc`) | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | +| Red Hat(`rdht`) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| Semeru 认证版(`semcrt`) | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| Gluon GraalVM(`gln`) | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| GraalVM CE 8(`grl8`) | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | +| GraalVM CE 11(`grl11`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| GraalVM CE 16(`grl16`) | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | +| GraalVM CE 17(`grl17`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | +| GraalVM CE 19(`grl19`) | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | “Alpine”指使用 musl C 库的 Linux。`ldd --version` 的输出里提到 musl,插件就当作 musl,否则当作 glibc。Loongnix 另有单独的页面:[loongnix.md](loongnix.md)。 @@ -37,7 +50,7 @@ Foojay 的数据会变,这张表也会过时。想看当前的情况,按 [fo ## 只有部分版本 -打勾不代表所有版本都有。以下同样截至 2026-10-18: +标了 ✅ 也不代表所有版本都有。以下同样截至 2026-10-18: - Windows ARM64 上,没有任何发行版提供 Java 8。Temurin 有 21 和 23,Zulu 有 16 到 19、21 和 25,Liberica 有 11 和 16 到 27,Microsoft 有 11、16、17、21 和 25,JetBrains Runtime 有 17、21 和 25。 - Apple Silicon 上,Java 8 来自 Zulu、Liberica、Corretto 和 Kona。Temurin 和 Semeru 在那里有 11 和 17 到 27,OpenJDK 有 17 到 27。Mandrel 有 23 到 25,Liberica NIK 有 22 到 25。 @@ -46,25 +59,34 @@ Foojay 的数据会变,这张表也会过时。想看当前的情况,按 [fo - Trava 在 Linux arm64 上只有一个构建,11.0.10+6。 - 带 JavaFX 的构建覆盖的平台比不带的少,见 [javafx.md](javafx.md#哪些平台有-javafx-构建)。 +2026-10-20 补上的那些行,截至当天: + +- AdoptOpenJDK 的 Alpine x64 构建只有 HotSpot 版的 Java 16,OpenJ9 版在 Linux arm64 上只有 8、11、15 和 16。 +- OJDKBuild 在 Linux 上只有 Java 8 和 11。 +- Red Hat 的构建只有 Linux x64 能下载,也就是表里它唯一的 ✅。Foojay 还列了几个 Linux arm64 的和一个 Windows 的,`vfox search` 也会列出来,但下载都返回 404。 +- Apple Silicon 上,Gluon GraalVM 有 22.1.0.1 和 23+25,GraalVM CE 11 和 17 有 GraalVM 22.1 到 22.3.1,GraalVM CE 19 有 22.3 和 22.3.1。 + ## 哪些只有 x64 -每个发行版在 Linux 上都有 arm64 构建,Trava 只有一个(11.0.10+6)。macOS 上,Dragonwell 和毕昇两种架构都没有,Trava 只有 Intel,Mandrel 只有 Apple Silicon。 +除了 OJDKBuild、OpenLogic、Red Hat、Gluon GraalVM 和 GraalVM CE 8,每个发行版在 Linux 上都有 arm64 构建,Trava 只有一个(11.0.10+6)。macOS 上,Dragonwell、毕昇、Eliya、OJDKBuild、Red Hat 和 Semeru 认证版两种架构都没有;Trava、AdoptOpenJDK、OpenLogic、GraalVM CE 8 和 GraalVM CE 16 只有 Intel;Mandrel 只有 Apple Silicon。 -Windows 上几乎都只有 x64。另外有 arm64 构建的是 Temurin、Zulu、Liberica、Microsoft 和 JetBrains Runtime。其余都只有 x64,其中毕昇在 Windows 上根本没有。 +Windows 上几乎都只有 x64。另外有 arm64 构建的是 Temurin、Zulu、Liberica、Microsoft 和 JetBrains Runtime。其余都只有 x64,其中毕昇、Eliya、Red Hat 和 Semeru 认证版在 Windows 上根本没有。 ## GraalVM Oracle GraalVM 和 GraalVM 社区版在 Linux 和 macOS 上有 x64 和 arm64 构建,在 Windows 上只有 x64。它们没有 Alpine 的构建。Intel Mac 上最新的是 25.0.1,25.1 之后每月发布的特性版本在 macOS 上只有 Apple Silicon 版本。e2e 套件在 arm64 上不测 GraalVM 社区版,只是因为它的 Windows arm64 作业没有可装的包。Linux arm64 是有构建的。 +GraalVM CE 8 到 19 和 Gluon GraalVM 同样没有 Alpine 和 Windows ARM64 的构建。GraalVM CE 从 JDK 11 起才有 Linux arm64 的构建,Gluon GraalVM 则没有。 + ## 其他 CPU vfox 除了 x64、arm64 和 loong64,还发布 32 位 x86 和 32 位 ARM 的二进制。插件会把 vfox 二进制的架构名传给 Foojay(`arm64` 改成 `aarch64`,Windows 上 `amd64` 改成 `x64`),所以能装到什么,取决于 Foojay 列出什么。e2e 套件没有覆盖这些情况。 -- 32 位 ARM Linux:Corretto、Liberica、Temurin 和 Zulu。 -- 32 位 x86 Linux:Corretto、Liberica、Zulu 和 JetBrains Runtime。 +- 32 位 ARM Linux:Corretto、Liberica、Temurin 和 Zulu,以及 HotSpot 版的 AdoptOpenJDK。 +- 32 位 x86 Linux:Corretto、Liberica、Zulu 和 JetBrains Runtime,以及 OpenLogic 的 Java 8。 - Foojay 不认识 loong64,Linux loong64 改用 Loongnix,见 [loongnix.md](loongnix.md)。 -如果你自己为 riscv64、ppc64le 或 s390x 编译 vfox:Foojay 列有 riscv64 包的是 Dragonwell、Liberica 和 Temurin,ppc64le 的是 Liberica、SapMachine、Semeru 和 Temurin,s390x 的是 Semeru 和 Temurin。 +如果你自己为 riscv64、ppc64le 或 s390x 编译 vfox:Foojay 列有 riscv64 包的是 Dragonwell、Liberica 和 Temurin,ppc64le 的是 Liberica、SapMachine、Semeru 和 Temurin,s390x 的是 Semeru 和 Temurin。2026-10-20 补上的发行版里,AdoptOpenJDK(HotSpot 版和 OpenJ9 版都有)和 Semeru 认证版有 ppc64le 和 s390x 的包,Red Hat 的 ppc64le 记录下载返回 404。 ## macOS 上的 Java home diff --git a/docs/zh-CN/sdkmanrc.md b/docs/zh-CN/sdkmanrc.md index 2f58f89..e397b61 100644 --- a/docs/zh-CN/sdkmanrc.md +++ b/docs/zh-CN/sdkmanrc.md @@ -55,6 +55,11 @@ vfox 挂载到 Shell 之后,进入目录时会读取这个文件,并选中 | `21.0.8+1.1-tem` | Temurin 21.0.8,见下文 | | `27.0.0+36-librca`、`25.0.1.0+8-open` | `27+36-librca`、`25.0.1+8`:补的零会被去掉 | | `28.ea.19-open`、`28.0.0+ea.19-open` | EA 构建 `28-ea+19` | +| `11.0.10.hs-adpt`、`11.0.10.j9-adpt` | AdoptOpenJDK 的 HotSpot 版 `11.0.10-adpt` 和 OpenJ9 版 `11.0.10-adptj9` | +| `22.3.3.r17-grl` | 基于 JDK 17 的 GraalVM CE 22.3.3,`22.3.3-grl17` | +| `22.1.0.1.r17-gln` | Gluon GraalVM 22.1.0.1,`22.1.0.1-gln` | + +最后三行是 SDKMAN 给它已经不再提供的发行版用过的标识符,虚拟机或 JDK 版本写在版本号里,见 [distributions.md](distributions.md#简称与-sdkman-的不同)。插件不安装 Gluon GraalVM 22 的 JDK 11 构建,也不安装 AdoptOpenJDK 的 upstream 构建,所以 `22.1.0.1.r11-gln` 和 `11.0.9.open-adpt` 什么都不会选中。未发布:0.6.2 对这三行都选不中任何 JDK。 SDKMAN 新写法里 `+` 后面的数字(`21.0.8+1.1-tem`)是 SDKMAN 自己重新构建的次数,不是厂商的构建号,所以插件不会去找这个构建,而是按版本匹配。Foojay 和安装后的版本名都不补零,所以 `27.0.0` 指的就是 `27`。`sdk list java` 里补一个 `.0` 很常见(`25.0.1.0+8-open`、`21.0.9.0+116386-jbr`),插件同样能读。 diff --git a/docs/zh-CN/troubleshooting.md b/docs/zh-CN/troubleshooting.md index c54c4a9..e0d0b73 100644 --- a/docs/zh-CN/troubleshooting.md +++ b/docs/zh-CN/troubleshooting.md @@ -20,7 +20,7 @@ Foojay 在这个平台上没有对应的包:版本、发行版、带不带 Jav ### `Could not extract a valid distribution: 21-foo` -`-` 前后两部分都不是发行版名。名字都是小写,取自 [distributions.md](distributions.md) 里的表。`java@21-openlogic` 也会报这个错,因为插件没有提供 Foojay 里的所有发行版。 +`-` 前后两部分都不是发行版名。名字都是小写,取自 [distributions.md](distributions.md) 里的表。未发布:0.6.2 之后新增的 13 个发行版,在 0.6.2 上都会报这个错,比如 `java@21-opnlgc` 和 `java@21-openlogic`。 ### `Unsupported distribution: foo` @@ -32,7 +32,7 @@ Foojay 在这个平台上没有对应的包:版本、发行版、带不带 Jav ### `source file not found` -下载时服务器返回 404。厂商会下线旧的构建,而 Foojay 仍保留它们的记录。最常见的是 EA 构建(见 [versions.md](versions.md#早期访问ea构建))。换一个较新的构建。 +下载时服务器返回 404。厂商会下线旧的构建,而 Foojay 仍保留它们的记录。最常见的是 EA 构建(见 [versions.md](versions.md#早期访问ea构建))。换一个较新的构建。Red Hat 除了 Linux x64 以外的构建都会报这个错,见 [distributions.md](distributions.md#red-hat-build-of-openjdkrdht)。 ### `java@21-tem is not installed` @@ -66,6 +66,7 @@ vfox config proxy.url http://127.0.0.1:7890 - **安装后的版本名里多了一个你没写的构建号。** `java@21.0.8-tem` 装出来是 `21.0.8+9-tem`。构建号是版本名的一部分,见 [versions.md](versions.md#安装后的版本名)。 - **`vfox install java@21-tem` 和 `vfox install java tem` 做的是不同的事。** 后者是两个 SDK,`java` 和 `tem`。 - **你设置的 `GRAALVM_HOME` 不会被改动。** 插件只设置 `JAVA_HOME` 和 `PATH`。 +- **`vfox use java@21` 选中了 `21.3.1-grl11`,而它运行的是 Java 11。** GraalVM CE 8 到 19 和 23 以前的 Gluon GraalVM 用的是 GraalVM 的版本号,对只写大版本号的写法,vfox 只按版本号匹配,不分发行版,见 [distributions.md](distributions.md#按-graalvm-编号的版本)。请写成 `java@21-tem`。 ## JDK 在哪里 diff --git a/docs/zh-CN/versions.md b/docs/zh-CN/versions.md index 1a3baf9..83e8a98 100644 --- a/docs/zh-CN/versions.md +++ b/docs/zh-CN/versions.md @@ -73,6 +73,8 @@ vfox uninstall java@21.0.8+9-tem 写明了构建或版本时,不会跳到别的构建或版本(`21.0.12-tem` 不会选中 `21.0.12.1+1-tem`)。也不会跨发行版,不会在带 JavaFX 和不带 JavaFX 的构建之间串用,不会在 EA 和 GA 之间串用。什么都匹配不上时,报 `java@99-tem is not installed`。 +vfox 自己匹配 `21` 时只看版本号,所以 GraalVM CE 8 到 19 和 Gluon GraalVM 也会被它选中,它们的版本号是 GraalVM 的:`21.3.1-grl11` 运行的是 Java 11,`vfox use java@21` 却会选中它,而不是 `21.0.12.1+1-tem`。见 [distributions.md](distributions.md#按-graalvm-编号的版本)。 + 作用域用 `vfox use` 的参数选择:`--global`、`--project` 或 `--session`,默认是会话作用域。如果 Shell 没有挂载 vfox,Windows 会警告并切到全局作用域,Linux 和 macOS 则报 `vfox requires hook support` 后退出。`--project` 会写出 `.vfox.toml`,里面记录的是安装后的版本名(`java = "17.0.10+7-tem"`)。`.sdkmanrc` 也会被读取,见 [sdkmanrc.md](sdkmanrc.md)。 ## 早期访问(EA)构建 @@ -91,7 +93,7 @@ vfox install java@28.ea.15-open # 28-ea+15 ```bash vfox search java # 默认的 OpenJDK vfox search java tem # 指定一个发行版,简称或长名都行 -vfox search java all # 所有发行版,在 Linux x64 上约 2300 行 +vfox search java all # 所有发行版,在 Linux x64 上约 2500 行 ``` 每一行都是可以接在 `java@` 后面的名字,新的在前,带 LTS、JavaFX(见 [javafx.md](javafx.md))备注,已安装的会有标记: diff --git a/hooks/available.lua b/hooks/available.lua index 99515cc..0a22ad8 100644 --- a/hooks/available.lua +++ b/hooks/available.lua @@ -18,7 +18,8 @@ local distribution_version_parser = require("distribution_version") -- is_feature_release reads GraalVM's numbering only. Liberica NIK and Mandrel -- numbered their releases after themselves up to 24 (Mandrel 23.1.12 is LTS) and --- follow the JDK from 25 on, so they stay out of it. +-- follow the JDK from 25 on, so they stay out of it, and so do GraalVM CE 8 to +-- 19 and Gluon GraalVM, which ended before the monthly feature releases began. local graalvm = { graal = true, graalce = true } --- Return all available versions provided by this plugin diff --git a/hooks/parse_legacy_file.lua b/hooks/parse_legacy_file.lua index 36b7a1e..7074d6b 100644 --- a/hooks/parse_legacy_file.lua +++ b/hooks/parse_legacy_file.lua @@ -17,14 +17,28 @@ local strings = require("vfox.strings") local distribution_version_parser = require("distribution_version") local installed_version = require("installed_version") +--- The distributions SDKMAN no longer offers, for which it wrote the VM or +--- the JDK into the version: AdoptOpenJDK with HotSpot or OpenJ9 +--- (11.0.10.hs-adpt, 11.0.10.j9-adpt), GraalVM CE on JDK 8 to 19 +--- (22.3.3.r17-grl) and Gluon GraalVM on JDK 17, the builds of it the plugin +--- installs (22.1.0.1.r17-gln). Each flavour maps to the plugin's short name. +local sdkman_flavours = { + adpt = { hs = "adpt", j9 = "adptj9" }, + grl = { r8 = "grl8", r11 = "grl11", r16 = "grl16", r17 = "grl17", r19 = "grl19" }, + gln = { r17 = "gln" }, +} + --- Rewrites an SDKMAN identifier in the plugin's spelling, which parse_version --- reads. SDKMAN calls JetBrains jbr (the plugin's jb) and puts fx in the --- version of JavaFX builds: 21.0.12.fx-zulu, or 21.0.12-fx+1.1-librca in its --- semverish identifiers (the plugin's 21.0.12-zulu-fx, 21.0.12+1.1-librca-fx). --- The semverish ones spell early-access builds 28.0.0+ea.19-open, padded or --- not (28.0.0.0+ea.19-open), where SDKMAN used to write the plugin's ---- 28.ea.19-open (Foojay's 28-ea+19). ---- Any other spelling, the plugin's own included, is returned unchanged. +--- 28.ea.19-open (Foojay's 28-ea+19). The VM or JDK of the distributions in +--- sdkman_flavours becomes the short name (22.3.3.r17-grl is 22.3.3-grl17), +--- and nil comes back for one the plugin does not install (11.0.9.open-adpt, +--- 22.1.0.1.r11-gln). Any other spelling, the plugin's own included, is +--- returned unchanged. local function plugin_spelling(identifier) local version, distribution = identifier:match("^(.+)%-([^-]+)$") if not version then @@ -33,6 +47,15 @@ local function plugin_spelling(identifier) if distribution == "jbr" then distribution = "jb" end + local flavours = sdkman_flavours[distribution] + local flavoured, flavour = version:match("^(%d[%d.]*)%.(%a%w*)$") + if flavours and flavoured then + distribution = flavours[flavour] + if not distribution then + return nil + end + version = flavoured + end local suffix = "-" .. distribution local release, build = version:match("^(%d[%d.]*)[.-]fx(.*)$") if release then @@ -79,7 +102,8 @@ function PLUGIN:ParseLegacyFile(ctx) return { version = javaVersion } end - local distributionVersion = distribution_version_parser.parse_version(plugin_spelling(javaVersion)) + local spelling = plugin_spelling(javaVersion) + local distributionVersion = spelling and distribution_version_parser.parse_version(spelling) if not distributionVersion then return {} end diff --git a/lib/distribution_version.lua b/lib/distribution_version.lua index 608d797..7453642 100644 --- a/lib/distribution_version.lua +++ b/lib/distribution_version.lua @@ -35,6 +35,25 @@ local short_name = { ["trava"] = "trava", ["zulu"] = "zulu", ["jb"] = "jetbrains", + -- SDKMAN no longer offers these. It wrote the VM or the JDK into the + -- version (11.0.10.j9-adpt, 22.3.3.r17-grl), which here is part of the + -- name, one per Foojay distribution. + ["adpt"] = "aoj", + ["adptj9"] = "aoj_openj9", + ["gln"] = "gluon_graalvm", + ["grl8"] = "graalvm_ce8", + ["grl11"] = "graalvm_ce11", + ["grl16"] = "graalvm_ce16", + ["grl17"] = "graalvm_ce17", + ["grl19"] = "graalvm_ce19", + -- SDKMAN has no identifier for these. Short vendor names stay whole, as its + -- zulu and kona do, and longer ones are cut down, mostly by dropping vowels, + -- as its librca and sapmchn are; semcrt is its sem with certified. + ["eliya"] = "eliya", + ["ojdkbld"] = "ojdk_build", + ["opnlgc"] = "openlogic", + ["rdht"] = "redhat", + ["semcrt"] = "semeru_certified", } local long_name = {} diff --git a/lib/foojay.lua b/lib/foojay.lua index c605d7d..eb2dd0d 100644 --- a/lib/foojay.lua +++ b/lib/foojay.lua @@ -20,6 +20,58 @@ local foojay = {} local URL = "https://api.foojay.io/disco/v3.0/packages/jdks?version=%s&distribution=%s&architecture=%s&%s&operating_system=%s&lib_c_type=%s&directly_downloadable=true" +-- Outside Windows a few distributions ship some or all releases in another +-- archive type than tar.gz, which vfox unpacks too: Red Hat's Linux builds +-- are tar.xz, OJDKBuild's Linux builds and OpenLogic's macOS builds zip, and +-- so are Gluon GraalVM's releases before 22.1. +local other_archive_type = { + redhat = "tar.xz", + ojdk_build = "zip", + openlogic = "zip", + gluon_graalvm = "zip", +} + +-- Fixes for the packages Foojay lists for a distribution, each returning the +-- ones to keep. +local fixes = { + -- Among OJDKBuild's Windows JDKs, Foojay lists JREs + -- (java-17-openjdk-17.0.3.0.6-1.jre.win.x86_64.zip), installer bundles, + -- which have the JDK one directory down, and RHEL 6 builds for Linux + -- (java-1.8.0-openjdk-1.8.0.161-3.b14.el6_9.x86_64.zip). + ojdk_build = function(packages) + local result = {} + for _, package in ipairs(packages) do + local filename = package.filename or "" + if + not filename:find(".jre.", 1, true) + and not filename:find("installer_bundle", 1, true) + and not filename:find("%.el%d") + then + table.insert(result, package) + end + end + return result + end, + -- Gluon GraalVM's 22.x releases come for JDK 11 and JDK 17 under one + -- java_version, with the JDK as distribution_version (11 and 17 for + -- 22.1.0.1), so an installed name could not tell them apart; the JDK 17 + -- ones stay. + gluon_graalvm = function(packages) + local newest = {} + for _, package in ipairs(packages) do + local jdk = tonumber(package.distribution_version) or 0 + newest[package.java_version] = math.max(newest[package.java_version] or 0, jdk) + end + local result = {} + for _, package in ipairs(packages) do + if (tonumber(package.distribution_version) or 0) == newest[package.java_version] then + table.insert(result, package) + end + end + return result + end, +} + --- Detects the libc type on Linux systems (glibc or musl) --- @return string "glibc" or "musl" local function detect_lib_c_type() @@ -64,6 +116,8 @@ foojay.fetchtJdkList = function(distribution, version) if arch == "amd64" then arch = "x64" end + elseif other_archive_type[distribution] then + archive_types = archive_types .. "&archive_type=" .. other_archive_type[distribution] end local lib_c_type = "" @@ -76,20 +130,34 @@ foojay.fetchtJdkList = function(distribution, version) -- latest=available would look at the major alone. local latest = version:match("^%d+$") and "&latest=available" or "" - local reqUrl = URL:format(encode(version), distribution, arch, archive_types, os, lib_c_type) .. latest + local function request(query, latest_query) + local reqUrl = URL:format(encode(query), distribution, arch, archive_types, os, lib_c_type) .. latest_query - local resp, err = http.get({ - url = reqUrl, - }) - if err ~= nil then - error("Failed to fetch jdk info from foojay: " .. err) - end - if resp.status_code ~= 200 then - error("Failed to fetch jdk info from foojay: status_code =>" .. resp.status_code) + local resp, err = http.get({ + url = reqUrl, + }) + if err ~= nil then + error("Failed to fetch jdk info from foojay: " .. err) + end + if resp.status_code ~= 200 then + error("Failed to fetch jdk info from foojay: status_code =>" .. resp.status_code) + end + + local respBody = json.decode(resp.body) + return respBody.result end - local respBody = json.decode(resp.body) - local result = respBody.result + local result = request(version, latest) + local fix = fixes[distribution] + if fix and result then + -- latest=available answers with one package of the newest release + -- per archive type, which may be one the fix drops (OJDKBuild's + -- 17.0.3 JRE on Windows): ask for that release in full. + if latest ~= "" and result[1] then + result = request(result[1].java_version, "") or {} + end + result = fix(result) + end return result end diff --git a/tests/e2e/common/common.go b/tests/e2e/common/common.go index a2d201e..1a8dff1 100644 --- a/tests/e2e/common/common.go +++ b/tests/e2e/common/common.go @@ -30,6 +30,7 @@ import ( "os" "regexp" "runtime" + "slices" "strconv" "strings" "testing" @@ -613,6 +614,70 @@ func BareMajorBuilds(searched []string, spec string) (builds []string, want stri return builds, want } +// nameOnly maps the distributions the suite checks by name only, by short +// name, to the runner platforms Foojay lists packages of them for +// (2026-10-20). Only Red Hat's Linux x64 builds still download, which the +// check needs not. +var nameOnly = map[string][]string{ + "adpt": {"linux/amd64", "linux/arm64", "windows/amd64"}, + "adptj9": {"linux/amd64", "linux/arm64", "windows/amd64"}, + "eliya": {"linux/amd64", "linux/arm64"}, + "gln": {"linux/amd64", "windows/amd64"}, + "grl8": {"linux/amd64", "windows/amd64"}, + "grl11": {"linux/amd64", "linux/arm64", "windows/amd64"}, + "grl16": {"linux/amd64", "linux/arm64", "windows/amd64"}, + "grl17": {"linux/amd64", "linux/arm64", "windows/amd64"}, + "grl19": {"linux/amd64", "linux/arm64", "windows/amd64"}, + "ojdkbld": {"linux/amd64", "windows/amd64"}, + "opnlgc": {"linux/amd64", "windows/amd64"}, + "rdht": {"linux/amd64", "linux/arm64", "windows/amd64"}, + "semcrt": {"linux/amd64", "linux/arm64"}, +} + +// NameOnlyDistributions returns, sorted, the distributions in nameOnly that +// Foojay has packages of for platform ("linux/amd64", "windows/arm64"). The +// suite checks them by name only, installing no JDK. The plugin had no name +// for them, so `vfox search java adpt` failed with "Unsupported +// distribution" and `vfox install java@16-adpt` with "Could not extract a +// valid distribution". +func NameOnlyDistributions(platform string) []string { + var names []string + for name, platforms := range nameOnly { + if slices.Contains(platforms, platform) { + names = append(names, name) + } + } + slices.Sort(names) + return names +} + +// ChecksNameOnly reports whether a combo also checks the distributions in +// NameOnlyDistributions, which downloads nothing. Temurin's combos do: they +// run on every runner. +func ChecksNameOnly(distribution string) bool { + return Base(distribution) == "tem" +} + +// leadingNumber matches the major of a Foojay java_version, which a dot +// or a build follows (22.3.3, 23+25). +var leadingNumber = regexp.MustCompile(`^\d+`) + +// NewestBareMajor picks the newest version `vfox search java ` +// lists (22.3.3-grl17) and the bare major spec that must install it +// (22-grl17). ok is false when there is none, or when the spec names the +// version itself: vfox reports a spec naming an installed version as +// installed without calling PreInstall. +func NewestBareMajor(searched []string, short string) (spec, newest string, ok bool) { + if len(searched) == 0 { + return "", "", false + } + newest = searched[0] + core, found := strings.CutSuffix(newest, "-"+short) + major := leadingNumber.FindString(core) + spec = major + "-" + short + return spec, newest, found && major != "" && spec != newest +} + // ContainerName returns a unique container name per run: the combo slug stays // greppable in `docker ps`, the random suffix avoids clashes with leftovers // from killed runs. diff --git a/tests/e2e/common/common_test.go b/tests/e2e/common/common_test.go index 5ea39f9..af83f44 100644 --- a/tests/e2e/common/common_test.go +++ b/tests/e2e/common/common_test.go @@ -460,3 +460,55 @@ func TestBareMajorBuilds(t *testing.T) { t.Error("only the GraalVM Community combos check Oracle GraalVM's bare major") } } + +func TestNameOnlyDistributions(t *testing.T) { + for platform, want := range map[string][]string{ + "linux/amd64": {"adpt", "adptj9", "eliya", "gln", "grl11", "grl16", "grl17", "grl19", "grl8", "ojdkbld", "opnlgc", "rdht", "semcrt"}, + "linux/arm64": {"adpt", "adptj9", "eliya", "grl11", "grl16", "grl17", "grl19", "rdht", "semcrt"}, + "windows/amd64": {"adpt", "adptj9", "gln", "grl11", "grl16", "grl17", "grl19", "grl8", "ojdkbld", "opnlgc", "rdht"}, + "windows/arm64": nil, + } { + if got := NameOnlyDistributions(platform); !slices.Equal(got, want) { + t.Errorf("NameOnlyDistributions(%s) = %q, want %q", platform, got, want) + } + } + // The suite installs these, so it knows their names already. + for name := range nameOnly { + if _, ok := distributions[name]; ok { + t.Errorf("%s is checked by name only, but the suite installs it", name) + } + } + // Temurin's combos run on every runner, arm64 included. + for _, arch := range []string{"amd64", "arm64"} { + if !slices.ContainsFunc(DefaultDistributions(arch), ChecksNameOnly) { + t.Errorf("no %s default combo checks the distributions by name", arch) + } + } + if ChecksNameOnly("librca-fx") { + t.Error("only the Temurin combos check the distributions by name") + } +} + +func TestNewestBareMajor(t *testing.T) { + for _, c := range []struct { + searched []string + short, spec, found string + ok bool + }{ + // Abridged `vfox search` output, observed on 2026-10-20. + {[]string{"22.3.3-grl17", "22.3.2-grl17"}, "grl17", "22-grl17", "22.3.3-grl17", true}, + {[]string{"25.0.4+7-opnlgc", "25.0.3+9-opnlgc"}, "opnlgc", "25-opnlgc", "25.0.4+7-opnlgc", true}, + {[]string{"23+25-gln", "22.1.0.1-gln"}, "gln", "23-gln", "23+25-gln", true}, + {[]string{"8.0.345+1-rdht"}, "rdht", "8-rdht", "8.0.345+1-rdht", true}, + // vfox would find 16-adpt itself installed, without asking PreInstall. + {[]string{"16-adpt", "15.0.2-adpt"}, "adpt", "16-adpt", "16-adpt", false}, + {[]string{"16.0.1-adptj9"}, "adpt", "", "16.0.1-adptj9", false}, + {nil, "eliya", "", "", false}, + } { + spec, found, ok := NewestBareMajor(c.searched, c.short) + if ok != c.ok || ok && (spec != c.spec || found != c.found) { + t.Errorf("NewestBareMajor(%q, %s) = %q, %q, %v; want %q, %q, %v", + c.searched, c.short, spec, found, ok, c.spec, c.found, c.ok) + } + } +} diff --git a/tests/e2e/linux/e2e_test.go b/tests/e2e/linux/e2e_test.go index 2b027f4..8b71a28 100644 --- a/tests/e2e/linux/e2e_test.go +++ b/tests/e2e/linux/e2e_test.go @@ -171,6 +171,9 @@ func runOne(t *testing.T, ctx context.Context, image, platform, arch string, c c if common.ChecksOracleGraalVM(c.Distribution) { checkGraalVMBareMajor(ctx, t, ctr) } + if common.ChecksNameOnly(c.Distribution) { + checkNameOnly(ctx, t, ctr, platform) + } installed := installJava(ctx, t, ctr, common.Spec(c.Distribution, version)) verifySearch(ctx, t, ctr, c.Distribution, installed) diff --git a/tests/e2e/linux/setup.go b/tests/e2e/linux/setup.go index 0b1046c..41a7de2 100644 --- a/tests/e2e/linux/setup.go +++ b/tests/e2e/linux/setup.go @@ -121,3 +121,30 @@ func checkGraalVMBareMajor(ctx context.Context, t *testing.T, ctr tc.Container) execOK(ctx, t, ctr, "rm --recursive "+strings.Join(dirs, " ")) t.Logf("PASS java@%s takes %s out of %s", spec, want, strings.Join(builds, ", ")) } + +// checkNameOnly proves the distributions checked by name only go by their +// short names (see common.NameOnlyDistributions): `vfox search java +// ` lists each, and with the newest version it lists faked as +// installed, `vfox install java@-` finds that one installed, +// so nothing downloads (see common.NewestBareMajor). +func checkNameOnly(ctx context.Context, t *testing.T, ctr tc.Container, platform string) { + t.Helper() + names := common.NameOnlyDistributions(platform) + var dirs []string + for _, name := range names { + search := "vfox search java " + name + out := execRetry(ctx, t, ctr, search, search) + spec, newest, ok := common.NewestBareMajor(common.SearchedVersions(out), name) + require.Truef(t, ok, "%s lists no newest version that a bare major names\n--- output ---\n%s", search, out) + dir := `"${VFOX_HOME:-$HOME/.vfox}"/cache/java/` + shQuote("v-"+newest) + dirs = append(dirs, dir) + execOK(ctx, t, ctr, "mkdir --parents "+dir+"/"+shQuote("java-"+newest)) + out = execRetry(ctx, t, ctr, "vfox install java@"+spec, "vfox install java@"+spec) + require.Containsf(t, common.StripANSI(out), "java@"+newest+" is already installed", + "vfox install java@%s must take %s, the newest version %s lists", spec, newest, search) + } + if len(dirs) > 0 { + execOK(ctx, t, ctr, "rm --recursive "+strings.Join(dirs, " ")) + } + t.Logf("PASS %d distributions go by name on %s: %s", len(names), platform, strings.Join(names, ", ")) +} diff --git a/tests/e2e/windows/e2e_test.go b/tests/e2e/windows/e2e_test.go index 8c18369..55c3a7f 100644 --- a/tests/e2e/windows/e2e_test.go +++ b/tests/e2e/windows/e2e_test.go @@ -248,6 +248,9 @@ func runOne(t *testing.T, ctx context.Context, image, platform, arch string, c c if common.ChecksOracleGraalVM(c.Distribution) { checkGraalVMBareMajor(ctx, t, ctr, box) } + if common.ChecksNameOnly(c.Distribution) { + checkNameOnly(ctx, t, ctr, box, platform) + } installed := installJava(ctx, t, ctr, box, common.Spec(c.Distribution, version)) verifySearch(ctx, t, ctr, box, c.Distribution, installed) diff --git a/tests/e2e/windows/setup.go b/tests/e2e/windows/setup.go index 15dfc0d..ac8f674 100644 --- a/tests/e2e/windows/setup.go +++ b/tests/e2e/windows/setup.go @@ -341,3 +341,31 @@ func checkGraalVMBareMajor(ctx context.Context, t *testing.T, ctr tc.Container, execOK(ctx, t, ctr, strings.Join(remove, "; "), box.vars...) t.Logf("PASS java@%s takes %s out of %s", spec, want, strings.Join(builds, ", ")) } + +// checkNameOnly proves the distributions checked by name only go by their +// short names (see common.NameOnlyDistributions): `vfox search java +// ` lists each, and with the newest version it lists faked as +// installed, `vfox install java@-` finds that one installed, +// so nothing downloads (see common.NewestBareMajor). +func checkNameOnly(ctx context.Context, t *testing.T, ctr tc.Container, box slotBox, platform string) { + t.Helper() + names := common.NameOnlyDistributions(platform) + var remove []string + for _, name := range names { + search := "vfox search java " + name + out := execRetry(ctx, t, ctr, search, search, box.vars...) + spec, newest, ok := common.NewestBareMajor(common.SearchedVersions(out), name) + require.Truef(t, ok, "%s lists no newest version that a bare major names\n--- output ---\n%s", search, out) + dir := fmt.Sprintf("(Join-Path $env:VFOX_HOME %s)", pwshQuote(`cache\java\v-`+newest)) + remove = append(remove, fmt.Sprintf("Remove-Item -LiteralPath %s -Recurse -Force", dir)) + execOK(ctx, t, ctr, fmt.Sprintf("New-Item -ItemType Directory -Force -Path (Join-Path %s %s) | Out-Null", + dir, pwshQuote("java-"+newest)), box.vars...) + out = execRetry(ctx, t, ctr, "vfox install java@"+spec, "vfox install "+pwshQuote("java@"+spec), box.vars...) + require.Containsf(t, common.StripANSI(out), "java@"+newest+" is already installed", + "vfox install java@%s must take %s, the newest version %s lists", spec, newest, search) + } + if len(remove) > 0 { + execOK(ctx, t, ctr, strings.Join(remove, "; "), box.vars...) + } + t.Logf("PASS %d distributions go by name on %s: %s", len(names), platform, strings.Join(names, ", ")) +} diff --git a/tests/parse_legacy_file_test.lua b/tests/parse_legacy_file_test.lua index 6471d52..8a5a477 100644 --- a/tests/parse_legacy_file_test.lua +++ b/tests/parse_legacy_file_test.lua @@ -127,6 +127,27 @@ local cases = { { "java=-tem\n", { "21.0.8+9-tem" }, nil }, { "java=zulu-fx\n", { "21.0.12+7-zulu-fx" }, nil }, { "java=open\n", { "25.0.2+10" }, nil }, + -- SDKMAN wrote the VM or the JDK of the distributions it no longer offers + -- into the version, which is the plugin's short name (adpt, adptj9, + -- grl17, gln). SDKMAN's AdoptOpenJDK upstream builds and Gluon's JDK 11 + -- builds are not the plugin's, so they select nothing. + { "java=11.0.10.hs-adpt\n", { "11.0.10-adpt", "11.0.10-adptj9" }, "11.0.10-adpt" }, + { "java=11.0.10.j9-adpt\n", { "11.0.10-adpt", "11.0.10-adptj9" }, "11.0.10-adptj9" }, + { "java=8.0.282.j9-adpt\n", { "8.0.282-adpt", "8.0.282-adptj9" }, "8.0.282-adptj9" }, + { "java=11.0.9.open-adpt\n", { "11.0.9-adpt", "11.0.11-adpt" }, nil }, + { "java=22.3.3.r17-grl\n", { "22.3.3-grl11", "22.3.3-grl17" }, "22.3.3-grl17" }, + { "java=22.3.3.r11-grl\n", { "22.3.3-grl11", "22.3.3-grl17" }, "22.3.3-grl11" }, + { "java=21.3.1.r8-grl\n", { "21.3.1-grl8", "21.3.1-grl11" }, "21.3.1-grl8" }, + { "java=22.3.r19-grl\n", { "22.3-grl19", "22.3.1-grl19" }, "22.3-grl19" }, + { "java=21.2.0.r16-grl\n", { "21.2-grl16" }, "21.2-grl16" }, + { "java=22.3.3.r20-grl\n", { "22.3.3-grl17" }, nil }, + { "java=22.1.0.1.r17-gln\n", { "22.1.0.1-gln" }, "22.1.0.1-gln" }, + { "java=22.1.0.1.r11-gln\n", { "22.1.0.1-gln" }, nil }, + -- The plugin's own spellings of them. + { "java=22.3.3-grl17\n", { "22.3.3-grl11", "22.3.3-grl17" }, "22.3.3-grl17" }, + { "java=21.0.8-rdht\n", { "21.0.8+9-rdht" }, "21.0.8+9-rdht" }, + { "java=25.0.4-semcrt\n", { "25.0.4-semcrt", "25.0.2+10-sem" }, "25.0.4-semcrt" }, + { "java=25.0.2-sem\n", { "25.0.4-semcrt", "25.0.2+10-sem" }, "25.0.2+10-sem" }, -- No java line at all selects nothing. { "maven=3.9.9\n", { "21.0.8+9-tem" }, nil }, } diff --git a/tests/pre_install_test.lua b/tests/pre_install_test.lua index 2164cae..ac9bdbf 100644 --- a/tests/pre_install_test.lua +++ b/tests/pre_install_test.lua @@ -32,9 +32,21 @@ local function lts(jdk) return jdk end +-- A package whose download is named after its file, for distributions that +-- list several packages of one version: Gluon GraalVM's builds for JDK 11 and +-- JDK 17, whose JDK Foojay gives as distribution_version, and OJDKBuild's JRE +-- next to its JDK. +local function file(jdk, filename, distribution_version) + jdk.filename = filename + jdk.distribution_version = distribution_version + jdk.links.pkg_info_uri = IDS .. filename + return jdk +end + -- Foojay answers observed on 2026-10-17 for linux/amd64 tar.gz packages, keyed -- by "[ ][ ]", and for windows/amd64 zip and --- tar.gz packages, keyed by "windows [ ][ ]". +-- tar.gz packages, keyed by "windows [ ][ ]" +-- (darwin/amd64: "macos ..."). local foojay = { ["temurin 21"] = { pkg("21+35") }, ["temurin 21 available"] = { pkg("21.0.12.1+1") }, @@ -100,8 +112,80 @@ local foojay = { pkg("21.0.8+895146"), pkg("21.0.5+79248"), }, + -- Observed on 2026-10-20. Outside Windows, Red Hat ships tar.xz only, + -- OJDKBuild's Linux builds and OpenLogic's macOS ones are zips, and so are + -- Gluon GraalVM's releases before 22.1 (macos in front for macOS). + ["redhat 21 available"] = { pkg("21.0.8+9", false, "tar.xz") }, + ["ojdk_build 11 available"] = { pkg("11.0.15", false, "zip") }, + ["macos openlogic 25 available"] = { pkg("25.0.4+7", false, "zip") }, + -- latest=available answers with one package of the newest release per + -- archive type, here the JDK 11 build of Gluon's 22.1.0.1, which the JDK + -- 17 one supersedes, as its JRE does OJDKBuild's 17.0.3 JDK. + ["gluon_graalvm 22 available"] = { + file(pkg("22.1.0.1"), "graalvm-svm-java11-linux-gluon-22.1.0.1-Final.tar.gz", "11"), + file(pkg("22.0.0.3", false, "zip"), "graalvm-svm-java11-linux-gluon-22.0.0.3-Final.zip", "11"), + }, + ["gluon_graalvm 22.1.0.1"] = { + file(pkg("22.1.0.1"), "graalvm-svm-java11-linux-gluon-22.1.0.1-Final.tar.gz", "11"), + file(pkg("22.1.0.1"), "graalvm-svm-java17-linux-gluon-22.1.0.1-Final.tar.gz", "17"), + }, + ["gluon_graalvm 21 available"] = { + file(pkg("21.2", false, "zip"), "graalvm-svm-linux-gluon-21.2.0-dev.zip", "21.2"), + file(pkg("21.1", false, "zip"), "graalvm-svm-linux-gluon-21.1.0-dev.zip", "21.1"), + }, + ["gluon_graalvm 21.2"] = { file(pkg("21.2", false, "zip"), "graalvm-svm-linux-gluon-21.2.0-dev.zip", "21.2") }, + ["gluon_graalvm"] = { + file(pkg("23+25"), "graalvm-java23-linux-amd64-gluon-23+25.1-dev.tar.gz", "23"), + file(pkg("22.1.0.1"), "graalvm-svm-java11-linux-gluon-22.1.0.1-Final.tar.gz", "11"), + file(pkg("22.1.0.1"), "graalvm-svm-java17-linux-gluon-22.1.0.1-Final.tar.gz", "17"), + file(pkg("21.2", false, "zip"), "graalvm-svm-linux-gluon-21.2.0-dev.zip", "21.2"), + }, + -- Among OJDKBuild's Windows JDKs Foojay lists JREs, installer bundles, which + -- have the JDK one directory down, and RHEL 6 builds for Linux. + ["windows ojdk_build 17 available"] = { + file(pkg("17.0.3", false, "zip"), "java-17-openjdk-17.0.3.0.6-1.jre.win.x86_64.zip"), + }, + ["windows ojdk_build 17.0.3"] = { + file(pkg("17.0.3", false, "zip"), "java-17-openjdk-17.0.3.0.6-1.jre.win.x86_64.zip"), + file(pkg("17.0.3", false, "zip"), "java-17-openjdk-17.0.3.0.6-1.win.x86_64.zip"), + }, + ["windows ojdk_build 11.0.14"] = { + file(pkg("11.0.14", false, "zip"), "java-11-openjdk-11.0.14.9-2.windows.ojdkbuild.x86_64.installer_bundle.zip"), + file(pkg("11.0.14", false, "zip"), "java-11-openjdk-11.0.14.9-2.windows.ojdkbuild.x86_64.zip"), + }, + ["windows ojdk_build 8.0.161"] = { + file(pkg("8.0.161+14", false, "zip"), "java-1.8.0-openjdk-1.8.0.161-3.b14.el6_9.x86_64.zip"), + file(pkg("8.0.161+14", false, "zip"), "java-1.8.0-openjdk-1.8.0.161-1.b14.ojdkbuild.windows.x86_64.zip"), + }, } +-- The 13 distributions added after release 0.6.2, with their Foojay name and the +-- newest release of a major each lists on Linux x64 (2026-10-20). Their +-- versions follow Foojay's java_version, GraalVM's own numbers for GraalVM CE +-- and Gluon GraalVM. +local others = { + { "adpt", "aoj", "16.0.1" }, + { "adptj9", "aoj_openj9", "16.0.1" }, + { "eliya", "eliya", "25.0.3" }, + { "gln", "gluon_graalvm", "23+25" }, + { "grl8", "graalvm_ce8", "21.3.1" }, + { "grl11", "graalvm_ce11", "22.3.3" }, + { "grl16", "graalvm_ce16", "21.2" }, + { "grl17", "graalvm_ce17", "22.3.3" }, + { "grl19", "graalvm_ce19", "22.3.1" }, + { "ojdkbld", "ojdk_build", "11.0.15", "zip" }, + { "opnlgc", "openlogic", "25.0.4+7" }, + { "rdht", "redhat", "21.0.8+9", "tar.xz" }, + { "semcrt", "semeru_certified", "25.0.4" }, +} +for _, other in ipairs(others) do + -- OJDKBuild and Gluon GraalVM ask for the newest release itself as well. + for _, key in ipairs({ other[3]:match("^%d+") .. " available", other[3] }) do + key = other[2] .. " " .. key + foojay[key] = foojay[key] or { pkg(other[3], false, other[4]) } + end +end + local requests = {} local responses = {} package.preload.http = function() @@ -131,8 +215,8 @@ package.preload.http = function() if params.latest then key = key .. " " .. params.latest end - if params.operating_system == "windows" then - key = "windows " .. key + if params.operating_system == "windows" or params.operating_system == "macos" then + key = params.operating_system .. " " .. key end -- Only the packages of the archive types asked for are listed. local result = {} @@ -187,6 +271,30 @@ local function check(version, expected, latest, archive_type) return lookups end +-- Installs version as OJDKBuild's and Gluon GraalVM's bare majors do: the +-- latest=available lookup names the newest release, and a second one asks +-- for that release in full, from which the package of the named file comes. +local function check_release_lookup(version, expected, release, filename) + requests = {} + local result = PLUGIN:PreInstall({ version = version }) + assert(result.version == expected, version .. ": expected " .. expected .. ", got " .. tostring(result.version)) + assert(result.url:sub(-#filename) == filename, version .. ": expected " .. filename .. ", got " .. result.url) + local lookups = {} + for _, url in ipairs(requests) do + if url:sub(1, #JDKS) == JDKS then + table.insert(lookups, url) + end + end + assert( + #lookups == 2 + and lookups[1]:find("&latest=available", 1, true) + and lookups[2]:find("?version=" .. release:gsub("%+", "%%2B") .. "&", 1, true) + and not lookups[2]:find("latest=", 1, true), + version .. ": unexpected lookups " .. table.concat(lookups, " ") + ) + cases = cases + 1 +end + -- A bare major installs its newest release, not the GA build. check("21-tem", "21.0.12.1+1-tem", true) check("temurin-21", "21.0.12.1+1-tem", true) @@ -266,6 +374,51 @@ assert( table.concat(jb, " ") == "21.0.11+1163116-jb 21.0.8+895146-jb 21.0.5+79248-jb", "Available jb on Windows: unexpected " .. table.concat(jb, " ") ) +-- OJDKBuild's bare major installs the JDK, not the JRE that latest=available +-- answers with, and no release installs an installer bundle or a Linux build. +check_release_lookup("17-ojdkbld", "17.0.3-ojdkbld", "17.0.3", "/java-17-openjdk-17.0.3.0.6-1.win.x86_64.zip") +check("11.0.14-ojdkbld", "11.0.14-ojdkbld", false, "windows.ojdkbuild.x86_64.zip") +check("8.0.161-ojdkbld", "8.0.161+14-ojdkbld", false, "b14.ojdkbuild.windows.x86_64.zip") +RUNTIME.osType = "linux" + +-- The distributions in others install by their short and long names, each from +-- its own Foojay distribution. +for _, other in ipairs(others) do + local short, long, release, archive_type = other[1], other[2], other[3], other[4] + local major = release:match("^%d+") + if long == "ojdk_build" or long == "gluon_graalvm" then + check_release_lookup(major .. "-" .. short, release .. "-" .. short, release, "." .. (archive_type or "tar.gz")) + check_release_lookup(long .. "-" .. major, release .. "-" .. short, release, "." .. (archive_type or "tar.gz")) + else + check(major .. "-" .. short, release .. "-" .. short, true, archive_type) + check(long .. "-" .. major, release .. "-" .. short, true, archive_type) + end +end +-- Only these distributions ask for another archive type besides tar.gz. +requests = {} +PLUGIN:PreInstall({ version = "21-rdht" }) +assert(requests[1]:find("&archive_type=tar.gz&archive_type=tar.xz&", 1, true), "21-rdht: " .. requests[1]) +requests = {} +PLUGIN:PreInstall({ version = "21-tem" }) +assert(requests[1]:find("&archive_type=tar.gz&operating_system=", 1, true), "21-tem: " .. requests[1]) +-- Gluon GraalVM's 22.x releases install their JDK 17 build, which they share a +-- version with the JDK 11 one, listed once by searching. +check_release_lookup("22-gln", "22.1.0.1-gln", "22.1.0.1", "/graalvm-svm-java17-linux-gluon-22.1.0.1-Final.tar.gz") +check_release_lookup("21-gln", "21.2-gln", "21.2", "/graalvm-svm-linux-gluon-21.2.0-dev.zip") +requests = {} +local gluon = PLUGIN:PreInstall({ version = "22.1.0.1-gln" }) +assert(gluon.url:find("/graalvm-svm-java17-", 1, true) and #requests == 2, "22.1.0.1-gln: " .. gluon.url) +local gln = {} +for _, item in ipairs(PLUGIN:Available({ args = { "gln" } })) do + table.insert(gln, item.version) +end +assert( + table.concat(gln, " ") == "23+25-gln 22.1.0.1-gln 21.2-gln", + "Available gln: unexpected " .. table.concat(gln, " ") +) +-- OpenLogic installs from a zip on macOS, where it ships no tar.gz. +RUNTIME.osType = "darwin" +check("25-opnlgc", "25.0.4+7-opnlgc", true, "zip") RUNTIME.osType = "linux" -- A distribution without a version, alone or after an empty one, asks for a diff --git a/tests/pre_use_test.lua b/tests/pre_use_test.lua index 76ace00..4beb8d2 100644 --- a/tests/pre_use_test.lua +++ b/tests/pre_use_test.lua @@ -41,6 +41,15 @@ for _, version in ipairs({ "21.0.2+13", "28-ea+18", "28-ea+19", + -- Some of the distributions added after release 0.6.2, two numbered after + -- GraalVM, with names that start like others. + "11.0.11-adpt", + "11.0.10-adptj9", + "22.3.3-grl17", + "22.3.1-grl11", + "21.0.8+9-rdht", + "25.0.4-semcrt", + "25.0.2+10-sem", }) do installed[version] = { name = "java", version = version, path = "/sdks/java-" .. version } end @@ -113,6 +122,20 @@ local cases = { { "21.0.8.0+7-tem", "21.0.8.0+7-tem" }, { "27.0.0+35-librca", "27.0.0+35-librca" }, { "26.0.0-graal", "26.0.0-graal" }, + -- The distributions added after release 0.6.2 go by their short and long + -- names too, and never cross to the one whose name starts the same. + { "11-adpt", "11.0.11-adpt" }, + { "11-adptj9", "11.0.10-adptj9" }, + { "aoj_openj9-11.0.10", "11.0.10-adptj9" }, + { "11.0.10-adpt", "11.0.10-adpt" }, + { "22-grl17", "22.3.3-grl17" }, + { "graalvm_ce17-22.3.3", "22.3.3-grl17" }, + { "22.3-grl11", "22.3-grl11" }, + { "21.0.8-rdht", "21.0.8+9-rdht" }, + { "redhat-21", "21.0.8+9-rdht" }, + { "25-semcrt", "25.0.4-semcrt" }, + { "25-sem", "25.0.2+10-sem" }, + { "semeru_certified-25.0.4", "25.0.4-semcrt" }, } for _, case in ipairs(cases) do local result = PLUGIN:PreUse({ version = case[1], installedSdks = installed })