Posted by: Brian de Alwis | October 13, 2011

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

Responses

  1. 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).

    So thanks again.
    SeB.

  2. 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.

    • My case was happening from within a webapp, and SWT was not involved in any form. I’m still baffled as to the cause of the problem.

      Where is your launch screen coming from? The Eclipse launch screen is done through SWT. Does running with ‘-noSplash’ make any difference?

    • have you tried the system property
      -XstartOnFirstThread
      to for the vm to launch the main thread on first thread.

      • 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.

  3. 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:

    *** -[NSConditionLock unlock]: lock ( ‘(null)’) unlocked when not locked
    *** Break on _NSLockError() to debug.

    Actually it’s not quite the same messages; the hex number changes in each one.

    • It sounds like your app is inadvertently starting SWT, somehow:

      http://www.eclipse.org/swt/faq.php#swtawtosxmore

      Try changing your packaging to no longer include org.eclipse.ui and org.eclipse.swt and friends. That should ensure your app is truly independent of SWT.

      • 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.

        And FWIW I stumbled across this bug that describes my situation exactly:
        https://bugs.eclipse.org/bugs/show_bug.cgi?id=290970

  4. did you look at comment N° 2 :https://bugs.eclipse.org/bugs/show_bug.cgi?id=290970#c2
    they suggest using –launcher.secondThread
    and in fact the -XstartOnFirstThread was not necessary as it is for swt GUI.
    My mistake.

    • 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?

  5. Thanks so much for your post. It helped us narrow down an issue with Adobe ColdFusion 9 on MAC Lion for the Mach-II framework.

    http://blog.maestropublishing.com/adobe-coldfusion-9-on-mac-lion-fix-for-hangin


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories