S
Sandman
Hello all,
I've been working on this problem for about 2 days now. Here it is:
I have a servlet programmed up that will operate in a headless environment.
I'm using j2sdk1.4.2 and apache tomcat 4.1.24. I have x-windows installed
on my linux server but it does not run all the time (only when i really need
it). What i want my servlet to do is to create a JButton (or any swing
Component--heavy or lightweight) and convert it to a Buffered Image and then
output that image as a image/png. Here is the code that I have currently
that works fine when I have x-windows running and isHeadless=false:
package graphics;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import javax.swing.*;
public class SwingGeneratorServlet extends HttpServlet
{
// this is the converter method. it throws the exception
public static BufferedImage createImage(Component cmp) {
Dimension d = cmp.getSize();
d.setSize(100, 100);
BufferedImage bi = new BufferedImage((int) d.getWidth(),
(int) d.getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();
//temporary container
JFrame jf = new JFrame();
jf.getContentPane().add(cmp);
jf.pack();
SwingUtilities.paintComponent(g2d, cmp, jf.getContentPane(),
0, 0, (int) d.getWidth(), (int)
d.getHeight());
return bi;
}
// this is the servlet's io method. it generates, converts, then
outputs the image
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
JButton bu = new JButton("Swing Servlet");
BufferedImage bi = createImage(bu);
response.setContentType("image/png");
ServletOutputStream out = response.getOutputStream();
ImageIO.write(bi, "png", out);
out.close();
}
// this just directs to doGet(...); nothing interesting here
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
doGet(request, response);
}
}
Now, when isHeadless=true (regardless of whether I am running x-windows or
not), an exception gets thrown:
HTTP Status 500 -
----------------------------------------------------------------------------
----
type Exception report
message
description The server encountered an internal error () that prevented it
from fulfilling this request.
exception
java.awt.HeadlessException
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:121)
at java.awt.Window.(Window.java:274)
at java.awt.Frame.(Frame.java:401)
at java.awt.Frame.(Frame.java:366)
at javax.swing.JFrame.(JFrame.java:154)
at
graphics.SwingGeneratorServlet.createImage(SwingGeneratorServlet.java:26)
at graphics.SwingGeneratorServlet.doGet(SwingGeneratorServlet.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Application
FilterChain.java:247)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterCh
ain.java:193)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.ja
va:256)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:643)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.ja
va:191)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:643)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180
)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:643)
at
org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.
java:171)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:641)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172
)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:641)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java
:174)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:643)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:594)
at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConne
ction(Http11Protocol.java:392)
at
org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:565)
at
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.jav
a:619)
at java.lang.Thread.run(Thread.java:534)
----------------------------------------------------------------------------
----
Apache Tomcat/4.1.24
This is to be expected, since Sun's new additions to 1.4.1 specify that the
isHeadless() check will be done on all heavyweight Components that do not
have lightweight peers (the last part of that statement I only somewhat
understand). Now, I have looked into many suggestions (such as the PJA
Toolkit -- which doesn't support java 1.4.2), but none have worked. My
thinking is that if Sun is going to add a special case for Java programmers
who wish to generate images in a headless environment, then they should've
also made a way for Java programmers who wish to generate images from Swing
components (such as realtime charts and graphs) in a headless environment.
I know of no such way, though. And while I have given it the old college
try for the past two-three days, I have yielded no results. Is there
anybody that can connect the dots for me? Show me the way to bypass the
HeadlessException problem and generate a BufferedImage out of a Component?
In this case, code is the best explanation--I've already reviewed the java
tutorials, the sdk specs, the javadocs, and many websites that talk about it
in general. It's the specifics that I am having trouble with.
THANKS TO ALL WHO HELP IN ANY WAY.
--sandman
I've been working on this problem for about 2 days now. Here it is:
I have a servlet programmed up that will operate in a headless environment.
I'm using j2sdk1.4.2 and apache tomcat 4.1.24. I have x-windows installed
on my linux server but it does not run all the time (only when i really need
it). What i want my servlet to do is to create a JButton (or any swing
Component--heavy or lightweight) and convert it to a Buffered Image and then
output that image as a image/png. Here is the code that I have currently
that works fine when I have x-windows running and isHeadless=false:
package graphics;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import javax.swing.*;
public class SwingGeneratorServlet extends HttpServlet
{
// this is the converter method. it throws the exception
public static BufferedImage createImage(Component cmp) {
Dimension d = cmp.getSize();
d.setSize(100, 100);
BufferedImage bi = new BufferedImage((int) d.getWidth(),
(int) d.getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();
//temporary container
JFrame jf = new JFrame();
jf.getContentPane().add(cmp);
jf.pack();
SwingUtilities.paintComponent(g2d, cmp, jf.getContentPane(),
0, 0, (int) d.getWidth(), (int)
d.getHeight());
return bi;
}
// this is the servlet's io method. it generates, converts, then
outputs the image
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
JButton bu = new JButton("Swing Servlet");
BufferedImage bi = createImage(bu);
response.setContentType("image/png");
ServletOutputStream out = response.getOutputStream();
ImageIO.write(bi, "png", out);
out.close();
}
// this just directs to doGet(...); nothing interesting here
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
doGet(request, response);
}
}
Now, when isHeadless=true (regardless of whether I am running x-windows or
not), an exception gets thrown:
HTTP Status 500 -
----------------------------------------------------------------------------
----
type Exception report
message
description The server encountered an internal error () that prevented it
from fulfilling this request.
exception
java.awt.HeadlessException
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:121)
at java.awt.Window.(Window.java:274)
at java.awt.Frame.(Frame.java:401)
at java.awt.Frame.(Frame.java:366)
at javax.swing.JFrame.(JFrame.java:154)
at
graphics.SwingGeneratorServlet.createImage(SwingGeneratorServlet.java:26)
at graphics.SwingGeneratorServlet.doGet(SwingGeneratorServlet.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Application
FilterChain.java:247)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterCh
ain.java:193)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.ja
va:256)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:643)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.ja
va:191)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:643)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180
)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:643)
at
org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.
java:171)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:641)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172
)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:641)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java
:174)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invok
eNext(StandardPipeline.java:643)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:594)
at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConne
ction(Http11Protocol.java:392)
at
org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:565)
at
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.jav
a:619)
at java.lang.Thread.run(Thread.java:534)
----------------------------------------------------------------------------
----
Apache Tomcat/4.1.24
This is to be expected, since Sun's new additions to 1.4.1 specify that the
isHeadless() check will be done on all heavyweight Components that do not
have lightweight peers (the last part of that statement I only somewhat
understand). Now, I have looked into many suggestions (such as the PJA
Toolkit -- which doesn't support java 1.4.2), but none have worked. My
thinking is that if Sun is going to add a special case for Java programmers
who wish to generate images in a headless environment, then they should've
also made a way for Java programmers who wish to generate images from Swing
components (such as realtime charts and graphs) in a headless environment.
I know of no such way, though. And while I have given it the old college
try for the past two-three days, I have yielded no results. Is there
anybody that can connect the dots for me? Show me the way to bypass the
HeadlessException problem and generate a BufferedImage out of a Component?
In this case, code is the best explanation--I've already reviewed the java
tutorials, the sdk specs, the javadocs, and many websites that talk about it
in general. It's the specifics that I am having trouble with.
THANKS TO ALL WHO HELP IN ANY WAY.
--sandman