1+ # syntax=docker/dockerfile:1.7
12# Layer 2: Java Bench Image
23# Extends Layer 1 (dev-bench-base) with Java specific tools
3- # Includes: OpenJDK 21 , Maven, Gradle, Spring CLI, Java tools
4+ # Includes: OpenJDK 25 , Maven, Gradle, Spring CLI, Java tools
45
56ARG BASE_IMAGE=dev-bench-base:latest
67FROM ${BASE_IMAGE}
78
8- ARG JACOCO_VERSION=0.8.14
9- ARG SONAR_MAVEN_PLUGIN_VERSION=5.6.0.6792
10- ARG SONAR_GRADLE_PLUGIN_VERSION=7.3.0.8198
9+ ARG JACOCO_VERSION=0.8.15
10+ ARG SONAR_MAVEN_PLUGIN_VERSION=5.7.0.6970
11+ ARG SONAR_GRADLE_PLUGIN_VERSION=7.3.1.8318
12+ ARG SPRINGBOOT_VERSION=4.1.0
13+ ARG KOTLIN_VERSION=2.4.0
14+ ARG GROOVY_VERSION=6.0.0-alpha-1
15+ ARG SCALA_VERSION=3.8.4
16+ ARG QUARKUS_VERSION=3.37.1
17+ ARG MICRONAUT_VERSION=5.0.3
1118
1219# Container version labels
1320LABEL layer="2"
1421LABEL layer.name="java-bench"
15- LABEL layer.version="2.2.1 "
22+ LABEL layer.version="2.2.10 "
1623LABEL layer.description="Java development tools and JDK (user-agnostic)"
1724LABEL bench.type="java"
1825
@@ -23,21 +30,27 @@ USER root
2330# JAVA JDK
2431# ========================================
2532
26- # Install OpenJDK 21 (LTS) and zip (required by SDKMAN)
33+ # Install OpenJDK 25 (LTS) and zip (required by SDKMAN)
2734RUN apt-get update && apt-get install -y \
28- openjdk-21 -jdk \
29- openjdk-21 -jre \
35+ openjdk-25 -jdk \
36+ openjdk-25 -jre \
3037 zip \
3138 && rm -rf /var/lib/apt/lists/*
3239
3340# Set JAVA_HOME
34- ENV JAVA_HOME=/usr/lib/jvm/java-21 -openjdk-amd64
41+ ENV JAVA_HOME=/usr/lib/jvm/java-25 -openjdk-amd64
3542ENV PATH="$JAVA_HOME/bin:$PATH"
3643ENV JACOCO_VERSION=${JACOCO_VERSION}
3744ENV JACOCO_CLI_JAR=/opt/jacoco/jacococli.jar
3845ENV JACOCO_AGENT_JAR=/opt/jacoco/jacocoagent.jar
3946ENV SONAR_MAVEN_PLUGIN_VERSION=${SONAR_MAVEN_PLUGIN_VERSION}
4047ENV SONAR_GRADLE_PLUGIN_VERSION=${SONAR_GRADLE_PLUGIN_VERSION}
48+ ENV SPRINGBOOT_VERSION=${SPRINGBOOT_VERSION}
49+ ENV KOTLIN_VERSION=${KOTLIN_VERSION}
50+ ENV GROOVY_VERSION=${GROOVY_VERSION}
51+ ENV SCALA_VERSION=${SCALA_VERSION}
52+ ENV QUARKUS_VERSION=${QUARKUS_VERSION}
53+ ENV MICRONAUT_VERSION=${MICRONAUT_VERSION}
4154
4255# ========================================
4356# BUILD TOOLS
@@ -48,29 +61,83 @@ RUN apt-get update && apt-get install -y \
4861 maven \
4962 && rm -rf /var/lib/apt/lists/*
5063
51- # Install Gradle
52- RUN wget https://services.gradle.org/distributions/gradle-8.5-bin.zip -P /tmp \
53- && unzip -d /opt/gradle /tmp/gradle-8.5-bin.zip \
54- && rm /tmp/gradle-8.5-bin.zip \
55- && ln -s /opt/gradle/gradle-8.5/bin/gradle /usr/local/bin/gradle
64+ # Install a resumable, multi-connection downloader for large tool distributions.
65+ RUN apt-get update && apt-get install -y --no-install-recommends \
66+ aria2 \
67+ && rm -rf /var/lib/apt/lists/*
5668
57- ENV GRADLE_HOME=/opt/gradle/gradle-8.5
69+ # Install Gradle
70+ RUN aria2c --allow-overwrite=true --auto-file-renaming=false --continue=true \
71+ --max-connection-per-server=8 --split=8 --min-split-size=8M \
72+ --max-tries=10 --retry-wait=5 --connect-timeout=30 --timeout=120 \
73+ --summary-interval=30 --console-log-level=warn \
74+ -d /tmp -o gradle-9.6.1-bin.zip \
75+ https://downloads.gradle.org/distributions/gradle-9.6.1-bin.zip \
76+ && unzip -d /opt/gradle /tmp/gradle-9.6.1-bin.zip \
77+ && rm /tmp/gradle-9.6.1-bin.zip \
78+ && ln -s /opt/gradle/gradle-9.6.1/bin/gradle /usr/local/bin/gradle
79+
80+ ENV GRADLE_HOME=/opt/gradle/gradle-9.6.1
5881ENV PATH="$GRADLE_HOME/bin:$PATH"
82+ ENV CURL_RETRY_OPTS="--retry 5 --retry-delay 5 --connect-timeout 30 --max-time 600"
83+ ENV ARIA2_RETRY_OPTS="--allow-overwrite=true --auto-file-renaming=false --continue=true --max-connection-per-server=8 --split=8 --min-split-size=1M --max-tries=10 --retry-wait=5 --connect-timeout=30 --timeout=120 --summary-interval=30 --console-log-level=warn"
5984
6085# ========================================
6186# JAVA DEVELOPMENT TOOLS
6287# ========================================
6388
6489# Install SDKMan system-wide
65- RUN curl -s "https://get.sdkman.io" | bash \
90+ RUN curl -fsSL $CURL_RETRY_OPTS "https://get.sdkman.io" | bash \
6691 && bash -c "source $HOME/.sdkman/bin/sdkman-init.sh" \
6792 && mv /root/.sdkman /opt/sdkman \
6893 && chmod -R a+rx /opt/sdkman
6994
7095ENV SDKMAN_DIR=/opt/sdkman
7196
72- # Install Spring Boot CLI via SDKMAN
73- RUN bash -c "source /opt/sdkman/bin/sdkman-init.sh && sdk install springboot" || true
97+ # Install SDKMAN-hosted JVM CLIs with resumable downloads. Calling `sdk install`
98+ # directly can fall back to a slow single-stream downloader inside Docker.
99+ RUN --mount=type=cache,target=/var/cache/sdkman-downloads,sharing=locked set -eux; \
100+ install_sdkman_archive() { \
101+ candidate="$1"; \
102+ version="$2"; \
103+ install_dir="/opt/${candidate}-${version}"; \
104+ download_dir="/var/cache/sdkman-downloads"; \
105+ archive="${download_dir}/${candidate}-${version}.zip"; \
106+ extract_dir="/tmp/${candidate}-${version}-extract"; \
107+ rm -rf "$install_dir" "$extract_dir"; \
108+ mkdir -p "$download_dir" "$extract_dir"; \
109+ aria2c $ARIA2_RETRY_OPTS -d "$download_dir" -o "$(basename "$archive")" \
110+ "https://api.sdkman.io/2/broker/download/${candidate}/${version}/linuxx64"; \
111+ unzip -q "$archive" -d "$extract_dir"; \
112+ first_entry="$(find "$extract_dir" -mindepth 1 -maxdepth 1 | head -n1)"; \
113+ entry_count="$(find "$extract_dir" -mindepth 1 -maxdepth 1 | wc -l)"; \
114+ mkdir -p "$install_dir"; \
115+ if [ "$entry_count" = "1" ] && [ -d "$first_entry" ]; then \
116+ cp -a "$first_entry"/. "$install_dir"/; \
117+ else \
118+ cp -a "$extract_dir"/. "$install_dir"/; \
119+ fi; \
120+ chmod -R a+rX "$install_dir"; \
121+ if [ -d "$install_dir/bin" ]; then \
122+ find "$install_dir/bin" -maxdepth 1 -type f -perm /111 -printf '%f\n' | \
123+ while read -r tool; do \
124+ ln -sf "$install_dir/bin/$tool" "/usr/local/bin/$tool"; \
125+ done; \
126+ fi; \
127+ rm -rf "$extract_dir"; \
128+ }; \
129+ install_sdkman_archive springboot "$SPRINGBOOT_VERSION"; \
130+ install_sdkman_archive kotlin "$KOTLIN_VERSION"; \
131+ install_sdkman_archive groovy "$GROOVY_VERSION"; \
132+ install_sdkman_archive scala "$SCALA_VERSION"; \
133+ install_sdkman_archive quarkus "$QUARKUS_VERSION"; \
134+ install_sdkman_archive micronaut "$MICRONAUT_VERSION"; \
135+ spring --version; \
136+ kotlin -version; \
137+ groovy --version; \
138+ scala -version; \
139+ quarkus --version; \
140+ mn --version
74141
75142# ========================================
76143# CONTAINER TOOLING
@@ -80,7 +147,7 @@ RUN bash -c "source /opt/sdkman/bin/sdkman-init.sh && sdk install springboot" ||
80147RUN apt-get update && apt-get install -y \
81148 ca-certificates gnupg lsb-release \
82149 && install -m 0755 -d /etc/apt/keyrings \
83- && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --batch --yes --dearmor -o /etc/apt/keyrings/docker.gpg \
150+ && curl -fsSL $CURL_RETRY_OPTS https://download.docker.com/linux/ubuntu/gpg | gpg --batch --yes --dearmor -o /etc/apt/keyrings/docker.gpg \
84151 && chmod a+r /etc/apt/keyrings/docker.gpg \
85152 && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list \
86153 && apt-get update && apt-get install -y docker-ce-cli docker-compose-plugin \
@@ -103,33 +170,37 @@ RUN apt-get update && apt-get install -y \
103170
104171# Checkstyle
105172RUN mkdir -p /opt/checkstyle \
106- && curl -fsSL https://github.com/checkstyle/checkstyle/releases/download/checkstyle-10.21.4/checkstyle-10.21.4-all.jar \
107- -o /opt/checkstyle/checkstyle.jar
173+ && aria2c $ARIA2_RETRY_OPTS -d /opt/checkstyle -o checkstyle.jar \
174+ https://github.com/checkstyle/checkstyle/releases/download/checkstyle-13.7.0/checkstyle-13.7.0-all.jar \
175+ && printf '%s\n' '#!/usr/bin/env sh' \
176+ 'exec java -jar /opt/checkstyle/checkstyle.jar "$@"' \
177+ > /usr/local/bin/checkstyle \
178+ && chmod +x /usr/local/bin/checkstyle
108179
109180# SpotBugs
110- RUN curl -fsSL https://github.com/spotbugs/spotbugs/releases/download/4.8.6/spotbugs-4.8.6 .tgz \
111- -o /tmp/ spotbugs.tgz \
181+ RUN aria2c $ARIA2_RETRY_OPTS -d /tmp -o spotbugs .tgz \
182+ https://github.com/ spotbugs/spotbugs/releases/download/4.10.2/spotbugs-4.10.2 .tgz \
112183 && tar -xzf /tmp/spotbugs.tgz -C /opt \
113- && chmod +x /opt/spotbugs-4.8.6 /bin/spotbugs \
114- && ln -s /opt/spotbugs-4.8.6 /bin/spotbugs /usr/local/bin/spotbugs \
184+ && chmod +x /opt/spotbugs-4.10.2 /bin/spotbugs \
185+ && ln -s /opt/spotbugs-4.10.2 /bin/spotbugs /usr/local/bin/spotbugs \
115186 && rm /tmp/spotbugs.tgz
116187
117188# PMD
118- RUN curl -fsSL https://github.com/pmd/pmd/releases/download/pmd_releases%2F7.9.0/pmd-dist-7.9.0-bin .zip \
119- -o /tmp/ pmd.zip \
189+ RUN aria2c $ARIA2_RETRY_OPTS -d /tmp -o pmd .zip \
190+ https://github.com/ pmd/pmd/releases/download/pmd_releases%2F7.26.0/pmd-dist-7.26.0-bin .zip \
120191 && unzip -q /tmp/pmd.zip -d /opt \
121- && ln -s /opt/pmd-bin-7.9 .0/bin/pmd /usr/local/bin/pmd \
192+ && ln -s /opt/pmd-bin-7.26 .0/bin/pmd /usr/local/bin/pmd \
122193 && rm /tmp/pmd.zip
123194
124195# JaCoCo coverage tools for manual Java coverage workflows.
125196COPY files/jacoco-cli /usr/local/bin/jacoco-cli
126197COPY files/sonarcloud-java-maven /usr/local/bin/sonarcloud-java-maven
127198COPY files/sonarcloud-java-gradle /usr/local/bin/sonarcloud-java-gradle
128199RUN mkdir -p /opt/jacoco \
129- && curl -fsSL "https://repo1.maven.org/maven2/org/ jacoco/org.jacoco.cli/${JACOCO_VERSION}/org.jacoco.cli-${JACOCO_VERSION}-nodeps .jar" \
130- -o /opt/ jacoco/jacococli. jar \
131- && curl -fsSL "https://repo1.maven.org/maven2/org/ jacoco/org.jacoco.agent/${JACOCO_VERSION}/org.jacoco.agent-${JACOCO_VERSION}-runtime .jar" \
132- -o /opt/ jacoco/jacocoagent. jar \
200+ && aria2c $ARIA2_RETRY_OPTS -d /opt/ jacoco -o jacococli .jar \
201+ "https://repo1.maven.org/maven2/org/ jacoco/org.jacoco.cli/${JACOCO_VERSION}/org.jacoco.cli-${JACOCO_VERSION}-nodeps. jar" \
202+ && aria2c $ARIA2_RETRY_OPTS -d /opt/ jacoco -o jacocoagent .jar \
203+ "https://repo1.maven.org/maven2/org/ jacoco/org.jacoco.agent/${JACOCO_VERSION}/org.jacoco.agent-${JACOCO_VERSION}-runtime. jar" \
133204 && chmod +x /usr/local/bin/jacoco-cli /usr/local/bin/sonarcloud-java-maven /usr/local/bin/sonarcloud-java-gradle
134205
135206# SonarScanner CLI is inherited from dev-bench-base.
@@ -139,12 +210,6 @@ RUN sonar-scanner --version
139210# JVM COMPANION LANGUAGES
140211# ========================================
141212
142- # Install Kotlin, Groovy, Scala via SDKMAN
143- RUN bash -c "source /opt/sdkman/bin/sdkman-init.sh \
144- && sdk install kotlin \
145- && sdk install groovy \
146- && sdk install scala" || true
147-
148213# ========================================
149214# SYSTEM UTILITIES
150215# ========================================
@@ -160,35 +225,36 @@ RUN apt-get update && apt-get install -y \
160225# FRAMEWORK CLIs
161226# ========================================
162227
163- # Install Quarkus and Micronaut CLIs via SDKMAN
164- # (Spring Boot CLI already installed above)
165- RUN bash -c "source /opt/sdkman/bin/sdkman-init.sh \
166- && sdk install quarkus \
167- && sdk install micronaut" || true
168-
169228# ========================================
170229# PERFORMANCE TESTING
171230# ========================================
172231
173232# Apache JMeter 5.6.3
174- RUN curl -fsSL https://dlcdn.apache.org/jmeter/binaries/apache- jmeter-5.6.3 .tgz \
175- -o /tmp/ jmeter.tgz \
233+ RUN aria2c $ARIA2_RETRY_OPTS -d /tmp -o jmeter.tgz \
234+ https://dlcdn.apache.org/ jmeter/binaries/apache-jmeter-5.6.3 .tgz \
176235 && tar -xzf /tmp/jmeter.tgz -C /opt \
177236 && ln -s /opt/apache-jmeter-5.6.3/bin/jmeter /usr/local/bin/jmeter \
178237 && rm /tmp/jmeter.tgz
179238
180239ENV JMETER_HOME=/opt/apache-jmeter-5.6.3
181240
182- # Gatling 3.10.5 (last traditional standalone bundle)
183- RUN curl -fsSL https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/3.10.5/ gatling-charts-highcharts-bundle-3.10.5-bundle .zip \
184- -o /tmp /gatling.zip \
241+ # Gatling standalone bundle
242+ RUN aria2c $ARIA2_RETRY_OPTS -d /tmp -o gatling.zip \
243+ https://repo1.maven.org/maven2/io/gatling/highcharts/gatling-charts-highcharts-bundle/3.15.1 /gatling-charts-highcharts-bundle-3.15.1-bundle .zip \
185244 && unzip -q /tmp/gatling.zip -d /opt \
186- && chmod +x /opt/gatling-charts-highcharts-bundle-3.10.5/bin/*.sh \
187- && ln -s /opt/gatling-charts-highcharts-bundle-3.10.5/bin/gatling.sh /usr/local/bin/gatling \
188- && ln -s /opt/gatling-charts-highcharts-bundle-3.10.5/bin/recorder.sh /usr/local/bin/gatling-recorder \
245+ && chmod +x /opt/gatling-charts-highcharts-bundle-3.15.1/mvnw \
246+ && printf '%s\n' '#!/usr/bin/env bash' \
247+ 'set -euo pipefail' \
248+ 'cd "${GATLING_HOME:-/opt/gatling-charts-highcharts-bundle-3.15.1}"' \
249+ 'exec ./mvnw gatling:test "$@"' > /usr/local/bin/gatling \
250+ && printf '%s\n' '#!/usr/bin/env bash' \
251+ 'set -euo pipefail' \
252+ 'cd "${GATLING_HOME:-/opt/gatling-charts-highcharts-bundle-3.15.1}"' \
253+ 'exec ./mvnw gatling:recorder "$@"' > /usr/local/bin/gatling-recorder \
254+ && chmod +x /usr/local/bin/gatling /usr/local/bin/gatling-recorder \
189255 && rm /tmp/gatling.zip
190256
191- ENV GATLING_HOME=/opt/gatling-charts-highcharts-bundle-3.10.5
257+ ENV GATLING_HOME=/opt/gatling-charts-highcharts-bundle-3.15.1
192258
193259# ========================================
194260# WORKSPACE SETUP
@@ -213,8 +279,8 @@ RUN mkdir -p /etc/skel/.m2 \
213279# Add Java development aliases and environment to /etc/skel/.zshrc
214280RUN echo '' >> /etc/skel/.zshrc && \
215281 echo '# Java Development Environment' >> /etc/skel/.zshrc && \
216- echo 'export JAVA_HOME=/usr/lib/jvm/java-21 -openjdk-amd64' >> /etc/skel/.zshrc && \
217- echo 'export GRADLE_HOME=/opt/gradle/gradle-8.5 ' >> /etc/skel/.zshrc && \
282+ echo 'export JAVA_HOME=/usr/lib/jvm/java-25 -openjdk-amd64' >> /etc/skel/.zshrc && \
283+ echo 'export GRADLE_HOME=/opt/gradle/gradle-9.6.1 ' >> /etc/skel/.zshrc && \
218284 echo 'export PATH="$JAVA_HOME/bin:$GRADLE_HOME/bin:$PATH"' >> /etc/skel/.zshrc && \
219285 echo '' >> /etc/skel/.zshrc && \
220286 echo '# Java Build aliases' >> /etc/skel/.zshrc && \
0 commit comments