情境:
java web程序中,頁面包含圖形的展示,是使用jfreechart來開發的。war包部署在RHEL 5.5環境下的tomcat中。
1 在服務器(服務器默認啓動爲圖形界面)本機上啓動tomcat,在客戶端瀏覽器上查看jfreechart圖形正常;
2 遠程通過ssh啓動服務器上的tomcat,在客戶端瀏覽器上查看jfreechart圖形爲小紅叉;
先將異常部分貼出:
java.lang.InternalError: Can't connect to X11 window server using 'localhost:10.0' as the value of the DISPLAY variable.
at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
at sun.awt.X11GraphicsEnvironment.access$000(X11GraphicsEnvironment.java:53)
at sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:142)
at java.security.AccessController.doPrivileged(Native Method)
at sun.awt.X11GraphicsEnvironment.<clinit>(X11GraphicsEnvironment.java:131)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:68)
at sun.awt.X11.XToolkit.<clinit>(XToolkit.java:96)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at java.awt.Toolkit$2.run(Toolkit.java:821)
at java.security.AccessController.doPrivileged(Native Method)
at java.awt.Toolkit.getDefaultToolkit(Toolkit.java:804)
at javax.swing.UIManager.initialize(UIManager.java:1236)
at javax.swing.UIManager.maybeInitialize(UIManager.java:1219)
at javax.swing.UIManager.getDefaults(UIManager.java:529)
at javax.swing.UIManager.getColor(UIManager.java:563)
at org.jfree.chart.JFreeChart.<clinit>(JFreeChart.java:261)
at org.jfree.chart.ChartFactory.createLineChart(ChartFactory.java:1242)
at cfca.xfraud.management.service.activity.ActivityStatisticsService.getEntityForm(ActivityStatisticsService.jav
a:325)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:592)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:
182)
…………分析以上異常已足夠,剩下的異常棧信息忽略。
經過研究,發現該問題更深一步是這樣:
1 如果以init 5的級別啓動REHL 5.5系統,再啓動tomcat,在客戶端瀏覽器上查看jfreechart圖形,圖形顯示正常;
2 如果以init 3的級別啓動RHEL 5.5系統,再啓動tomcat,在客戶端瀏覽器上查看jfreechart圖形,圖形顯示爲小紅叉;
這是很重要的結論,這個錯誤是因爲圖表程序是通過AWT實現的,AWT會調用操作系統本地窗口資源繪圖,windows對此支持很好,
在linux下如果沒有進到X window,AWT就不能繪圖。
而且,通過查看異常的堆棧,發現at org.jfree.chart.JFreeChart.<clinit>(JFreeChart.java:261)這個異常,此時查找jfreechart官網的作者對該問題的解答:Web-Applications cannot have a Swing-GUI.也就是說,JFreechart採用AWT來繪圖,如果沒有圖形界面,jfreechart裏面所用到的
java.awt.Toolkit
java.awt.Color
java.awt.Rectangle
java.awt.Font
java.awt.FontMetrics
java.awt.image.ColorModel
等一系列包,均不能夠使用。
使用了tomcat遠程調試,將項目中所使用的jfreechart-1.0.13.jar源碼下載,發現確實是跟蹤到這行報錯:
JFreeChart chart = ChartFactory.createLineChart("交易量統計圖", "時間(" + units + ")" + time, "數量", dataset, PlotOrientation.VERTICAL, true, false, false);
createLineChart方法裏面會調用的JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,plot, legend);
而JFreeChart.DEFAULT_TITLE_FONT是public static final Font DEFAULT_TITLE_FONT = new Font("SansSerif", Font.BOLD, 18);
也就是說,用了awt的Font類。因爲JFreeChart(String title, Font titleFont, Plot plot,boolean createLegend) 這個構造函數,本來就用的是Font,修改源碼的方式可能會很麻煩,作罷。
問題應該已經研究的很清楚了。
(http://www.jfree.org/phpBB2/viewtopic.php?p=58565&sid=96ed91d7c0d71ba11e988201cbaafb47 jfreechart網站)
網上關於Can't connect to X11 window server的解決方案如下:
1 export DISPLAY=:0,然後重啓服務器
已驗證,無效。
2 在JVM中加入-Djava.awt.headless=true
對於tomcat ,可以修改catalina.sh,加入:CATALINA_OPTS="$CATALINA_OPTS -Djava.awt.headless=true"
已驗證,無效
自己研究的解決方法:
3 調用ChartUtilities.writeChartAsPN
將每個chart存爲圖片到硬盤上,然後通過頁面加載,這種方法,勉強解決該問題,但必須修改程序。
4 修改tomcat的startup.sh
加入export CATALINA_OPTS="-Djava.awt.headless=true",問題得到完美解決。
也就是說,init 3啓動級別下,這種方式可以解決java awt的問題。