【问题标题】:Setting java.awt.headless=true programmatically以编程方式设置 java.awt.headless=true
【发布时间】:2019-12-19 19:49:16
【问题描述】:

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

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

除了-Djava.awt.headless=true,还有其他方法将 headless 设置为 true 吗?我宁愿不在控制台上配置任何东西。

【问题讨论】:

标签: java awt headless


【解决方案1】:

我在一个类中使用main(),该类在常量(和其他静态代码)中静态加载 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() {}
  }

仔细想想,这完全有道理:)。巨呼!

【讨论】:

  • 这很奇怪。对我有用的是明确将java.awt.headless 设置为false
  • 在静态初始化块中将属性设置为"true" 工作得很好。 @kumetix 也许你试过 true 而不是 "true"
【解决方案2】:

这应该可行,因为对 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());
}

【讨论】:

  • 此时工具包似乎已经加载,因此我无法再更改该属性。静态 {} 块应在主块之前调用。
【解决方案3】:

这是一种完全不同的方法。

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)中绘制服务器端 BufferedImages。 这样做的好处是它不需要在命令行上设置任何 -D 变量,也不需要设置 DISPLAY 变量。

您也可以随时执行此代码。您无需担心在加载其他类之前调用​​它。

如果您尝试从无头环境驱动远程机器上的 Swing 接口,我想这可能不起作用。

【讨论】:

    【解决方案4】:

    我认为可以通过将其作为参数传递给 Java 虚拟机来设置此参数,例如

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

    【讨论】:

    • “除了 -Djava.awt.headless 之外还有其他方法设置 headless=true 吗?我宁愿不在控制台上配置任何东西。”
    【解决方案5】:

    您可以像这样设置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
    

    【讨论】:

    • 问题是如何在应用程序内设置它。
    • 不要对他投反对票,这可能对我的其他情况有用。
    猜你喜欢
    • 1970-01-01
    • 2021-11-21
    • 2018-11-26
    • 2011-04-18
    • 2012-07-18
    • 2016-02-15
    • 2014-07-26
    • 1970-01-01
    • 2011-06-06
    相关资源
    最近更新 更多