Login  Register

Re: Patch for ImageJ that fixes a HeadlessException error

Posted by Wayne Rasband on Jul 19, 2007; 3:44pm
URL: http://imagej.273.s1.nabble.com/Patch-for-ImageJ-that-fixes-a-HeadlessException-error-tp3698809p3698810.html

This bug is fixed in ImageJ 1.39a. The v1.39a daily build is at
<http://rsb.info.nih.gov/ij/ij.jar>, the source is at
<http://rsb.info.nih.gov/ij/source/>, and the release notes are at
<http://rsb.info.nih.gov/ij/source/release-notes.html>.

-wayne

On Jul 18, 2007, at 5:32 PM, Victor Petrov wrote:

> Dear all,
>
> I would like to submit a patch that corrects ImageJ's behavior when
> running
> in headless mode (i.e. with java -Djava.awt.headless=true).
>
> Symptoms:
>   When operating in headless mode ( i.e. java -
> Djava.awt.headless=true-jar
> MyConverter.jar ), ImageJ is unable to perform a successful call to
> ij.processor.ImageProcessor.drawString() because drawString() calls the
> setupFrame() function, which in turn attempts to instanciate a
> java.awt.Frame object.
> This attempt results in a HeadlessException error being thrown by the
> java.awt.Frame constructor (there isn't much sense for Java to create a
> frame if a display server is not present, so it throws an exception
> error).
> The mistake here is that functions that do image manipulation, like
> drawString(), and do not require the ImageJ GUI, should not call
> setupFrame() if Java is running in headless mode.
>
> Solution:
>   The only reason drawString() calls setupFrame() is to create valid
> Font
> and FontMetrics objects, and the only reason setupFrame() creates a
> Frame
> object is to get a Graphics object that is used to create the
> FontMetrics
> object. If it were possible to get the Graphics object from a different
> source, not java.awt.Frame, then there would be no need to create the
> Frame.
> And thus, I have modified the setupFrame() function to use a
> BufferedImage
> object, only in case the java.awt.headless property is true.
> Below is a modified version of the setupFrame() function, contained in
> ij.process.ImageProcessor.java (revision 1.37v):
>
> -------------- v.137v ----------------------
> private void setupFrame() {
>
>        if
> (System.getProperty("java.awt.headless").equalsIgnoreCase("true"))
>
>        {
>            if (image==null)
>                image=new BufferedImage(img.getWidth(null),img.getHeight
> (null),BufferedImage.TYPE_INT_RGB);
>
>            if (font==null)
>                font = new Font("SansSerif", Font.PLAIN, 12);
>            if (fontMetrics==null)
>            {
>                Graphics g=image.getGraphics();
>                fontMetrics=g.getFontMetrics(font);
>            }
>            return;
>        }
>        if (frame==null) {
>            frame = new Frame();
>            frame.pack();
>            frame.setBackground(Color.white);
>        }
>        if (font==null)
>            font = new Font("SansSerif", Font.PLAIN, 12);
>        if (fontMetrics==null) {
>            frame.setFont(font);
>            fontMetrics = frame.getFontMetrics(font);
>        }
>    }
> ----------------------------------------------------------
>
> I have attached the modified source code of ImageProcessor.java.
>
> Conclusion:
>   This approach allowed us, the developers at the Center for Brain
> Science
> and Neuroimaging at Harvard, to continue using our image
> viewer/converter on
> Linux computers that do not have the X server installed.
> Currently, we are forced to maintain a separate version of ImageJ that
> incorporates the changes explained above.
> We would like this fix to be applied by the ImageJ maintainers, or, at
> least, for the setupFrame() problem to be resolved, so that we could
> use new
> versions of ImageJ in the future, without worrying about modifying and
> rebuilding from source.
>
> Sincerely,
> Victor Petrov
> <ImageProcessor.java.txt>