Skip to content

Commit 27febe2

Browse files
pantherman594v-Kaniska244abdurriq
authored
Fix java version matching (#1714)
* Fix java version matching * Address PR feedback: escape + in regex, validate lts, add ms/tem tests - Escape `+` in requested_version regex substitutions so SDKMAN identifiers with build metadata (e.g. `21.0.12+1-ms`) match correctly. - Validate that the LTS branch resolves to a non-empty version before invoking `sdk install`, so a failed version lookup surfaces an error instead of silently installing SDKMAN's default candidate. - Add integration test scenarios covering major-only version resolution for the `ms` and `tem` JDK distributions. * Update scenarios.json with Java installation configurations Added configurations for installing additional Java versions and Java 8 MS distribution on Debian. * Add test scenario scripts --------- Co-authored-by: Kaniska <kaniska244@github.com> Co-authored-by: Abdurrahmaan Iqbal <abdurriq@github.com>
1 parent ecceac4 commit 27febe2

7 files changed

Lines changed: 117 additions & 30 deletions

‎src/java/devcontainer-feature.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"id": "java",
3-
"version": "1.8.1",
3+
"version": "1.8.2",
44
"name": "Java (via SDKMAN!)",
55
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/java",
66
"description": "Installs Java, SDKMAN! (if not installed), and needed dependencies.",

‎src/java/install.sh‎

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -219,30 +219,32 @@ install_sdkman_cli() {
219219
}
220220

221221
find_version_list() {
222-
prefix="$1"
223-
suffix="$2"
224-
install_type=$3
225-
ifLts="$4"
226-
version_list=$5
227-
java_ver=$6
228-
229-
check_packages jq
230-
all_versions=$(curl -s https://api.adoptium.net/v3/info/available_releases)
231-
if [ "${ifLts}" = "true" ]; then
232-
major_version=$(echo "$all_versions" | jq -r '.most_recent_lts')
233-
elif [ "${java_ver}" = "latest" ]; then
234-
major_version=$(echo "$all_versions" | jq -r '.most_recent_feature_release')
222+
install_type=$1
223+
version_list=$2
224+
java_ver=$3
225+
226+
if [ "${java_ver}" = "lts" ] || [ "${java_ver}" = "latest" ]; then
227+
check_packages jq
228+
major_versions=$(curl -s https://api.adoptium.net/v3/info/available_releases)
229+
if [ "${java_ver}" = "lts" ]; then
230+
major_version=$(echo "$major_versions" | jq -r '.most_recent_lts')
231+
else
232+
major_version=$(echo "$major_versions" | jq -r '.most_recent_feature_release')
233+
fi
235234
else
236235
major_version=$(echo "$java_ver" | cut -d '.' -f 1)
237236
fi
237+
238+
platform="$(cat ${SDKMAN_DIR}/var/platform)"
239+
all_versions=$(curl -s "https://api.sdkman.io/2/candidates/${install_type}/${platform}/versions/all" | tr ',' '\n' | tr -d '\r')
238240

239241
# Remove the hardcoded fallback as this fails for new jdk latest version released ex: 24
240242
# Related Issue: https://github.com/devcontainers/features/issues/1308
241243
if [ "${JDK_DISTRO}" = "ms" ]; then
242244
# Check if the requested version is available in the 'ms' distribution
243245
echo "Check if OpenJDK is available for version ${major_version} for ${JDK_DISTRO} Distro"
244-
available_versions=$(su ${USERNAME} -c ". ${SDKMAN_DIR}/bin/sdkman-init.sh && sdk list ${install_type} | grep ${JDK_DISTRO} | grep -oE '[0-9]+(\.[0-9]+(\.[0-9]+)?)?' | sort -u")
245-
if echo "${available_versions}" | grep -q "^${major_version}"; then
246+
available_versions=$(echo "${all_versions}" | grep -- "-${JDK_DISTRO}" | sort -u)
247+
if echo "${available_versions}" | grep -q "^${major_version}\\."; then
246248
echo "JDK version ${major_version} is available in ${JDK_DISTRO}..."
247249
else
248250
echo "JDK version ${major_version} not available in ${JDK_DISTRO}.... Switching to (tem)."
@@ -251,21 +253,19 @@ find_version_list() {
251253
fi
252254
echo "JDK_DISTRO: ${JDK_DISTRO}"
253255
if [ "${install_type}" != "java" ]; then
254-
regex="${prefix}\\K[0-9]+\\.?[0-9]*\\.?[0-9]*${suffix}"
256+
regex="^${major_version}\\.[0-9]+(\\.[0-9]+)*$"
255257
else
256-
regex="${prefix}\\K${major_version}\\.?[0-9]*\\.?[0-9]*${suffix}${JDK_DISTRO}\\s*"
258+
regex="^${major_version}\\.[0-9]+(\\.[0-9]+)*(\\.r[0-9]+)?(\\+[a-z0-9]+(\\.[a-z0-9]+)*)?-${JDK_DISTRO}$"
257259
fi
258-
declare -g ${version_list}="$(su ${USERNAME} -c ". \${SDKMAN_DIR}/bin/sdkman-init.sh && sdk list ${install_type} 2>&1 | grep -oP \"${regex}\" | tr -d ' ' | sort -rV")"
260+
declare -g ${version_list}="$(echo "${all_versions}" | grep -E "${regex}" | sort -rV)"
259261
}
260262

261263
# Use SDKMAN to install something using a partial version match
262264
sdk_install() {
263265
local install_type=$1
264266
local requested_version=$2
265-
local prefix=$3
266-
local suffix="${4:-"\\s*"}"
267-
local full_version_check=${5:-".*-[a-z]+"}
268-
local set_as_default=${6:-"true"}
267+
local full_version_check=${3:-".*-[a-z]+"}
268+
local set_as_default=${4:-"true"}
269269
pkgs=("maven" "gradle" "ant" "groovy")
270270
pkg_vals="${pkgs[@]}"
271271
if [ "${requested_version}" = "none" ]; then return; fi
@@ -274,24 +274,30 @@ sdk_install() {
274274
elif [[ "${pkg_vals}" =~ "${install_type}" ]] && [ "${requested_version}" = "latest" ]; then
275275
requested_version=""
276276
elif [ "${requested_version}" = "lts" ]; then
277-
find_version_list "$prefix" "$suffix" "$install_type" "true" version_list "${requested_version}"
277+
find_version_list "$install_type" version_list "${requested_version}"
278278
requested_version="$(echo "${version_list}" | head -n 1)"
279+
if [ -z "${requested_version}" ]; then
280+
echo -e "LTS version not found. Available versions:\n${version_list}" >&2
281+
exit 1
282+
fi
279283
elif echo "${requested_version}" | grep -oE "${full_version_check}" > /dev/null 2>&1; then
280284
echo "${requested_version}"
281285
else
282-
find_version_list "$prefix" "$suffix" "$install_type" "false" version_list "${requested_version}"
286+
find_version_list "$install_type" version_list "${requested_version}"
283287
if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ]; then
284288
requested_version="$(echo "${version_list}" | head -n 1)"
285289
else
290+
escaped_version="${requested_version//./\\.}"
291+
escaped_version="${escaped_version//+/\\+}"
286292
set +e
287-
requested_version="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|-|$)")"
293+
requested_version="$(echo "${version_list}" | grep -E -m 1 "^${escaped_version}([\\.\\s]|-|$)")"
288294
set -e
289295
fi
290296
if [ -z "${requested_version}" ] || ! echo "${version_list}" | grep "^${requested_version//./\\.}$" > /dev/null 2>&1; then
291297
# Fallback to LTS if "latest" was requested and not found (java only)
292298
if [ "$2" = "latest" ] && [ "${install_type}" = "java" ]; then
293299
echo "Latest version not found in SDKMAN. Falling back to LTS..."
294-
find_version_list "$prefix" "$suffix" "$install_type" "true" version_list "lts"
300+
find_version_list "$install_type" version_list "lts"
295301
requested_version="$(echo "${version_list}" | head -n 1)"
296302
if [ -z "${requested_version}" ] || ! echo "${version_list}" | grep "^${requested_version//./\\.}$" > /dev/null 2>&1; then
297303
echo -e "Version $2 (and LTS fallback) not found. Available versions:\n${version_list}" >&2
@@ -370,15 +376,15 @@ if [ ! -d "${SDKMAN_DIR}" ]; then
370376
updaterc "export SDKMAN_DIR=${SDKMAN_DIR}\n. \${SDKMAN_DIR}/bin/sdkman-init.sh"
371377
fi
372378

373-
sdk_install java ${JAVA_VERSION} "\\s*" "(\\.[a-z0-9]+)*-" ".*-[a-z]+$" "true"
379+
sdk_install java ${JAVA_VERSION} ".*-[a-z]+$" "true"
374380

375381
# Additional java versions to be installed but not be set as default.
376382
if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then
377383
OLDIFS=$IFS
378384
IFS=","
379385
read -a additional_versions <<< "$ADDITIONAL_VERSIONS"
380386
for version in "${additional_versions[@]}"; do
381-
sdk_install java ${version} "\\s*" "(\\.[a-z0-9]+)*-" ".*-[a-z]+$" "false"
387+
sdk_install java ${version} ".*-[a-z]+$" "false"
382388
done
383389
IFS=$OLDIFS
384390
su ${USERNAME} -c ". ${SDKMAN_DIR}/bin/sdkman-init.sh && sdk default java ${JAVA_VERSION}"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Optional: Import test library
6+
source dev-container-features-test-lib
7+
8+
check "java version openjdk 25 installed as default" grep "openjdk 25\." <(java --version)
9+
check "java version 21 installed as additional version" grep "^21\." <(ls /usr/local/sdkman/candidates/java)
10+
11+
# Report result
12+
reportResults
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Optional: Import test library
6+
source dev-container-features-test-lib
7+
8+
check "java version openjdk 8 installed" /bin/bash -c 'java -version 2>&1 | grep "openjdk version \"1.8\."'
9+
10+
# Report result
11+
reportResults
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Optional: Import test library
6+
source dev-container-features-test-lib
7+
8+
check "java version openjdk 21 installed" grep "openjdk 21." <(java --version)
9+
10+
# Report result
11+
reportResults
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Optional: Import test library
6+
source dev-container-features-test-lib
7+
8+
check "java version openjdk 21 installed" grep "openjdk 21." <(java --version)
9+
10+
# Report result
11+
reportResults

‎test/java/scenarios.json‎

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
11
{
2+
"install_additional_java_versions": {
3+
"image": "ubuntu:noble",
4+
"features": {
5+
"java": {
6+
"version": "25",
7+
"additionalVersions": "21"
8+
}
9+
}
10+
},
11+
"install_java_8_ms_distro_debian": {
12+
"image": "mcr.microsoft.com/devcontainers/base:debian",
13+
"features": {
14+
"java": {
15+
"version": "8",
16+
"jdkDistro": "ms"
17+
}
18+
}
19+
},
220
"install_from_non_default_distro": {
321
"image": "ubuntu:noble",
422
"features": {
@@ -8,6 +26,24 @@
826
}
927
}
1028
},
29+
"install_major_only_ms_distro": {
30+
"image": "ubuntu:noble",
31+
"features": {
32+
"java": {
33+
"version": "21",
34+
"jdkDistro": "ms"
35+
}
36+
}
37+
},
38+
"install_major_only_tem_distro": {
39+
"image": "ubuntu:noble",
40+
"features": {
41+
"java": {
42+
"version": "21",
43+
"jdkDistro": "tem"
44+
}
45+
}
46+
},
1147
"install_latest_version": {
1248
"image": "ubuntu:noble",
1349
"features": {
@@ -223,4 +259,4 @@
223259
"java": {}
224260
}
225261
}
226-
}
262+
}

0 commit comments

Comments
 (0)