Headless support
So I developed an image resizing class and successfully tested it on local Windows environment. However, as soon as I tested this code on our Linux webserver, I started receiving x server connect errors. I did some research and discovered this was because the linux webserver is headless.
After doing more research, I found that in headless mode support has been available since the J2SE 1.4 platform. So, I set the headless mode system property to be true and my code still won't run. Now, instead of Tomcat shutting down with the x server connect error, I simply get Headless exceptions thrown.
I read stuff like, " Instead of setting up a dummy X server like Xvfb, just put the parameter "-Djava.awt.headless=true" in your Java invocation line, and that's it! Life is good." I'm confused, all this parameter seems to do is cause my code to throw an exception instead of completely bombing out. Methods such as:
java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment()
still don't seem like they can run in headless mode. So what purpose does it actually serve? Please help!
# 2
Thank you for getting back to me. Alright, here are the details. First my code:
public class ImageScale {
public static void scale(File inFile, String photoDir) {
try {
FileInputStream fs = new FileInputStream(inFile);
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(fs);
BufferedImage srcImg = decoder.decodeAsBufferedImage();
fs.close();
JPEGDecodeParam param = decoder.getJPEGDecodeParam();
int width = param.getWidth();
scaleHelper(width, 150, photoDir, srcImg, inFile);
}
catch (Exception e) {
System.out.println (e);
}
}
public static void scaleHelper(int width, int size, String photoDir, BufferedImage srcImg, File inFile) {
try {
double scale = calculateScale(width, size);
FileOutputStream out = new FileOutputStream (new File (photoDir + "/" + PicUploader.getPictureFileName(inFile.getName(),Integer.toString(size))));
Image img = getScaledInstance(srcImg, scale, getDefaultConfiguration());
BufferedImage biImg = toBufferedImage(img, BufferedImage.TYPE_INT_RGB);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out,JPEGCodec.getDefaultJPEGEncodeParam(biImg));
encoder.encode(biImg);
out.close();
}
catch (Exception e) {
System.out.println (e);
}
}
public static double calculateScale(int length, int limit) {
double scale;
if (length < limit) {
scale = 1d;
} else {
scale = (double)limit/(double)length ;
}
return scale;
}
public static GraphicsConfiguration getDefaultConfiguration() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
return gd.getDefaultConfiguration();
}
public static BufferedImage copy(BufferedImage source, BufferedImage target, Object interpolationHint) {
Graphics2D g = target.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolationHint);
double scalex = (double) target.getWidth() / source.getWidth();
double scaley = (double) target.getHeight() / source.getHeight();
AffineTransform at = AffineTransform.getScaleInstance(scalex, scaley);
g.drawRenderedImage(source, at);
g.dispose();
return target;
}
public static BufferedImage getScaledInstance2D(BufferedImage source, double factor, Object interpolationHint, GraphicsConfiguration gc) {
if (gc == null)
gc = getDefaultConfiguration();
int w = (int) (source.getWidth() * factor);
int h = (int) (source.getHeight() * factor);
int transparency = source.getColorModel().getTransparency();
return copy(source, gc.createCompatibleImage(w, h, transparency), interpolationHint);
}
public static Image getScaledInstanceAWT(BufferedImage source, double factor, int hint) {
int w = (int) (source.getWidth() * factor);
int h = (int) (source.getHeight() * factor);
return source.getScaledInstance(w, h, hint);
}
public static Image getScaledInstance(BufferedImage source, double factor, GraphicsConfiguration gc) {
if (factor >= 1.0)
return getScaledInstance2D(source, factor, RenderingHints.VALUE_INTERPOLATION_BICUBIC, gc);
else
return getScaledInstanceAWT(source, factor, Image.SCALE_AREA_AVERAGING);
}
public static BufferedImage toBufferedImage(Image image, int type) {
int w = image.getWidth(null);
int h = image.getHeight(null);
BufferedImage result = new BufferedImage(w, h, type);
Graphics2D g = result.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
return result;
}
}
Really, right now, I'm only trying to create thumbnails on the server so only the getScaledInstance2D method is being invoked. Like I said, originally, I was getting the x server connection error. But, I added the headless attribute to my startup scripts and now I receive the following exception:
java.awt.HeadlessException
I don't understand what the headless attribute does then? Does anyone see a way I could change my code so that this problem doesn't happen on the server.
On a related note, I've tried using Xvfd without success also. I have a process running in the bg:
root25078 24923 0 21:48 pts/200:00:00 /usr/X11R6/bin/Xvfb :10 -screen 0 1152x900x8
And the DISPLAY var set to the correct server slot:
# echo $DISPLAY
localhost:10.0
And this doesn't seem to work either. Please help!