As well as containing very useful functions and objects for the creation of GUIs (useful because Swing extends AWT really) Java AWT (Abstract Windowing Toolkit) also provides a bunch of utility methods and object used for non-GUI related image manipulation via the excellent ImageIO classes that were introduced in Java 1.4. This all sounds great but the problems start when you try to use ImageIO in a scenario where the JVM has no access to an X-server or equivalent to do GUI stuff, then ImageIO breaks down because as soon as you access any AWT component java checks for a place to render to and if it finds none it gives a bizarre and really un-informative exception and dies! Now, you might ask why you would need to manipulate images if you have no GUI, well if you think about it that is the kind of thing that web servers have to do all the time, in fact the blogging software I am using to write this post needs to do that kind of thing all the time (but not in Java of course)!

However, do not despair, deep in the bowels of Java there is a solution and since even Google had some trouble pointing me to it I figured I’d share it with the world!

The key is to decapitate AWT, or, to be more formal to force it to run "headless". If you are just running your application from the command line this is not hard to do at all, you just pass Java a command line argument to tell it to run AWT headless like so:

java xxxxxxx -Djava.awt.headless=true

However, the chances are you won’t be running this kind of application from the command line, in all likelihood you will be trying to do this from within a web server like Tomcat and you can’t just add that -D flag to the Tomcat startup script!

However, after some dissecting of the main tomcat startup script (catalina.sh) I found the solution for Tomcat servers, you need to set up an environment variable called JAVA_OPTS that contains the option and export it in what ever script you are using to start Tomcat. I am running Tomcat on OS X so I did this in my StartupItem for Tomcat (/Library/StartupItems/Tomcat/Tomcat) which now looks like this:

#!/bin/sh

. /etc/rc.common
export JAVA_HOME="/Library/Java/Home"
export CATALINA_HOME="/usr/local/tomcat"
export JAVA_OPTS="-Djava.awt.headless=true"

if [ "${TOMCAT}" = "-YES-" ]; then
ConsoleMessage "Starting Tomcat"
su tomcat - /usr/local/tomcat/bin/startup.sh
fi

So, it really is that simple but I have to say it took me a long to to figure all this out this afternoon when for no apparent reason ImageIO was crashing with some error about a window!