web-dev-qa-db-ja.com

java.awt.AWTError:DISPLAY変数の値として「:0」を使用してX11ウィンドウサーバーに接続できません

私はUbuntuでJavaAWTベースのアプリケーションを実行しようとしていますVM Docker内)。アプリケーションは非常に単純なもので、Eclipseを介してWindows上で問題なく実行されます。ウィンドウを開いてhello world!を出力するだけです。実際、jarファイルをUbuntuにエクスポートするとVM Windows Hostは、jarファイルを“ Java -jar JFrameDocker.jar”で実行すると、Windowsと同じ出力を提供します。

ただし、Docker内で実行しようとすると、話は同じではありません。 Dockerfileで指定した命令はエラーなしで実行されますが、アプリケーションを実行すると“ Java.awt.AWTError: ':0'を使用してX11ウィンドウサーバーに接続できませんDISPLAY変数の値として」。私を信じてください、私はそれを解決するために何度も試みましたが、今まで運がありませんでした。 DISPLAY変数値を複数回設定するのと同じように、xtermとxeyesを使用してXサーバーを起動し、Webで見つけたすべての可能な記事を調べます。しかし、ここでは何も機能していないようです。私の問題をよりよく理解できるように、ここにすべてのファイルを提供しています。ちなみに this は、変更を加えた後でも同じエラーがスローされるため、私の質問には答えません。

これは私の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
2

Java:8ベースイメージを使用していますが、グラフィック環境を提供していない可能性があります。

手動でインストールされたubuntu:18.04およびxvfbパッケージでopenjdk-11-jdkベースイメージを使用できます。 xvfb-run コマンドは、仮想Xサーバー環境のセットアップを処理します。

xvfb-runはX権限ファイルを設定し(または既存のユーザー指定ファイルを使用し)、それにCookieを書き込みます(xauth(1x)を参照)次に、バックグラウンドプロセスとしてXvfbXサーバーを起動します。 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
1
Karol Dowbecki