Offscreen Imaging: X11, DISPLAY, BufferedImage

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
John Matthews

Offscreen Imaging: X11, DISPLAY, BufferedImage

Post by John Matthews » Tue Jun 25, 2002 8:03 pm

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

David Gilbert

Re: Offscreen Imaging: X11, DISPLAY, BufferedImage

Post by David Gilbert » Tue Jun 25, 2002 11:54 pm

Hi John,

Thanks for providing this excellent summary. It may become the first entry in the JFreeChart FAQ!

Regards,

DG.

Alex Shepherd

Re: Offscreen Imaging: X11, DISPLAY, BufferedImage

Post by Alex Shepherd » Thu Jul 11, 2002 7:35 am

Well, I am trying to get JFreeChart to run on a Linux system without X installed and it is throwing the following exception:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /opt/j2sdk1.4.0_01/jre/lib/i386/libawt.so: libXp.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:1480)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1396)
at java.lang.Runtime.loadLibrary0(Runtime.java:772)
at java.lang.System.loadLibrary(System.java:832)
at sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:50)
at java.security.AccessController.doPrivileged(Native Method)
at java.awt.Toolkit.loadLibraries(Toolkit.java:1397)
at java.awt.Toolkit.<clinit>(Toolkit.java:1418)
at java.awt.Color.<clinit>(Color.java:250)
at com.jrefinery.chart.ValueAxis.<clinit>(ValueAxis.java:85)
at com.jrefinery.chart.ChartFactory.createTimeSeriesChart(ChartFactory.java:453)
at com.pav.chart.TimeSeriesLineChart.main(TimeSeriesLineChart.java:256)

The problem appears to be triggered by classes setting default Colors in static variables.

I have tried setting the system properties (one at a time) for both Java 1.4 headless and tried to use PJA as below

Properties prop = System.getProperties ();
prop.put ("awt.toolkit", "com.eteks.awt.PJAToolkit");
// prop.put ("java.awt.headless", "true");
System.setProperties (prop);

But I still have the problem. Do I still have to install part of X even if I don't want to use it?

Any help appreciated!!!!

Alex Shepherd

RC

Re: Offscreen Imaging: X11, DISPLAY, BufferedImage

Post by RC » Tue Jul 16, 2002 8:47 pm

I asked this question long time ago, but people only tell me use Xvfb without
any instructions.

Finally I got the Xvfb work with JRE 1.3.x, tomcat 3.x, Redhat Linux 7.2.

Start Xvfb with server 1 (server 0 is default for console),
screen 0 (I only have one monitor screen),
size 1280x1024,
depth 8
In background or in rc startup script.

Xvfb :1 -screen 0 1280x1024x8 &

Then longin and
setenv DISPLAY :1.0 (for csh, tcsh)
or
export DISPLAY=:1.0 (for sh, ksh, bash)
Then recompiled your code(s) for tomcat servlet.
javac YourJFreeChartClass.java

When you run your servlet or JSP vs. browser, YourJFreeChartClass
will dump the JPEG image and display to your browser.

Casey Rodgers

Re: Offscreen Imaging: X11, DISPLAY, BufferedImage

Post by Casey Rodgers » Thu Aug 29, 2002 4:32 am

This works fine when you have full control, but what about running an a J2EE environment. You will have have the option of starting an external process.

Can JFreeChart be used in a J2EE environment?
Has anyone sucessfully deployed JFreeChart in a J2EE environment?


Thanks,


Casey

Guillermo Castro

Re: Offscreen Imaging: X11, DISPLAY, BufferedImage

Post by Guillermo Castro » Thu Sep 19, 2002 9:57 pm

I wonder,

Why don't you use the PJA library to avoid this kind of problems. The library is GPL, so it can be included with JFreeCharts, and it would make JFreeCharts work on any environment. I've use it for a servlet that renders barcodes, and now I can put my servlet on any server, linux, win or solaris, w/o any problem. There's almost no need to change the code, so...

Anyways, it's just a thought.

Guillermo

Andreas Schroeder

Re: Offscreen Imaging: X11, DISPLAY, BufferedImage

Post by Andreas Schroeder » Fri Sep 20, 2002 7:39 am

Hi Guillermo,
JFreeChart is LGPL. PJA is GPL for me, this makes a BIG difference: i can use the one, but not the other - if i want to earn some money :-)
I think that if JFreeChart uses PJA, it must use the GPL too. That is the reason i think.

regards,

Andreas Schroeder
Gillardon Application Server Framework (ASF) developer

David Gilbert

Re: Offscreen Imaging: X11, DISPLAY, BufferedImage

Post by David Gilbert » Wed Sep 25, 2002 11:02 am

PJA is a good workaround for the X11 issue, but only one of several, so I don't think it is a good idea to incorporate it by default with JFreeChart. As people migrate to JDK1.4 (which has the "headless" mode), there will be less and less need for PJA anyway.

Regards,

DG.

OleJohan Rustad/Andreas

Re: Offscreen Imaging: X11, DISPLAY, BufferedImage

Post by OleJohan Rustad/Andreas » Tue Feb 25, 2003 11:29 am

We (also) had problems using cewolf on linux-server (redhat 8.0), but now it works perfectly, using the tip on top of this page. Wrote CATALINA_OPTS=" -Djava.awt.headless=true" in the/usr/bin/dtomcat4-file. We use j2sdk1.4.1. Great!

Ivan Bayross

Error : java.lang.NoClassDefFoundError: com/jrefinery/ui/Dra

Post by Ivan Bayross » Wed Mar 05, 2003 6:17 am

hi
my chart are working perfectly on Windows but when i copied the same folder in Linux . it displays the message .

help me plz

help me plz

help me plz

help me plz

help me plz

help me plz

help me plz

i donno reason


java.lang.NoClassDefFoundError: com/jrefinery/ui/Drawable
at java.lang.ClassLoader.findBootstrapClass(Native Method)
at java.lang.ClassLoader.findBootstrapClass0(ClassLoader.java:730)
at java.lang.ClassLoader.loadClass(ClassLoader.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:265)
at java.lang.ClassLoader.loadClass(ClassLoader.java:262)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1320)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1254)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:322)
at java.lang.Class.getDeclaredFields0(Native Method)
at java.lang.Class.privateGetDeclaredFields(Class.java:1480)
at java.lang.Class.getField0(Class.java:1713)
at java.lang.Class.getDeclaredField(Class.java:1176)
at java.io.ObjectStreamClass.getDeclaredSUID(ObjectStreamClass.java:1404)
at java.io.ObjectStreamClass.access$400(ObjectStreamClass.java:45)
at java.io.ObjectStreamClass$3.run(ObjectStreamClass.java:331)
at java.security.AccessController.doPrivileged(Native Method)
at java.io.ObjectStreamClass.(ObjectStreamClass.java:329)
at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:249)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1010)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1330)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1302)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1245)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1052)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:278)
at de.laures.cewolf.util.cache.KeyGenerator.generateKey(KeyGenerator.java:46)
at de.laures.cewolf.taglib.ChartImageDefinitionImpl.getKey(ChartImageDefinitionImpl.java:103)
at de.laures.cewolf.taglib.ChartImageDefinitionImpl.hashCode(ChartImageDefinitionImpl.java:117)
at java.util.Hashtable.containsKey(Hashtable.java:305)
at de.laures.cewolf.util.cache.ChartImageCacheImpl.containsChart(ChartImageCacheImpl.java:123)
at de.laures.cewolf.taglib.ChartImgTag.doStartTag(ChartImgTag.java:70)
at org.apache.jsp.testpage$jsp._jspService(testpage$jsp.java:965)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:107)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.jasper.servlet.JspServlet$JspServletWrapper.service(JspServlet.java:201)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:381)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:473)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:243)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:190)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2347)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:170)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:170)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:468)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at org.apache.catalina.connector.http.HttpProcessor.process(HttpProcessor.java:1027)
at org.apache.catalina.connector.http.HttpProcessor.run(HttpProcessor.java:1125)
at java.lang.Thread.run(Thread.java:536)

David Gilbert

Re: Offscreen Imaging: X11, DISPLAY, BufferedImage

Post by David Gilbert » Wed Mar 05, 2003 10:48 am

You don't have the jcommon-0.7.2.jar file on your classpath.

Regards,

Dave Gilbert

RV

java.awt.headless prop works

Post by RV » Thu Jun 12, 2003 4:59 pm

I set this prop to disable X11 dependency. And it works fine on solaris 2.8

superjma
Posts: 8
Joined: Sat Jun 14, 2003 12:15 pm

PJA do not work on RH9

Post by superjma » Sat Jun 14, 2003 3:31 pm

I got a Redhat 9 server without any X installed. I got the same problem as described, with the error message:
Exception in thread "main" java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.

I used these system.properties but this did not help:

Properties prop = System.getProperties ();
prop.put ("awt.toolkit", "com.eteks.awt.PJAToolkit");
prop.put ("java.awt.headless", "true");
System.setProperties (prop);

The command /usr/java/j2sdk1.4.1_01/bin/java -Djava.awt.headless=true grafdata do not work either.

I am running the program from the shell as root, because it is the plan that it should be run as a cron-job. Hope someone can help me...

I do not have Tomcat installed but I do have Resin! (But the plan was only to generate a new JPEG once a week)

I installed the package compat-libstdc++-7.3-2.96.118.i386.rpm which solved one of my problems with libstdc++, but then I got an other one, X11! :(

edweirdo
Posts: 4
Joined: Fri Jul 25, 2003 7:07 pm

Excellent post. This should be in the installation document

Post by edweirdo » Fri Jul 25, 2003 7:45 pm

There are 2 categories of runtime environments that will use jfreechart:
- GUI applications
- non-GUI applications (e.g. cron jobs)

I wrote code to generate reporting charts and tested it in my Linux environment. But when I went to automate the reporting charts generation via cron, they failed due to the problem addressed in this post. For me, this was no big deal, as I have root privileges and was able to install Java 1.4 and set that "headless" AWT system property in my shell script.

I think it would be wise in the installation documentation to discuss the different runtime environments based on how people are using JFreeChart. If I did not have root privileges, I would have had to wait for an admin to install it, and that can take time. Developers who use open-source packages often get the question: what is needed to use this software? It's not good to find out something needs to be installed last minute...

juanny

Solaris 2.8 and SunONE Enterprise Server 6.0 X11 issue

Post by juanny » Fri Aug 01, 2003 6:26 am

Hi guys:
I have tried java 1.4 with the java.awt.headless=true setting at the servlet engine configuration level jvm12.conf and on an initialization servlet and still can't get chartdemo1 to work. Anybody running SunONE
and JFreeCharts? Please advice.
ja

============ Error trace ======================
[01/Aug/2003:01:08:38] failure ( 6250): Internal error: Unexpected error condition thrown (java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.,Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.), stack: java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.
at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
at <Unloaded Method>
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName0(Compiled Code)
at java.lang.Class.forName(Compiled Code)
at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:63)
at java.awt.Font.initializeFont(Font.java:262)
at java.awt.Font.<init>(Font.java:292)
at <Unloaded Method>
at org.jfree.chart.axis.Axis.<init>(Unknown Source)
at org.jfree.chart.axis.CategoryAxis.<init>(Unknown Source)
at org.jfree.chart.ChartFactory.createBarChart(Unknown Source)
at chartdemo1.doGet(chartdemo1.java:77)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at com.iplanet.server.http.servlet.NSServletRunner.invokeServletService(NSServletRunner.java:891)
at com.iplanet.server.http.servlet.WebApplication.service(WebApplication.java:1064)
at com.iplanet.server.http.servlet.NSServletRunner.ServiceWebApp(NSServletRunner.java:953)

==========================================

Locked