Search code examples
javatomcatwicketawtheadless

Wicket CaptchaImageResource creating zero-length images on Linux server


I'm using Wicket's CaptchaImageResource to protect a submission form against bots. It works fine in my test environment (a Mac) using the Jetty server, as well as when deployed to a local Tomcat instance.

But the Captcha image fails to render when the app is deployed to Tomcat 7 on a remote Linux server. Instead I get a zero-byte response. Here's what curl -v returns for the image URL:

HTTP/1.1 200 OK
Date: Thu, 28 Jul 2011 14:28:22 GMT
Set-Cookie: JSESSIONID=6D37183A1FF2C3F43C35B49433A0FC1B; Path=/; HttpOnly
Cache-Control: no-cache, must-revalidate
Content-Type: image/png
Content-Length: 0
Connection: close

* Closing connection #0

My first instinct was that Tomcat needed to be run with -Djava.awt.headless=true. I set that up, and verified with ps that it is in fact running with that option, but the captcha still fails to render.

I don't see any error messages or warnings in Tomcat's logs. I went so far as to enable remote debugging, and set breakpoints deep in CaptchaImageResource.render(). It's entering that method, but I never see it return; somewhere around line 291 it just mysteriously stops hitting my breakpoints.

The server JVM is java-1.6.0-openjdk.x86_64. Is there any reason why that JVM wouldn't be able to render AWT graphics in headless mode?


Solution

  • Ah, biziclop led me in the right direction. I wrote this quick standalone (i.e. no-Tomcat) test:

    public static void main(String[] args) throws Exception
    {
        CaptchaImageResource resource = new CaptchaImageResource();
        int avail = resource.getResourceStream().getInputStream().available();
        System.out.println("avail: " + avail);
    }
    

    Which resulted in the following error:

    Probable fatal error:No fonts found.
    

    Some Googling on that string led me to install the following packages:

    yum install bitmap*
    yum install dejavu-lgc*
    yum install bitstream-vera*
    

    And now it works.