Alierak (alierak) wrote,

CFMX6.1, cfchart, and java awt graphics

I'm posting this so it gets into google. I don't really want anyone else to waste as much time as I just did trying to google for answers and then have to solve it themselves anyway. The key phrases here have maybe a dozen hits each, none of which helped in any measurable way.

On my webservers, I run Macromedia ColdFusion MX Server 6.1, using the included JRun, using the included Java 2 1.4.2 runtime.

I've got some java servlets on older webservers that I need to move to the CFMX server, and I figure it would be nice to use JRun's ServletInvoker instead of setting up some completely different java servlet engine for them. The servlets produce graphics output using AWT (java's abstract windowing toolkit), which has traditionally required a connection to some type of display even if you just want to create images in memory and then encode them as gifs or jpegs or whatever. For Windows servers, this is fine, you rarely run them without a graphics card and KVM of some sort. On Unix, you can use your X11 display. Unix boxes are more often set up headless, though, using serial consoles and sometimes lacking graphics hardware altogether, so the traditional workarounds include running Xvfb (the virtual framebuffer X server), or PJA (Pure Java AWT, which I'm told still requires the X11 libraries to be on the system).

These workarounds mainly ought to apply to older JVMs, since 1.4.2 introduces headless support. But according to this Macromedia technote, if you actually set java.awt.headless=true, it will break ColdFusion's own cfchart graphing software, which we are actually hoping to use. I can confirm that it does break, cfchart will throw java.awt.HeadlessException when subsequently invoked. But it also doesn't allow the other graphics servlets to work; it turns out that java's headless mode means you can do some things, but you can't use any awt classes or methods that would "require" a keyboard, mouse, or display and BufferedImage.createGraphics is one of those. So creating a Frame is off limits in headless mode, as is creating a Graphics or Graphics2D, even just to draw in a BufferedImage. Argh. Some of the servlets that do these things are closed-source, or so crufty that we can't justify changing them to avoid the problem. D'oh.

OK, fine, so I'll install Xvfb just like I've done in the past, and any awt methods that need the display can just connect to it, right? Well, not so fast. CFMX has already anticipated the lack of X display and configured itself to run with, which throws exceptions whenever you try to use awt graphics methods: "java.lang.RuntimeException: This graphics environment can be used only in the software emulation mode." This is pretty much what the technote said: you can set either headless mode or this special graphics environment setting, so you can either have cfchart working, or you can have your servlets working (and ours didn't). Bah.

Well, I found some google traces of "ExGraphicsEnvironment" instead of "ExHeadlessGraphicsEnvironment", apparently related to older JVMs or versions of CFMX; that sounded like it might be able to work with the X11 display. But it didn't work out; changing the setting in jvm.config broke cfchart as well as the servlets, causing SIGSEGV in a backend thread and producing the following cryptic error: "java.lang.Error: no font properties file found." Uhm, but I was sure I hadn't deleted the files in the ColdFusion runtime dir... strace didn't show the process even trying to look for a file. So I gave up for the day.

Today's answer to the above junk: don't specify any options in ColdFusion's runtime/bin/jvm.config, and do run Xvfb. Be sure the DISPLAY environment variable is set correctly when invoking the coldfusion startup script, or else modify the script to set and export DISPLAY for itself. Both cfchart and the servlets are happy now. So I submitted terse feedback on the bad technote within their 300-character limit, and I'm posting this little narrative.

But the solution I stumbled onto makes me suspect that PJA might work even more cleanly. It seems cfchart doesn't suffer from having java.awt.graphicsenv set to the default native X11 display, so it also shouldn't mind if you set it to some other full-featured graphics environment, right? Maybe next time I'll try it; if anyone else does, please leave a comment.
Tags: work

  • travel plans

    I'm flying to Boston in a few days to give some cluedumps at work. In case anyone there cares, I'll be flying up on the 10th and back on the 18th.

  • Sleep schedule randomization

    Ugh. I was doing so well last week at the LISA conference. I was sleeping 11pm to 7am without having to use an alarm clock or wakeup calls. Here I am…

  • Stuff and things

    More of this journal stuff. No way am I doing this every day. I cleaned up the garage on Sunday, Alex's empty crates and junk, thinking I'll want to…

  • Post a new comment


    default userpic

    Your reply will be screened

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.