Ubuntu客户端通过SSH运行无头服务器上的Swing GUI问题排查
问题描述
我在Ubuntu 20.04无头服务器上测试带Swing GUI的Java程序,开发机(同样是Ubuntu 20.04)把程序打包成Jar后通过SSH传到服务器,想在开发机上显示并交互这个GUI。尝试设置export DISPLAY=:0.0但无效,出现以下错误:
设置DISPLAY前的错误
Exception in thread "AWT-EventQueue-0" java.awt.HeadlessException: No X11 DISPLAY variable was set, but this program performed an operation which requires it. at java.desktop/java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:208) at java.desktop/java.awt.Window.<init>(Window.java:548) at java.desktop/java.awt.Frame.<init>(Frame.java:423) at java.desktop/java.awt.Frame.<init>(Frame.java:388) at java.desktop/javax.swing.JFrame.<init>(JFrame.java:180) at com.mochilafulfillment.agv.gui.RemoteGui.<init>(RemoteGui.java:21) at com.mochilafulfillment.agv.modes.RemoteControlMode$1.run(RemoteControlMode.java:30) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
设置DISPLAY后的错误
java.awt.AWTError: Cant connect to X11 window server using '0.0' as the value of the DISPLAY variable. at java.desktop/sun.awt.X11GraphicsEnvironment.initDisplay(Native Method) at java.desktop/sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:102) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.desktop/sun.awt.X11GraphicsEnvironment.<clinit>(X11GraphicsEnvironment.java:61) at java.base/java.lang.Class.forName0(Native Method) at java.base/java.lang.Class.forName(Class.java:315) at java.desktop/java.awt.GraphicsEnvironment$LocalGE.createGE(GraphicsEnvironment.java:101) at java.desktop/java.awt.GraphicsEnvironment$LocalGE.<clinit>(GraphicsEnvironment.java:83) at java.desktop/java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:129) at java.desktop/sun.awt.X11.XToolkit.<clinit>(XToolkit.java:232) at java.base/java.lang.Class.forName0(Native Method) at java.base/java.lang.Class.forName(Class.java:315) at java.desktop/java.awt.Toolkit$2.run(Toolkit.java:588) at java.desktop/java.awt.Toolkit$2.run(Toolkit.java:583) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.desktop/java.awt.Toolkit.getDefaultToolkit(Toolkit.java:582) at java.desktop/java.awt.Toolkit.getEventQueue(Toolkit.java:1498) at java.desktop/java.awt.EventQueue.invokeLater(EventQueue.java:1312) at java.desktop/javax.swing.SwingUtilities.invokeLater(SwingUtilities.java:1421) at com.mochilafulfillment.agv.modes.RemoteControlMode.run(RemoteControlMode.java:27) at com.mochilafulfillment.agv.Agv.run(Agv.java:53) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829)
解决方案
问题出在你设置的DISPLAY指向了服务器本地的X11服务,但服务器是无头的,根本没有本地显示。正确做法是让服务器把GUI输出转发到你的开发机X11服务上,步骤如下:
开发机开启X11转发权限
编辑开发机的SSH配置文件(/etc/ssh/ssh_config或~/.ssh/config),添加或修改以下内容:ForwardX11 yes ForwardX11Trusted yes保存后重启SSH服务:
sudo systemctl restart ssh用X11转发模式连接服务器
从开发机SSH连接服务器时,加上-Y参数(信任X11转发,适合本地开发场景):ssh -Y username@server_ip连接成功后,服务器会自动设置正确的
DISPLAY环境变量,可通过以下命令验证:echo $DISPLAY正常输出应该是类似
localhost:10.0的格式,而非:0.0。确保服务器安装X11依赖
无头服务器默认可能缺少X11相关库,安装Java GUI所需依赖:sudo apt update && sudo apt install libx11-6 libxext6 libxrender1 libxtst6 libxi6运行Jar包
直接在SSH会话中运行Jar包即可,无需手动设置DISPLAY:java -jar your_program.jar此时开发机上会弹出Swing界面,可正常交互。
若仍有问题,可尝试:
- 关闭开发机防火墙,或允许X11相关端口(通常是6000+DISPLAY数字,比如DISPLAY为:10则开放6010)
- 确认开发机的X11服务正在运行(Ubuntu桌面版默认运行,远程桌面需额外确认状态)
内容的提问来源于stack exchange,提问作者jlaufer
相关产品推荐
相关产品推荐

