Skip to content

fix(java): Add retry logic for transient SDKMAN bootstrap failures#1688

Open
V-Subhankar-infy wants to merge 5 commits into
devcontainers:mainfrom
V-Subhankar-infy:patch-java
Open

fix(java): Add retry logic for transient SDKMAN bootstrap failures#1688
V-Subhankar-infy wants to merge 5 commits into
devcontainers:mainfrom
V-Subhankar-infy:patch-java

Conversation

@V-Subhankar-infy

@V-Subhankar-infy V-Subhankar-infy commented Jul 20, 2026

Copy link
Copy Markdown
Member

Fix: Java feature transient SDKMAN 503 failures

Problem

The Java feature fails intermittently when get.sdkman.io returns HTTP 503 during bootstrap/install. No recovery mechanism exists, causing build failures and manual reruns. Reported at #1684 & #454.

Error: curl: (22) The requested URL returned error: 503

Solutions

1. Add Retry Logic (Temporary)

5 attempts, 10-second intervals (~50s total). Mirrors existing patterns in git, python, ruby, terraform features.

  • Minimal: 30 lines added
  • Proven: Same approach works in other features
  • Only tolerates transient failures (doesn't solve chronic SDKMAN downtime)

2. Switch to Alternative Package Source (Permanent)

Use OS package manager (apt install openjdk-*) or direct Temurin downloads instead of SDKMAN.

  • Limited to OpenJDK/LTS versions (no GraalVM, Corretto, Microsoft Java)
  • Breaks reproducibility (different JVMs per distro)
  • High maintenance: per-distro logic, test matrix explosion

Current Choice: Retry Logic

Why temporary over permanent?

  • No 100% viable alternative (all permanent solutions lose significant feature coverage)
  • Problem is transient, not systemic (intermittent 503s, not chronic downtime)
  • Maintenance burden unjustified by severity
  • SDKMAN is still the best solution when working

Strategy: Monitor for 2-3 weeks post-merge. If failures persist, revisit permanent solutions.

Implementation

Added to src/java/install.sh:

run_with_retries() {
    local max_attempts="$1" wait_seconds="$2" operation="$3" attempt=1
    shift 3
    until "$@"; do
        [ "${attempt}" -ge "${max_attempts}" ] && return 1
        echo "(*) ${operation} failed on attempt ${attempt}. Retrying in ${wait_seconds}s..."
        attempt=$((attempt + 1))
        sleep "${wait_seconds}"
    done
}

install_sdkman_cli() {
    bash -o pipefail -c 'curl -sSL "https://get.sdkman.io?rcupdate=false" | bash'
}

Applied to:

  • SDKMAN bootstrap: run_with_retries 5 10 "Installing SDKMAN" install_sdkman_cli
  • SDK install: run_with_retries 5 10 "Installing ${install_type} ${requested_version} via SDKMAN" ...

Total change: ~30 lines

Testing & Validation

Deterministic proof:

  • Baseline (unpatched + injected 503): Failed at 12s
  • Patched (same injected 503): Recovered at 79s with retry evidence in logs
  • No regression on healthy path: ~84-85s (same as before)
# Test command
devcontainer features test -f java --skip-scenarios -i ubuntu:noble --log-level info .

# Watch for retries
grep -i "retrying\|failed on attempt" logs

Impact

  • Reduces the transient SDKMAN 503s error due to added waiting.
  • No impact on user performance.
  • No Performance overhead.
  • No change in support of Java versions/distributions

Added a retry mechanism for SDK installation and SDKMAN CLI installation.
Mandatory minor bump for fixing the sdkman transient error
@V-Subhankar-infy
V-Subhankar-infy requested a review from a team as a code owner July 20, 2026 08:27
@V-Subhankar-infy
V-Subhankar-infy enabled auto-merge (squash) July 20, 2026 08:34
@V-Subhankar-infy
V-Subhankar-infy marked this pull request as draft July 20, 2026 09:07
auto-merge was automatically disabled July 20, 2026 09:07

Pull request was converted to draft

Java version updated due to upstream update from sdkman.
@V-Subhankar-infy
V-Subhankar-infy marked this pull request as ready for review July 20, 2026 13:02
@V-Subhankar-infy
V-Subhankar-infy requested a review from Copilot July 20, 2026 13:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to reduce intermittent failures in the Java feature by adding retry logic around SDKMAN installation/SDK-based installs, addressing transient HTTP 503 errors during SDKMAN bootstrap and candidate downloads.

Changes:

  • Added a run_with_retries helper and applied it to SDKMAN bootstrap and sdk install operations in src/java/install.sh.
  • Bumped the Java feature version to 1.8.1.
  • Updated the “latest” Java test expectation in test/java/install_latest_version.sh.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/java/install.sh Introduces and applies retry logic for SDKMAN bootstrap and SDK-based installs.
src/java/devcontainer-feature.json Bumps feature version to reflect behavioral change.
test/java/install_latest_version.sh Updates latest-version assertion (and currently contains a quoting bug in the hello-world check).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/java/install.sh
Comment thread test/java/install_latest_version.sh Outdated
@V-Subhankar-infy
V-Subhankar-infy marked this pull request as draft July 20, 2026 13:19
@V-Subhankar-infy
V-Subhankar-infy marked this pull request as ready for review July 20, 2026 13:55
@V-Subhankar-infy
V-Subhankar-infy enabled auto-merge (squash) July 20, 2026 13:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Java feature install experiencing frequent 503s from SDKMan

2 participants