Установка java.awt.headless = true программно

Я пытаюсь установить java.awt.headless=true во время запуска приложения, но он появляется, как будто я слишком поздно, и режим без головок уже запущен:

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

Есть ли другой способ установить без головы на true рядом с -Djava.awt.headless=true? Я бы предпочел ничего не настраивать на консоли.

Ответ 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() {}
  }

Когда об этом думаешь, это имеет смысл:). Juhu!

Ответ 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

Я думаю, что этот параметр можно установить, передав его как аргумент виртуальной машине Java, например.

-Djava.awt.headless=true. Не уверен, повлияет ли это на другие компоненты вашего приложения.

Ответ 4

Вот совершенно другой подход.

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();
}

Я использую это успешно, чтобы использовать BufferedImages на стороне сервера в безголовой среде (Ubuntu). Самое приятное в этом состоит в том, что не требуется устанавливать какие-либо переменные -D в командной строке, и вам не нужно устанавливать переменную DISPLAY.

Вы также можете выполнить этот код в любое время. Вам не нужно беспокоиться об этом, прежде чем загружать другие классы.

Я предполагаю, что это может не сработать, если вы пытаетесь управлять интерфейсом Swing на удаленной машине из безголовой среды.

Ответ 5

Вы можете установить JAVA_TOOL_OPTIONS следующим образом:

JAVA_TOOL_OPTIONS: -Djava.awt.headless = true

Затем любые новые процессы будут использовать этот параметр во время сеанса. Вы можете добавить его в свой .bashrc или .bash_profile (или любой файл запуска оболочки) для всех последующих сеансов.

Вы также можете добавить его в первую строку groovy script следующим образом:

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