I have been trying to run a Java AWT based application on an Ubuntu VM inside Docker. The application is a very simple one and it flawlessly runs on Windows through Eclipse. It simply opens up a window and prints hello world!. In fact when I export the jar file in to an Ubuntu VM that is running on my Windows host also gives me the same output as Windows when I run the jar file through “java -jar JFrameDocker.jar”.
However the story is not same when I try to run it inside docker. The instructions that I have specified in the Dockerfile executes without any error but when I run the application it throws “java.awt.AWTError: Can't connect to X11 window server using ':0' as the value of the DISPLAY variable” . Trust me guys, I have tried many a times to resolve it but no luck till now. Like setting the DISPLAY variable value multiple times, starting X server using xterm and xeyes, going through every possible article that I found on the Web. But nothing seems to be working here. I am providing all my files here that could get you a better understanding of my problem. By the way this doesn't answer my question as same error is being thrown even after making the changes.
This is my java file.
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);
}
}
This is my Dockerfile:
FROM java:8
ENV DISPLAY :0
ADD JFrameDocker.jar JFrameDocker.jar
CMD ["java","-jar", "JFrameDocker.jar"]
I have used below docker commands to build image and run it.
Docker Build : sudo docker build -t jframedocker .
Docker Run : sudo docker run jframedocker
Output Without Error Screenshot: (Without Docker)
Output with 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
You are using java:8
base image which most likely doesn't provide a graphical environment.
You can use ubuntu:18.04
base image with manually installed openjdk-11-jdk
and xvfb
packages. The xvfb-run
command will take care of setting up the virtual X Server environment:
xvfb-run sets up an X authority file (or uses an existing user-specified one), writes a cookie to it (see xauth(1x)) and then starts the Xvfb X server as a background process. The process ID of Xvfb is stored for later use. The specified command is then run using the X display corresponding to the Xvfb server just started and the X authority file created earlier.
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