Question

I'm trying to set java.awt.headless=true during the application startup but it appears like I'm too late and the non-headless mode has already started:

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

Is there another way set headless to true beside -Djava.awt.headless=true? I would prefer not configure anything on the console.

Was it helpful?

Solution

I was working with a main() in a class which statically loads different parts of JFreeChart in Constants (and other static code).

Moving the static loading block to the top of the class solved my problem.

This doesn't work:

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

Have java execute the static block as early as possible by moving it to the top of the class!

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

When thinking about it this makes perfectly sense :). Juhu!

OTHER TIPS

This should work because the call to System.setProperty is before the creation of the toolkit:

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

I think this parameter can be set by passing it as an argument to Java Virtual Machine e.g.

-Djava.awt.headless=true. Not sure if this would have impact on other components of your application.

Here is a completely different approach.

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

I am using this successfully to draw on server-side BufferedImages in a headless environment (Ubuntu). The nice thing about this is that it does not require setting any -D variables on the command line, nor do you need to set the DISPLAY variable.

You can also execute this code at any time. You don't need to worry about invoking this before other classes are loaded.

I suppose this might not work if you were trying to drive a Swing interface on a remote machine from a headless environment.

You can set the JAVA_TOOL_OPTIONS like this:

JAVA_TOOL_OPTIONS: -Djava.awt.headless=true

Then any new processes will use that setting during the session. You can add it to your .bashrc or .bash_profile (or whatever shell's startup file) for all subsequent sessions.

You can also add it to the first line of a groovy script like this:

cat hello.groovy
#!/usr/bin/env groovy -Djava.awt.headless=true
println hello
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top