Setting java.awt.headless=true programmatically
Asked Answered
C

5

36

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.

Cotto answered 31/3, 2010 at 11:17 Comment(1)
You may also be interested in en.wikipedia.org/wiki/Xvfb.Tanaka
C
42

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!

Cotto answered 31/3, 2010 at 11:32 Comment(0)
S
6

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());
}
Sled answered 31/3, 2010 at 11:22 Comment(1)
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.Cotto
V
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.

Verbalize answered 16/8, 2011 at 0:43 Comment(0)
D
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.

Dam answered 12/1, 2011 at 9:56 Comment(1)
"Is there another way set headless=true beside -Djava.awt.headless? I would prefer to not configure anything on the console."Cotto
T
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
Tyrus answered 13/12, 2015 at 7:13 Comment(2)
The question was how to set it from WITHIN the application.Cotto
Don't downvote him, it might be useful to other case, as mine.Gentility

© 2022 - 2024 — McMap. All rights reserved.