繁体   English   中英

java.awt.AWTError:无法使用“:0”作为DISPLAY变量的值连接到X11窗口服务器

[英]java.awt.AWTError: Can't connect to X11 window server using ':0' as the value of the DISPLAY variable

我一直试图在Docker内部的Ubuntu VM上运行基于Java AWT的应用程序 该应用程序非常简单,可以通过Eclipse在Windows上完美运行。 它只是打开一个窗口并打印您好世界!。 实际上,当我将jar文件导出到在Windows主机上运行的Ubuntu VM时,通过“ java -jar JFrameDocker.jar”运行jar文件时,也会提供与Windows相同的输出。

但是,当我尝试在docker中运行时,故事并不相同。 我在Dockerfile中指定的指令执行没有任何错误,但是当我运行应用程序时,它抛出“ java.awt.AWTError:无法使用':0'作为DISPLAY变量的值连接到X11窗口服务器” 相信我,我已经尝试过很多次了,但是到目前为止还没有运气。 就像多次设置DISPLAY变量值一样,使用xterm和xeyes启动X服务器,仔细阅读我在Web上找到的所有文章。 但似乎没有任何工作在这里。 我在这里提供所有文件,可以使您更好地了解我的问题。 顺便说一句, 不能回答我的问题,因为即使进行更改后也会抛出相同的错误。

这是我的java文件。

package com.etp;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class JFrameDockerTest {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        JLabel lable = new JLabel("Hello World");
        panel.setLayout( new FlowLayout() );  
        frame.add(panel);
        panel.add(lable);
        frame.setVisible(true);
        frame.setSize(800, 600);
    }

}

这是我的Dockerfile:

FROM java:8
ENV DISPLAY :0
ADD JFrameDocker.jar JFrameDocker.jar
CMD ["java","-jar", "JFrameDocker.jar"]

我已经使用了以下docker命令来构建映像并运行它。

Docker构建: sudo docker build -t jframedocker .

Docker Run: sudo docker run jframedocker

输出无错误截图:(无Docker)

Docker的输出:

etp@etp-VirtualBox:~/Downloads/JFrameDocker$ sudo docker run jframedocker
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.awt.AWTError: Can't connect to X11 window server using ':0' as the value of the DISPLAY variable.
    at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
    at sun.awt.X11GraphicsEnvironment.access$200(X11GraphicsEnvironment.java:65)
    at sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:115)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.awt.X11GraphicsEnvironment.<clinit>(X11GraphicsEnvironment.java:74)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at java.awt.GraphicsEnvironment.createGE(GraphicsEnvironment.java:103)
    at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:82)
    at java.awt.Window.initGC(Window.java:475)
    at java.awt.Window.init(Window.java:495)
    at java.awt.Window.<init>(Window.java:537)
    at java.awt.Frame.<init>(Frame.java:420)
    at java.awt.Frame.<init>(Frame.java:385)
    at javax.swing.JFrame.<init>(JFrame.java:189)
    at com.etp.JFrameDockerTest.main(JFrameDockerTest.java:12)
    ... 5 more

您正在使用java:8基本图像,该图像很可能没有提供图形化环境。

您可以将ubuntu:18.04基本映像与手动安装的openjdk-11-jdkxvfb软件包一起使用。 xvfb-run命令将负责设置虚拟X Server环境:

xvfb运行会设置一个X授权文件(或使用现有的用户指定文件),向其中写入一个cookie(请参阅xauth(1x)),然后将Xvfb X服务器作为后台进程启动。 Xvfb的进程ID被存储以供以后使用。 然后,使用与刚启动的Xvfb服务器相对应的X显示器以及之前创建的X授权文件运行指定的命令。

Dockerfile

FROM ubuntu:18.04
RUN apt-get update -y && apt-get upgrade -y && apt-get install -y openjdk-11-jdk xvfb 
ADD JFrameDocker.java MANIFEST.mf ./
RUN javac JFrameDocker.java
RUN jar cfm JFrameDocker.jar MANIFEST.mf JFrameDocker.class 
RUN xvfb-run java -jar JFrameDocker.jar

JFrameDocker.java

import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class JFrameDocker {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        JLabel lable = new JLabel("Hello World");
        panel.setLayout(new FlowLayout());  
        frame.add(panel);
        panel.add(lable);
        frame.setSize(800, 600);
        frame.setVisible(true);
        System.out.println("Up and running");
    }

}

MANIFEST.MF

Manifest-Version: 1.0
Main-Class: JFrameDocker

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM