Offscreen Imaging
-----------------
Keywords: X11, DISPLAY, BufferedImage
JFreeChart was designed to draw into an arbitrary Java 2D graphics device. In this way, a java servlet can render a chart into an offscreen image for subsequent display in a browser. See, for example:
com.jrefinery.chart.JFreeChart.createBufferedImage()
This method hinges on the construction of a java.awt.image.BufferedImage. Sadly, the constructor fails under JRE 1.3.x in he absence of a window environment from which to obtain various device properties. Typically, you get an InternalError exception:
java.lang.InternalError: Can't connect to X11 window server using ':0.0'
as the value of the DISPLAY variable.
Several workarounds are known:
1) X Virtual Frame Buffer (Xvfb) <http://xfree86.org/>
2) Pure Java AWT (PJA) <http://www.eteks.com/pja/en/index.jsp>
3) Virtual Network Computing (VNC) <http://www.uk.research.att.com/vnc>
On WinNT and Win2K with JRE 1.3.1, logging onto the console instantiates the window system and the BufferedImage creation succeeds. You must be logged is as the same user that instantiates the servlet container. Installing VNC and running tomcat as a service allows normal operation even when logged out.
On Mac OS X 10.1.4, the OS creates an anonymous instance of the JRE. This fails if the machine enters "sleep" mode, but it works during normal screen-saver operation. I haven't tried VNC in this environemnt.
Under Solaris 2.7 with JRE 1.2.2, VNC allows correct operation as long as the same user starts both tomcat and VNC.
Under RedHat linux 7.1, JRE 1.3.1 and tomcat 4.0.3, vnc-server-3.3.3r2-28 allows correct operation as long as the same user starts both tomcat and VNC. Edit the file /etc/tomcat4/conf/tomcat4.conf to set the DISPLAY variable to the same virtual X session created in /etc/sysconfig/vncservers. You may need to start VNC before starting tomcat.
Under JRE 1.4, setting the "headless" property to true allows JFreeChart to render in the absence of an X11 instance. Ray Mercer reports success on RedHat Linux 7.1, 7.1j & 7.2. I have verified correct operation on Solaris 2.7.20:
System.setProperty("java.awt.headless","true");
For servlets, you can use set the property in the command line that invokes the servlet container:
java -Djava.awt.headless=true ...
In tomcat 4, the catalina.sh script can use an environment setting:
setenv CATALINA_OPTS -Djava.awt.headless=true
Comments, corrections and additions are welcome.
John
----
John B. Matthews
johnmatthews@mac.com