友情提示:后面在2014 7 29 日有增加一个新的解决方法和问题原因的说明
笔者在开发一个java ssh+mysql的项目过程中,本来在windows下开发测试,在myeclipse中的部署都没有问题,但当想要上线测试到linux服务器时,我预先做了移植测试,在Linux上,在启动过程中,如果验证码图片是采用背景图片的,在windows下没问题,但是在linux(centos5.5)上就会有问题:异常信息如下:
1. 导致的原因
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'net.shopxx.common.JCaptchaEngine#ee20ab' defined in file [/usr/local/apache-tomcat-6.0.32/webapps/shopx/WEB-INF/classes/applicationContext.xml]:
Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [net.shopxx.common.JCaptchaEngine]:
Constructor threw exception; nested exception is com.octo.captcha.CaptchaException: Unknown error during file reading
Caused by: javax.imageio.IIOException: Not a JPEG file: starts with 0x42 0x4d
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(JPEGImageReader.java:603)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(JPEGImageReader.java:341)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(JPEGImageReader.java:475)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(JPEGImageReader.java:596)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1042)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1022)
at sun.awt.image.codec.JPEGImageDecoderImpl.decodeAsBufferedImage(JPEGImageDecoderImpl.java:89)
at com.octo.captcha.component.image.backgroundgenerator.FileReaderRandomBackgroundGenerator.getImage(FileReaderRandomBackgroundGenerator.java:201)
... 75 more
2014-4-22 2:15:55 org.apache.catalina.core.StandardContext start
Caused by:
java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.Caused by: com.octo.captcha.CaptchaException: Unknown error during file reading
2 问题分析
最关键部分就是这句错误,在读文件时发生未知错误,这个问题的因该是文件系统路径造成的,
我说一下如何解决的办法:
在原来的JCaptchaEngine这个类中,路径是这样写的,这个是测试shopxx,也有这个问题,我直接使用shopxx来说了,如果需要看shopxx的源码直接发送邮件到(845885222@qq.com)
private static final String IMAGE_PATH = "./net/shopxx/captcha/";// 随机背景图片路径
你会在JCaptchaEngine类文件中找到如下代码,这句代码的意思是,在获取验证码时采用不同的背景图片,背景图片的位置放在IMAGE_PATH指定的目录下。
BackgroundGenerator backgroundGenerator = new FileReaderRandomBackgroundGenerator(IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_PATH);
3 解决办法
方法一:不使用原有的图片作为验证码的背景了,而是使用渐变色代替验证码的背景
在验证码获取时修改成不要验证码背景,也就是把验证码背景颜色设置为纯色,
替换上边一行,代码如下:
//背景颜色随机生成
// BackgroundGenerator backgroundGenerator = new GradientBackgroundGenerator(IMAGE_WIDTH, IMAGE_HEIGHT, Color.white,Color.white);方法二:把private static final String IMAGE_PATH = "./net/shopxx/captcha/";// 随机背景图片路径下的不是jpg格式的图片删除,shopxx中在图片验证码背景图片文件夹下多加了一个captcha_bg_61.bmp的图片,我把该图片删了,一切正常。
4. 重启服务器,
更新日期:2014-07-29 早9:24
5.更新该文档后的总结,在第一次解决这个问题的时候,我自认为是验证码背景图片文件夹路径在window上和linux不一致引起的,其实不然,报的错误有一个非常明显得提示如下:
Caused by: javax.imageio.IIOException: Not a JPEG file: starts with 0x42 0x4d
上面红色的异常提示说不是一个jpeg文件,我在查找我背景图片存放的目录后,果然发现一个captcha_bg_61.bmp的图片文件,很显然,这个bmp的图片是window特有的文件,这只是可以解释的原因之一。6.从JCaptcha源码解释说明:
FileReaderRandomBackgroundGenerator.java
private static BufferedImage getImage(File o) { BufferedImage out = null; try { // ImageInfo info = new ImageInfo(); // Image image = ToolkitFactory.getToolkit().createImage(o.toString()); // info.setInput(new FileInputStream(o)); // out = new BufferedImage(info.getWidth(), info.getHeight(),BufferedImage.TYPE_INT_RGB ); // out.getGraphics().drawImage(image,out.getWidth(),out.getHeight(),null); // out.getGraphics().dispose(); // FileInputStream fis = new FileInputStream(o); JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(fis); out = decoder.decodeAsBufferedImage(); fis.close(); // Return the format name return out; } catch (IOException e) { throw new CaptchaException("Unknown error during file reading ", e); } catch (ImageFormatException e) { return null; } }
从代码中可以看出decoder是JPEGCodec的,其实这个也是我知道问题所在了,然后才这样理解的,总之一句话,在你存放验证码背景图片的文件夹src ./net/shopxx/captcha/ 下,只要存放的都是真正jpg的文件,真正你懂的,就是不要通过改后缀名过来的。而是你存储的时候就是.jpg的,搞定收工。