35

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.

Kasun Siyambalapitiya
  • 3,956
  • 8
  • 38
  • 58
reto
  • 16,189
  • 7
  • 53
  • 67

5 Answers5

41

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!

Gray
  • 115,027
  • 24
  • 293
  • 354
reto
  • 16,189
  • 7
  • 53
  • 67
5

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());
}
pitpod
  • 389
  • 1
  • 3
  • At that point the toolkit appears to alreay loaded, so I can't change that property anymore. the static {} block should be called even before the main block. – reto Mar 31 '10 at 11:24
5

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.

javac
  • 2,431
  • 4
  • 17
  • 26
Carl Sayres
  • 51
  • 1
  • 1
3

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.

  • 1
    "Is there another way set headless=true beside -Djava.awt.headless? I would prefer to not configure anything on the console." – reto Jan 12 '11 at 18:56
1

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
Sampada
  • 2,931
  • 7
  • 27
  • 39
Mike Kinney
  • 87
  • 1
  • 3