如何从远程ssh终端在Mac上运行java UI应用程序?

时间:2014-11-27 12:41:58

标签: java macos

在Mac上,您可以通过ssh连接并运行应用程序而无需任何DISPLAY设置,例如open .将在远程终端的mac屏幕上运行Finder。

这对java应用程序不起作用:

java -jar demo/jfc/Font2DTest/Font2DTest.jar 

将抛出:

Exception in thread "main" java.awt.HeadlessException
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:207)
at java.awt.Window.<init>(Window.java:536)
at java.awt.Frame.<init>(Frame.java:420)
at javax.swing.JFrame.<init>(JFrame.java:225)
at Font2DTest.main(Font2DTest.java:1032)

任何使用DISPLAY值的实验都无济于事。

1 个答案:

答案 0 :(得分:3)

在JDK8中,您可以使用AWT_FORCE_HEADFUL env变量来克服这个问题:

AWT_FORCE_HEADFUL=true java -jar demo/jfc/Font2DTest/Font2DTest.jar 

不幸的是,在JDK7中没有简单的方法。

问题隐藏在mac无头模式检测中。下一个代码检查应用程序是否在“Aqua”会话中,否则强制无头。

// jdk/src/solaris/native/java/lang/java_props_macosx.c
int isInAquaSession() {
  // environment variable to bypass the aqua session check
  char *ev = getenv("AWT_FORCE_HEADFUL");
  if (ev && (strncasecmp(ev, "true", 4) == 0)) {
    // if "true" then tell the caller we're in an Aqua session without actually checking
    return 1;
  }
  // Is the WindowServer available?
  SecuritySessionId session_id;
  SessionAttributeBits session_info;
  OSStatus status = SessionGetInfo(callerSecuritySession, &session_id, &session_info);
  if (status == noErr) {
    if (session_info & sessionHasGraphicAccess) {
        return 1;
    }
  }
  return 0; 
}

// jdk/src/solaris/native/java/lang/java_props_md.c

// check if we're in a GUI login session and set java.awt.headless=true if not
sprops.awt_headless = isInAquaSession() ? NULL : "true";