我正在尝试让一个在我的机器上完美运行的应用程序在 docker 上运行,这是我的 docker 文件:
FROM openjdk:11-jre-slim
VOLUME /tmp
ADD someJar.jar someJar.jar
ADD lib lib
ADD config.properties config.properties
ENTRYPOINT ["java", "-javaagent:lib/aspectjweaver-1.9.2.jar",
"-javaagent:lib/spring-instrument-5.1.6.RELEASE.jar", "--module-path",
"lib/javafx-sdk-11.0.2", "--add-modules=javafx.controls", "-
Dprism.verbose=true", "-jar","someJar.jar"]
我还尝试将其基于 alpine openjdk11 版本,得到相同的结果:
FROM adoptopenjdk/openjdk11:alpine
VOLUME /tmp
RUN apk update && apk add libx11 mesa-gl gtk+3.0 && apk update
ADD someJar.jar someJar.jar
ADD lib lib
ADD config.properties config.properties
ENTRYPOINT ["java", "-javaagent:lib/aspectjweaver-1.9.2.jar", "-javaagent:lib/spring-instrument-5.1.6.RELEASE.jar", "--module-path", "lib", "--add-modules=javafx.controls", "-Dprism.verbose=true", "-jar","someJar.jar"]
lib 文件夹包含 openJFX 运行时的 Linux 版本(.so 文件和 .jar 文件)。我正在一台 Windows 机器上使用 openJDK 运行时的 Windows 等效版本来开发它,它运行得很好。运行容器时,我得到以下输出:
Prism pipeline init order: es2 sw
Using Double Precision Marlin Rasterizer
Using dirty region optimizations
Not using texture mask for primitives
Not forcing power of 2 sizes for textures
Using hardware CLAMP_TO_ZERO mode
Opting in for HiDPI pixel scaling
Prism pipeline name = com.sun.prism.es2.ES2Pipeline
Loading ES2 native library ... prism_es2
GraphicsPipeline.createPipeline failed for com.sun.prism.es2.ES2Pipeline
java.lang.UnsatisfiedLinkError: no prism_es2 in java.library.path: [/usr/java/packages/lib, /usr/lib/x86_64-linux-gnu/jni, /lib/x86_64-linux-gnu, /usr/lib/x86_64-linux-gnu, /usr/lib/jni, /lib, /usr/lib]
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2660)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:829)
at java.base/java.lang.System.loadLibrary(System.java:1867)
at javafx.graphics/com.sun.glass.utils.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:150)
at javafx.graphics/com.sun.glass.utils.NativeLibLoader.loadLibrary(NativeLibLoader.java:52)
at javafx.graphics/com.sun.prism.es2.ES2Pipeline.lambda$static$0(ES2Pipeline.java:68)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.prism.es2.ES2Pipeline.<clinit>(ES2Pipeline.java:50)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:315)
at javafx.graphics/com.sun.prism.GraphicsPipeline.createPipeline(GraphicsPipeline.java:187)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:91)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
at java.base/java.lang.Thread.run(Thread.java:834)
*** Fallback to Prism SW pipeline
Prism pipeline name = com.sun.prism.sw.SWPipeline
(X) Got class = class com.sun.prism.sw.SWPipeline
Initialized prism pipeline: com.sun.prism.sw.SWPipeline
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:47)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:86)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: java.lang.UnsupportedOperationException: Unable to open DISPLAY
at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$new$6(GtkApplication.java:173)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.<init>(GtkApplication.java:171)
at javafx.graphics/com.sun.glass.ui.gtk.GtkPlatformFactory.createApplication(GtkPlatformFactory.java:41)
at javafx.graphics/com.sun.glass.ui.Application.run(Application.java:144)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.startup(QuantumToolkit.java:258)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:269)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:834)
知道如何让基于 OpenJFX11 的 Java 应用程序在 Docker 中工作吗?
******更新******
我在这方面取得了一些进展。我发现将 openJFX 运行时文件直接放在 lib 文件夹中可以使其进步更多。新的错误变成了这样:
ImportError: libGL.so.1: cannot open shared object file: No such file or directory
经过一番研究后,我在 dockerfile 中添加了以下 RUN 命令:
RUN apt-get update && apt-get install libgl1-mesa-glx -y
这给了我一个新的堆栈跟踪:
Prism pipeline init order: es2 sw
Using Double Precision Marlin Rasterizer
Using dirty region optimizations
Not using texture mask for primitives
Not forcing power of 2 sizes for textures
Using hardware CLAMP_TO_ZERO mode
Opting in for HiDPI pixel scaling
Prism pipeline name = com.sun.prism.es2.ES2Pipeline
Loading ES2 native library ... prism_es2
succeeded.
GLFactory using com.sun.prism.es2.X11GLFactory
(X) Got class = class com.sun.prism.es2.ES2Pipeline
GraphicsPipeline.createPipeline: error initializing pipeline
com.sun.prism.es2.ES2Pipeline
*** Fallback to Prism SW pipeline
Prism pipeline name = com.sun.prism.sw.SWPipeline
(X) Got class = class com.sun.prism.sw.SWPipeline
Initialized prism pipeline: com.sun.prism.sw.SWPipeline
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:47)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:86)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: java.lang.UnsupportedOperationException: Unable to open DISPLAY
at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$new$6(GtkApplication.java:173)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.<init>(GtkApplication.java:171)
at javafx.graphics/com.sun.glass.ui.gtk.GtkPlatformFactory.createApplication(GtkPlatformFactory.java:41)
at javafx.graphics/com.sun.glass.ui.Application.run(Application.java:144)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.startup(QuantumToolkit.java:258)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:269)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:834)
******另一个更新******
仔细研究 GtkApplication.class 文件中的 JavaFX 代码,这是失败的部分:
int libraryToLoad = _queryLibrary(gtkVersion, gtkVersionVerbose);
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
if (libraryToLoad == QUERY_NO_DISPLAY) {
throw new UnsupportedOperationException("Unable to open DISPLAY");
} else if (libraryToLoad == QUERY_USE_CURRENT) {
if (gtkVersionVerbose) {
System.out.println("Glass GTK library to load is already loaded");
}
} else if (libraryToLoad == QUERY_LOAD_GTK2) {
if (gtkVersionVerbose) {
System.out.println("Glass GTK library to load is glassgtk2");
}
NativeLibLoader.loadLibrary("glassgtk2");
} else if (libraryToLoad == QUERY_LOAD_GTK3) {
if (gtkVersionVerbose) {
System.out.println("Glass GTK library to load is glassgtk3");
}
NativeLibLoader.loadLibrary("glassgtk3");
} else {
throw new UnsupportedOperationException("Internal Error");
}
return null;
});
我是否缺少图书馆之类的东西?
... 帮助?
Thanks