===============================
gentoo(linux)系统下图片问题
验证码图片问题或者是说采用以下方案生成图片的问题
{code}
// 创建内存图象并获得其图形上下文
final BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
final Graphics g = image.getGraphics();
{code}
如何解决?
我目前机器上的JDK如下(java-config -L)
JDK发行版:
1) IcedTea6-bin 1.8.1 [icedtea6-bin]
*) Sun JDK 1.6.0.21 [sun-jdk-1.6]
解决方案1:
使用sun-jdk-1.6就可以好(java-config -S 1 / java-config -s 1)
但是使用icedtea6-bin会报以下异常:
{code}
java.lang.UnsatisfiedLinkError: /opt/icedtea6-bin-1.8.1/jre/lib/amd64/libfontmanager.so: libfreetype.so.6: cannot open shared
object file: No such file or directory
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1750)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1667)
at java.lang.Runtime.loadLibrary0(Runtime.java:840)
at java.lang.System.loadLibrary(System.java:1047)
at sun.font.FontManagerNativeLibrary$1.run(FontManagerNativeLibrary.java:61)
at java.security.AccessController.doPrivileged(Native Method)
at sun.font.FontManagerNativeLibrary.<clinit>(FontManagerNativeLibrary.java:32)
at sun.font.FontManager$1.run(FontManager.java:233)
at java.security.AccessController.doPrivileged(Native Method)
at sun.font.FontManager.<clinit>(FontManager.java:230)
at sun.java2d.SunGraphicsEnvironment$2.run(SunGraphicsEnvironment.java:178)
at java.security.AccessController.doPrivileged(Native Method)
at sun.java2d.SunGraphicsEnvironment.<init>(SunGraphicsEnvironment.java:162)
at sun.awt.X11GraphicsEnvironment.<init>(X11GraphicsEnvironment.java:252)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
at java.lang.Class.newInstance0(Class.java:372)
at java.lang.Class.newInstance(Class.java:325)
at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:82)
at java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1152)
at java.awt.image.BufferedImage.getGraphics(BufferedImage.java:1142)
java.lang.NoClassDefFoundError: Could not initialize class sun.font.FontManager
at sun.java2d.SunGraphicsEnvironment$2.run(SunGraphicsEnvironment.java:178)
at java.security.AccessController.doPrivileged(Native Method)
at sun.java2d.SunGraphicsEnvironment.<init>(SunGraphicsEnvironment.java:162)
at sun.awt.X11GraphicsEnvironment.<init>(X11GraphicsEnvironment.java:252)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
at java.lang.Class.newInstance0(Class.java:372)
at java.lang.Class.newInstance(Class.java:325)
at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:82)
at java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1152)
at java.awt.image.BufferedImage.getGraphics(BufferedImage.java:1142)
{code}
解决方案2:
启动 X11 window server
编辑tomcat的启动脚本,加上export DISPLAY=:0,重启tomcat
无论使用sun jdk还是使用icedtea都会正常,并且jfreechart的问题也能解决
如果关闭了X11 那么Web服务会崩溃掉(503),再启动X11还是不能恢复,还需要重启tomcat
如果设置了export DISPLAY=:0 而没有启动X11 window server会报以下异常:
{code}
java.lang.InternalError: Can't connect to X11 window server using ':0' as the value of the DISPLAY variable.
at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
at sun.awt.X11GraphicsEnvironment.access$100(X11GraphicsEnvironment.java:62)
at sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:166)
at java.security.AccessController.doPrivileged(Native Method)
at sun.awt.X11GraphicsEnvironment.<clinit>(X11GraphicsEnvironment.java:142)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:186)
at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:82)
at java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1152)
at java.awt.image.BufferedImage.getGraphics(BufferedImage.java:1142)
{code}
如果启动了X11 window server,而没有设置export DISPLAY=:0那么无论使用sun jdk还是使用icedtea都会正常。
==============================
jfreechart生成图片时候会出现错误
这个方法http://lansky07.iteye.com/blog/283899 我没有得到解决。
同一思路的方案 http://www.iteye.com/topic/665688 也没得到解决。
都会出现这个异常:
{code}
java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:159)
at java.awt.Window.<init>(Window.java:432)
at java.awt.Frame.<init>(Frame.java:403)
at javax.swing.JFrame.<init>(JFrame.java:202)
at org.jfree.ui.ApplicationFrame.<init>(ApplicationFrame.java:65)
{code}
解决方法:
1、安装xorg-server (X11 window server)并启动(startx)
2、找到tomcat的启动脚本,加上export DISPLAY=:0,重启tomcat
位置如下:
{code}
init_env_vars() {
# Populate JAVA_HOME
JAVA_HOME=`java-config --jre-home`
export DISPLAY=:0
{code}
如果没有设置export DISPLAY=:0,出错如下:
{code}
java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:173)
at java.awt.Window.<init>(Window.java:437)
at java.awt.Frame.<init>(Frame.java:419)
at javax.swing.JFrame.<init>(JFrame.java:218)
at org.jfree.ui.ApplicationFrame.<init>(ApplicationFrame.java:65)
{code}
如果设置了export DISPLAY=:0 而没有安装 x11-libs/libX11,出错如下:
{code}
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.apache.catalina.startup.Bootstrap.load(Unknown Source)
at org.apache.catalina.startup.Bootstrap.main(Unknown Source)
Caused by: java.util.ServiceConfigurationError: sun.java2d.cmm.PCMM: Provider sun.java2d.cmm.lcms.LCMS could not be instantiated:
java.lang.UnsatisfiedLinkError: /opt/icedtea6-bin-1.8.1/jre/lib/amd64/xawt/libmawt.so: libX11.so.6: cannot open shared object
file: No such file or directory
at java.util.ServiceLoader.fail(ServiceLoader.java:224)
at java.util.ServiceLoader.access$100(ServiceLoader.java:181)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:370)
at java.util.ServiceLoader$1.next(ServiceLoader.java:438)
at sun.java2d.cmm.CMSManager$1.run(CMSManager.java:65)
at java.security.AccessController.doPrivileged(Native Method)
at sun.java2d.cmm.CMSManager.getModule(CMSManager.java:55)
at java.awt.color.ICC_Profile.activateDeferredProfile(ICC_Profile.java:1100)
at java.awt.color.ICC_Profile$1.activate(ICC_Profile.java:741)
at sun.java2d.cmm.ProfileDeferralMgr.activateProfiles(ProfileDeferralMgr.java:93)
at java.awt.color.ICC_Profile.getInstance(ICC_Profile.java:774)
at java.awt.color.ICC_Profile.getInstance(ICC_Profile.java:994)
at java.awt.color.ICC_Profile.getInstance(ICC_Profile.java:959)
at java.awt.color.ICC_Profile$2.run(ICC_Profile.java:910)
at java.security.AccessController.doPrivileged(Native Method)
at java.awt.color.ICC_Profile.getStandardProfile(ICC_Profile.java:905)
at java.awt.color.ICC_Profile.getInstance(ICC_Profile.java:866)
at java.awt.color.ColorSpace.getInstance(ColorSpace.java:321)
at com.sun.imageio.plugins.jpeg.JPEG.<clinit>(JPEG.java:217)
at com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi.<init>(JPEGImageReaderSpi.java:45)
at javax.imageio.spi.IIORegistry.registerStandardSpis(IIORegistry.java:175)
at javax.imageio.spi.IIORegistry.<init>(IIORegistry.java:137)
at javax.imageio.spi.IIORegistry.getDefaultInstance(IIORegistry.java:159)
at javax.imageio.ImageIO.<clinit>(ImageIO.java:64)
at org.apache.catalina.core.JreMemoryLeakPreventionListener.lifecycleEvent(JreMemoryLeakPreventionListener.java:138)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
at org.apache.catalina.core.StandardServer.initialize(StandardServer.java:770)
at org.apache.catalina.startup.Catalina.load(Catalina.java:524)
at org.apache.catalina.startup.Catalina.load(Catalina.java:548)
... 6 more
Caused by: java.lang.UnsatisfiedLinkError: /opt/icedtea6-bin-1.8.1/jre/lib/amd64/xawt/libmawt.so: libX11.so.6: cannot open shared
object file: No such file or directory
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1750)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1646)
at java.lang.Runtime.load0(Runtime.java:787)
at java.lang.System.load(System.java:1022)
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1750)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1667)
at java.lang.Runtime.loadLibrary0(Runtime.java:840)
at java.lang.System.loadLibrary(System.java:1047)
at sun.java2d.cmm.lcms.LCMS$1.run(LCMS.java:94)
at java.security.AccessController.doPrivileged(Native Method)
at sun.java2d.cmm.lcms.LCMS.<clinit>(LCMS.java:88)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:362)
... 32 more
{code}
=================
这个事情耗费了我近两天的时间,哪位仁兄在gentoo下面也遇到这个问题了?麻烦赐教,给个好的解决方案。
为方便调试,我建立了个缺省包的JAVA文件,可以编译调试
javac -cp ./jcommon-1.0.16.jar:./jfreechart-1.0.13.jar ChartDemo.java java -cp ./jcommon-1.0.16.jar:./jfreechart-1.0.13.jar:. ChartDemo
在附件中下载该类和依赖jar包(一个简单的java文件和两个依赖包)。
===================================================================
最终解决方案:
以上问题的出现,是一个大错误导致。代码本身写的就有问题,就用到了图形界面的东西,怪不得人家要是要求X11服务呢?
如果你继承了 org.jfree.ui.ApplicationFrame 在此基础上写,就会出现问题
所以请不要继承他,画图的地方直接画就是了,也用不着这个父类的啥方法。
恨啊,没看那段代码是如何写的。后面做了这么多测试。