以编程方式设置java.awt.headless=true

36

我正在尝试在应用程序启动时设置java.awt.headless=true,但似乎为时已晚,非无头模式已经启动:

static {
    System.setProperty("java.awt.headless", "true");
    /* java.awt.GraphicsEnvironment.isHeadless() returns false */
}

除了使用-Djava.awt.headless=true,还有其他设置headless为true的方法吗?我希望不需要在控制台上进行任何配置。


2
您可能也对http://en.wikipedia.org/wiki/Xvfb感兴趣。 - lexicore
5个回答

42

我在一个类的main()中使用Constants(和其他静态代码),用于静态加载JFreeChart的不同部分。

将静态加载块移到类的顶部解决了我的问题。

这种方法是不起作用的:

  public class Foo() {
    private static final Color COLOR_BACKGROUND = Color.WHITE;

    static { /* too late ! */
      System.setProperty("java.awt.headless", "true");
      System.out.println(java.awt.GraphicsEnvironment.isHeadless());
      /* ---> prints false */
    }

    public static void main() {}
  }

将静态块移到类的顶部,让Java尽早执行它!

  public class Foo() {
    static { /* works fine! ! */
      System.setProperty("java.awt.headless", "true");
      System.out.println(java.awt.GraphicsEnvironment.isHeadless());
      /* ---> prints true */
    }

    private static final Color COLOR_BACKGROUND = Color.WHITE;

    public static void main() {}
  }

仔细思考这个问题,就会变得非常清晰 :). 欣喜万分!


5
这里提供了一种完全不同的方法。
try {
    Field defaultHeadlessField = java.awt.GraphicsEnvironment.class.getDeclaredField("defaultHeadless");
    defaultHeadlessField.setAccessible(true);
    defaultHeadlessField.set(null,Boolean.FALSE);
    Field headlessField = java.awt.GraphicsEnvironment.class.getDeclaredField("headless");
    headlessField.setAccessible(true);
    headlessField.set(null,Boolean.TRUE);
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (NoSuchFieldException e) {
    e.printStackTrace();
}

我已成功地在无界面环境(Ubuntu)中使用它来绘制服务器端缓冲图像。这个好处是,它不需要在命令行上设置任何-D变量,也不需要设置DISPLAY变量。

你可以随时执行这段代码。你不需要担心在其他类加载之前调用它。

我想,如果你试图从无界面环境驱动一个远程机器上的Swing界面,这可能无法正常工作。


5
这应该可行,因为在创建工具包之前调用 System.setProperty。
public static void main(String[] args)
{
    // Set system property.
    // Call this BEFORE the toolkit has been initialized, that is,
    // before Toolkit.getDefaultToolkit() has been called.
    System.setProperty("java.awt.headless", "true");

    // This triggers creation of the toolkit.
    // Because java.awt.headless property is set to true, this 
    // will be an instance of headless toolkit.
    Toolkit tk = Toolkit.getDefaultToolkit();

    // Check whether the application is
    // running in headless mode.
    GraphicsEnvironment ge = 
        GraphicsEnvironment.getLocalGraphicsEnvironment();
    System.out.println("Headless mode: " + ge.isHeadless());
}

此时工具包似乎已经加载完毕,因此我无法再更改该属性。静态{}块应该在主块之前被调用。 - reto

3

我认为可以将此参数作为Java虚拟机的参数传递来设置,例如:

-Djava.awt.headless=true。不确定这是否会影响您的应用程序的其他组件。


2
除了使用“-Djava.awt.headless”之外,是否还有其他设置“headless=true”的方法?我不想在控制台上进行任何配置。 - reto

1
您可以像这样设置JAVA_TOOL_OPTIONS

JAVA_TOOL_OPTIONS: -Djava.awt.headless=true

然后在会话期间,任何新进程都将使用该设置。您可以将其添加到.bashrc.bash_profile(或任何其他shell的启动文件)中,以供所有后续会话使用。

您还可以将其添加到Groovy脚本的第一行,如下所示:

cat hello.groovy
#!/usr/bin/env groovy -Djava.awt.headless=true
println hello

问题是如何在应用程序内部进行设置。 - reto
1
不要对他进行投票否决,这可能对其他情况有用,就像我的一样。 - Danielr

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