Open nezartarbin opened 1 year ago
Hi @nezartarbin!
Have you tried running the container as an unprivileged user? SDKMAN! is not intended to be run as root.
Hi @helpermethod !
Thanks for the advice. I tried doing this with a non-root user, but it does not work still. I followed similar steps to the above, but with a different containerfile.
FROM alpine:3.16
ARG JDK_VERSION="17.0.4.1"
ARG MAVEN_VERSION="3.8.6"
RUN apk update \
&& apk upgrade \
&& apk add --no-cache bash curl zip \
&& adduser -D oat
USER oat
SHELL ["/bin/bash", "-c"]
RUN curl "https://get.sdkman.io" | bash \
&& source $HOME/.sdkman/bin/sdkman-init.sh \
&& sdk install java $JDK_VERSION-tem \
&& sdk install maven $MAVEN_VERSION \
&& sdk install springboot
CMD ["bash"]
again, I:
Containerfile
podman build -f Containerfile -t spring-temurin-maven-alpine
podman run -dt spring-temurin-maven-alpine
podman attach -l
# whoami
oat
# java --version
bash: /home/oat/.sdkman/candidates/java/current/bin/java: No such file or directory
Does SDKMAN! have any hard dependency on glibc or GNU coreutils? I suppose this may be one reason that it would have issues with alpine linux, as it is unique as a linux distro in using musl instead of glibc ans busybox instead of coreutils.
Hi @nezartarbin,
thanks for providing the containerfile. It seems even with glibc installed the OpenJDKs provided by SDKMAN! don't work, but we are using Foojay's DiscoAPI, which provides special OpenJDK versions for Alpine.
I'll speak with the team to see how much effort this is (doesn't look too hard from a first glance).
any progress ?
I have the same problem, the installation via SDKMan succeeds but running a java program fails (with the errors already mentioned by @nezartarbin )
The problem might be related to https://gitlab.alpinelinux.org/alpine/aports/-/issues/12981
@eddumelendez any ideas regarding this?
I can reproduce the problem with Docker (for Desktop) on my MacOS 13 as well.
Looks like the java
binary is linked to a shared library which is missing some symbols:
$ ldd /root/.sdkman/candidates/java/current/bin/java
/lib64/ld-linux-x86-64.so.2 (0x7f8439027000)
libz.so.1 => /lib/libz.so.1 (0x7f8439008000)
libjli.so => /root/.sdkman/candidates/java/current/bin/../lib/libjli.so (0x7f8438ff5000)
libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f8439027000)
libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7f8439027000)
libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f8439027000)
Error relocating /root/.sdkman/candidates/java/current/bin/../lib/libjli.so: __strdup: symbol not found
Error relocating /root/.sdkman/candidates/java/current/bin/../lib/libjli.so: __rawmemchr: symbol not found
Where can I find more information, how the Temurin builds are provided for sdkman (on Alpine)?
@nezartarbin you probably want to make use of an official Temurin build for your Alpine JDK installation by following the instructions here: https://adoptium.net/en-GB/installation/linux/#_alpine_linux_instructions?
I only tested the java -version
by now, and it works
# /usr/lib/jvm/java-17-temurin/bin/java -version
openjdk version "17.0.5" 2022-10-18
OpenJDK Runtime Environment Temurin-17.0.5+8 (build 17.0.5+8)
OpenJDK 64-Bit Server VM Temurin-17.0.5+8 (build 17.0.5+8, mixed mode, sharing)
ldd
finds all libraries and does not complain over missing symbols if used on the real binary (not on /usr/bin/java
which is a symbolic link):
# ldd /usr/lib/jvm/java-17-temurin/bin/java
/lib/ld-musl-x86_64.so.1 (0x7f58f35f5000)
libjli.so => /usr/lib/jvm/java-17-temurin/bin/../lib/libjli.so (0x7f58f35de000)
libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f58f35f5000)
libz.so.1 => /lib/libz.so.1 (0x7f58f35c4000)
However, as @eddumelendez mentioned in the respective Slack discussion, the problem seems to be related to the usage of glibc vs. musl. The Temurin package as provided by Adoptium is using musl.
Nevertheless, latest Temurin JDK builds were never (automatically) tested for the current Alpine releases in a clean way (only the edge
version) -> adoptium/installer#590.
Currently there is no way for SDKMAN! to detect if the currently running Linux is an Alpine.
So as a first step, SDKMAN! would need to detect this, e.g. by checking the existence of /etc/alpine-release
[[ -f /etc/alpine-release ]]
Then we would need to pass this information to the SDKMAN! backend (the SDKMAN! candidates service), which then needs to incorporate this information to only return JDK versions which work for Alpine.
And we would also need to add support for musl-based JDKs to our Disco API importer.
Wdyt @eddumelendez @marc0der? I've probably forgotten a few steps :D.
@helpermethod I think the problem might be related to Alpine's use of the musl
C library instead of glibc
. I would suggest checking for that instead, like maybe via checking if the output of ldd /bin/usr/env
includes musl (via grep maybe?)
This way the fix would be generalized to other musl distributions
I have the same issue trying to install sdkman and Java on Alpine: For example, with the following Dockerfile:
FROM alpine:3.18.4
RUN apk update
RUN apk add bash curl zip
RUN addgroup -S my-group && adduser -S my-user -G my-group -s bash
USER my-user
WORKDIR /home/my-user
RUN curl -s "https://get.sdkman.io" | bash
RUN bash -c "export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$JAVA_HOME/lib/server" && source $HOME/.sdkman/bin/sdkman-init.sh"
The image is created via docker build -t sdkman-example .
. When I run the container via docker container run --rm -it sdkman-example bash
I get errors depending on the command I run:
>sdk list
# Ok, This returns a list of candidates
>sdk version
bash: /home/my-user/.sdkman/libexec/version: cannot execute: required file not found
From the previous comments I assumed it was related to the missing glibc. I then added in the dockerfile:
# https://wiki.alpinelinux.org/wiki/Running_glibc_programs
RUN apk add gcompat libstdc++
then I could get the version and install Java:
> sdk version
SDKMAN!
script: 5.18.2
native: 0.4.2
> sdk install java 17.0.8-tem && sdk use java 17.0.8-tem
[...]
Using java version 17.0.8-tem in this shell.
But this fails:
java --version
Error occurred during initialization of VM
Unable to load jimage library: /home/my-user/.sdkman/candidates/java/17.0.8-tem/lib/libjimage.so
I could make it work manually by setting the LD_LIBRARY_PATH :
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$JAVA_HOME/lib/server
> java --version
openjdk 17.0.8 2023-07-18
[...]
I don't understand the missing path though and how to set it automatically.
Bug report
I am trying out sdkman in a (custom) container image based on alpine linux.
When I tried installing Java with sdkman, then trying to initialize those programs, I get
no such file or directory error
.Specifically, when running
java
orjava -version
or/root/.sdkman/candidates/java/current/bin/java
I get the error:Similar error for running
spring
for spring CLI (which I also installed through sdkman):when looking to see the file
root/.sdkman/candidates/java/current/bin/java
, I can see it does indeed exist and has execution permissions:To reproduce
The container image below:
Containerfile
filepodman build -t spring-temurin-maven-alpine -f Containerfile
podman run -dt spring-temurin-maven-alpine
podman attach -l
source $HOME/.sdkman/bin/sdkman-init.sh
java -version
to see the error I got.System info
Hope I can get help with this please; thanks!