tags:

views:

593

answers:

3

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

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

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

Thanks!

Reto

A: 

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
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
+1  A: 

I think I found it!

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

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

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

  }

Let 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!

reto
This solution is fragile.
Stephen C
I think it is not, I like your decoupuling solution, but as long as you put your static block first (and you dont have a base class which triggers anything) you should be fine. The simple 'import' doesnt trigger any static blocks in the respecitve clases, ive tried that.
reto
+1  A: 

@reto and @pitpod have found (essentially) the same solution. Sad to say, it is rather fragile.

The problem is that that the class containing the main method could depend on other application classes. If any of those classes refer to AWT or SWT classes, this dependency could cause the JVM to initialize the graphics environment before executing the statics of the main class.

Here is an alternative. It is a bit cumbersome, but this approach should avoid triggering early graphics init:

public class HeadlessMain {
   static {
      System.setProperty("java.awt.headless", "true");
      Toolkit tk = Toolkit.getDefaultToolkit();
   }

   public static void main(String[] args) {
       // Dynamically loading avoids early triggering of class init.
       Class<?> cls = Class.forName("some.package.RealMain");
       // Use reflection to get the "static void main(String[])" method from cls.
       // Use reflection to invoke the method passing our args parameter.
   }
}
Stephen C
why do you use Class.forName? A simple import doesnt trigger anything, and the static {} block should get called before the main block is being called.
reto