为什么可以在Docker映像中手动运行Java程序,但不能作为ENTRYPOINT运行

时间:2018-08-12 19:03:00

标签: docker alpine java-11

我创建了一个openjdk-11高山docker映像并将其jar复制到其中。我的Dockerfile是这样的:

FROM pwittchen/alpine-java11
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} /opt/app.jar
ENTRYPOINT ["java", "-jar", "/opt/app.jar"]

如果我跑步:

docker run -it image

然后

Error loading shared library libjli.so: No such file or directory (needed by /usr/local/share/jdk-11/bin/java)
Error relocating /usr/local/share/jdk-11/bin/java: JLI_Launch: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_PreprocessArg: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_ReportMessage: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_StringDup: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_MemFree: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_InitArgProcessing: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_AddArgsFromEnvVar: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_List_add: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_List_new: symbol not found

但是如果:

docker run -it --entrypoint /bin/sh image

然后我可以直接在shell中执行

$ java -jar /opt/app.jar

工作。

为什么以ENTRYPOINT身份运行会使libjli.so库消失并尝试重新定位JLI *?

1 个答案:

答案 0 :(得分:2)

问题出在肌肉方面。当您直接从外壳执行时,musl可以读取库路径,但是当您使用CMD和/或ENTRYPOINT执行时,musl无法解析库路径。

阅读并发现旧问题已经在openjdk8-alpine中解决后,我能够找到它。那是回归。

https://github.com/docker-library/openjdk/issues/77

要解决此问题,请首先创建一个文件 ld-musl-x86_64.pat ,指定musl所需的库在哪里。文件内容如下:

/lib
/usr/lib
/usr/local/lib
/usr/local/share/jdk-11/lib/jli

在构建阶段将文件复制到Docker映像。我的新Dockerfile如下所示:

FROM pwittchen/alpine-java11
VOLUME /tmp
ARG JAR_FILE
#Copy the configuration file with the Library path!
COPY ld-musl-x86_64.path /etc/ld-musl-x86_64.pat
COPY ${JAR_FILE} /opt/app.jar
ENTRYPOINT ["java", "-jar", "/opt/app.jar"]

最后工作。