Truly headless AWT operation on MacOS X

I’ve been trying to debug some Java code called from within a BIRT web service on MacOS X. But the requests would hang as the BIRT report viewer would attempt to query the system’s printers with javax.print.PrintServiceLookup, which in turn loaded AWT and then hangs calling out to apple.awt.CToolkit#runningInHiDPI(), a native method on Apple’s native Toolkit implementation.

Unfortunately specifying the property java.awt.headless=true wasn’t quite sufficient: this setting still results in Apple’s CToolkit being loaded (in java.awt.Toolkit#getDefaultToolkit()), but it would then be wrapped in a HeadlessToolkit. So my process would still hang.

After poking around a bit further, I discovered that the JRE includes a different headless toolkit implementation called sun.awt.HToolkit. This headless toolkit can be configured using the awt.toolkit property as follows:

-Djava.awt.headless=true
-Dawt.toolkit=sun.awt.HToolkit

With these settings, my debugging is now hang free. I’m not sure why this toolkit implementation is not used on java.awt.headless=true.

Advertisements

Share this:

Related

Responses

A big thank you to you.
I happend to read your post a couple of days ago and thought I would never need this.
And today I was testing some report generation using Jasper report generation engine and freeze….
Then I found again your post and tried right away your 2 magic system properties, and everything was fine.
You saved my day (a probably more).

I would like to ask if you have any insight for what I believe is precisely the opposite problem. I have a legacy app built on AWT/Swing that we retrofitted as an Eclipse RCP headless application. It uses absolutely zero SWT; launches and runs beautifully on Winders and Linux as an Eclipse app. Launch attempts on MacOS yield the splash screen, then hang as soon as the first AWT reference is attempted. Have you wrestled with this one? Thanks.

Yes I am using the -XstartOnFirstThread VM argument. But I hadn’t thought carefully about the splash screen. From googling wildly I believe the trouble occurs when the Eclipse RCP launcher attempts to run both SWT *and* AWT. Since my app does not run SWT I foolishly thought that no SWT was being used. I will try nosplash.

By: Chris Lott on October 21, 2011 at 6:31 am

Ok I modified the Eclipse application launch configuration, Arguments tab, to add “-noSplash” first in the list of Program Arguments (in addition to -os, -arch etc). Then the splash screen did not appear and wonder of wonders, my app opened!!! So kudos to SeB.fr for suggesting -noSplash.

However, the app does not function – it does not respond to mouse clicks, nothing, and the spinny icon appears after the first attempt. I also see errors in the Eclipse console, this is the text that occurs repeatedly:

Thanks for the suggestion, but none of those are in the dependency list. The app makes zero references to SWT.

The FAQ at the link you posted mentions that the code must use java.awt.EventQueue.invokeLater(). I rather suspect that is not done cleanly and properly in our app, but that will take some time to investigate.

Saw the comment but have utterly failed to implement it. I removed -XstartOnFirstThread and added –launcher.secondThread (note double dash) in various places but in my Eclipse Indigo release, the launcher does not seem to take that argument. Instead the argument is passed to my application (which chokes on it, but that’s another matter). Contrast with the launcher’s behavior for the “-noSplash” argument, that apparently is eaten by the launcher (I guess), certainly it is NOT passed to my app. Perhaps modern Eclipse no longer understands that –launcher option?