如何在通过SSH连接后在Mac OSX上运行Java GUI

4

我正在使用 Mac OS X 10.7.5 上的 Java 1.7.0_67。以下是我的“Hello World” GUI:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class helloWorld extends JFrame {
    helloWorld(String title) { 
        this.setSize(500,500); 
        setTitle(title); 
    }

    public static void main(String[] args) {
       helloWorld window = new helloWorld("Helloworld");
       window.setVisible(true);
       window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    }
}

当我在 Mac 终端中打开并输入 java helloWorld 时,程序可以正常运行。然而,当我从另一台主机 ssh 连接到我的 Mac,并设置了 DISPLAY 环境变量并运行程序时,出现以下异常:

Exception in thread "main" java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
    at java.awt.GraphicsEnvironment.checkedHeadless(GraphicsEnvironment.java:207)
    at java.awt.Window.<init>(Window.java:535)
    at java.awt.Frame.<init>(Frame.java:420)
    at java.awt.Frame.<init>(Frame.java:385)
    at javax.swing.JFrame.<init>(JFrame.java:180)
    at helloWorld.<init>(helloWorld.java:8)
    at helloWorld.main(helloWorld.java:14)

据我所查,这个问题好像是故意制造的,因为在Java 1.6版本中仍能正常工作。

有没有什么办法可以让远程主机通过ssh登录后显示GUI界面而不使用X11(希望使用本地的GUI渲染)?


使用 ssh -X 命令在 ssh 下启用 X11 协议隧道传输。 - Jean-Baptiste Yunès
可能是["No X11 DISPLAY variable" - what does it mean?]的重复问题。(https://dev59.com/WXRB5IYBdhLWcg3wUFvB) - StackFlowed
谢谢 - 我已经看过那个了,但那是关于在Linux系统上显示,而不是在Mac OS X上 - 就此而言,我甚至不知道为什么错误会提及X11,因为我并没有使用X11和本地显示GUI。 - gnr
@Jean-BaptisteYunès 不幸的是,这不起作用 - 这里我直接使用Mac OS来显示GUI,而不是X11。 - gnr
那么你应该为你的 Mac 安装 X11,没错!http://xquartz.macosforge.org/trac - Jean-Baptiste Yunès
显示剩余2条评论
2个回答

3

当在Mac OS X上运行ssh会话时,Java开发人员选择使用无头工具包。您可以通过设置AWT_TOOLKIT环境变量为CToolkit来说服Java继续显示GUI。例如,在bash中:

export AWT_TOOLKIT=CToolkit
java helloWorld

使用设置好的变量,您的GUI应该按照您的期望显示。

@duskwuff - 这个对我有用,想知道你对这个解决方案有什么看法。 - gnr
即使我有多个用户登录了一个带有多个桌面的 Mac,这个甚至也能正常工作:看起来它是根据用户 ID 进行选择,这是有道理的。 - android.weasel
虽然有趣的是,它在我的MBP上无法工作 - 只能在我们作为构建代理的Mac Minis上工作。也许这是因为我本地有(过)一个Quartz会话?我可以轻松地“打开/Applications/Sikuli.app”并在Dock上看到一个图标,所以登录会话以某种方式进行通信。 - android.weasel
Java 1.8.0_45 在 MBP 上,1.7.0_71 在 Mac mini 上也可能是一个因素。 - android.weasel
好的 - 我已将1.7版本复制到我的MBP并设置了JAVA_HOME。与AWT_TOOLKIT结合使用,它可以在Mac桌面上从ssh上愉快地启动。 - android.weasel
显示剩余2条评论

0

不行。要连接到 Mac OS X 上的窗口服务器,进程必须在当前用户的登录会话中。SSH 不是登录会话的一部分,因此通过 SSH 运行的进程无法连接到窗口服务器,因此无法显示 GUI。


真的吗?我可以在Mac OSX 10.7.3和Java 1.6.0_29上做到这一点,版本之间有什么变化吗?无论如何,我能以任何方式伪造这个(例如设置环境变量,更改某些配置文件等)吗? - gnr
1
我不知道为什么这在之前的Mac OS X版本上可能有效。而且,没有办法覆盖这种行为。 - user149341
1
我可以在ssh shell中打开“some.jpg”,它会出现在我的桌面上,“open some.sh”将在终端窗口中执行“some.sh; exit”,并定义所有桌面环境变量,如果我使用-W选项,它将等待应用程序退出(尽管令人恼火的是,它不会传递--args后面的参数),因此这个答案并不完全正确。(虽然我以管理员身份运行) - android.weasel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接