主  题:  分享一下,linux下在servlet中使用java.awt.*对象的解决办法
作  者:  MarsZ (夜夜夜夜) 
等  级:   
信 誉 值:  94
所属论坛:  Java JSP/Servlet/JavaBean
问题点数:  0
回复次数:  5
发表时间:  2004-03-29 15:57:04



前几天自己碰上的一个问题


代码和Exception如下:


/**
* AuthorityGenerator.java 
*/


import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import java.awt.*;
import Acme.JPM.Encoders.GifEncoder;


public class AuthorityGenerator extends HttpServlet {
  private static final String CONTENT_TYPE = “image/gif”;
  //Initialize global variables
  public void init() throws ServletException {
  }
  //Process the HTTP Get request
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ServletOutputStream out = response.getOutputStream();


    Frame frame = null ;
    Graphics g = null;


    Random random = new Random();
   
    /* background RGB */
    int bgr = Integer.parseInt(request.getParameter(“bgr”));
    int bgg = Integer.parseInt(request.getParameter(“bgg”));
    int bgb = Integer.parseInt(request.getParameter(“bgb”));
    /* foreground RGB */
    int fgr = Integer.parseInt(request.getParameter(“fgr”));
    int fgg = Integer.parseInt(request.getParameter(“fgg”));
    int fgb = Integer.parseInt(request.getParameter(“fgb”));


    String text = request.getParameter(“text”);
    String fontName = request.getParameter(“fontName”);
    int fontSize = Integer.parseInt(request.getParameter(“fontSize”));



    try{
      frame = new Frame();
      frame.addNotify();


      Image image = frame.createImage(100, 100);
      g = image.getGraphics();


      g.setColor(new Color(bgr, bgg, bgb));
      g.fillRect(0, 0, image.getWidth(frame), image.getHeight(frame));
      for(int i=0; i<image.getWidth(frame);i++){
        int x = random.nextInt(100);
        int y = random.nextInt(100);
        g.setColor(new Color(random.nextInt()));
        g.fillRect(x, y, 1, 1);
      }
      g.setColor(new Color(fgr, fgg, fgb));
      g.setFont(new Font(fontName, Font.PLAIN, fontSize));
      g.drawString(text, 2, 100);


      response.setContentType(CONTENT_TYPE);
      GifEncoder encoder = new GifEncoder(image, out);
      encoder.encode();
    }finally{
      if(g!=null) g.dispose();
        if(frame != null) frame.removeNotify();
    }


  }
  //Clean up resources
  public void destroy() {
  }
}


/**
* exceptions
*/


java.lang.NoClassDefFoundError
 at java.lang.Class.forName0(Native Method)
 at java.lang.Class.forName(Class.java:141)
 at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:62)
 at java.awt.Window.init(Window.java:231)
 at java.awt.Window.<init>(Window.java:275)
 at java.awt.Frame.<init>(Frame.java:401)
 at java.awt.Frame.<init>(Frame.java:366)
 at listener_test.AuthorityGenerator.doGet(AuthorityGenerator.java:46)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:126)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:103)
 at com.caucho.server.http.FilterChainServlet.doFilter(FilterChainServlet.java:96)
 at com.caucho.server.http.Invocation.service(Invocation.java:315)
 at com.caucho.server.http.CacheInvocation.service(CacheInvocation.java:135)
 at com.caucho.server.http.RunnerRequest.handleRequest(RunnerRequest.java:346)
 at com.caucho.server.http.RunnerRequest.handleConnection(RunnerRequest.java:274)
 at com.caucho.server.TcpConnection.run(TcpConnection.java:139)
 at java.lang.Thread.run(Thread.java:534)


网上找了很久,很多类似问题但没有得到解决,基本上都是说加入系统环境变量
System.setProperty(“java.awt.headless”, “true”);
但也无效,最后解决的办法是首先linux要安装xwindow并启动,然后在系统环境变量中加入DISPLAY(这个是Xserver的地址)
> vi /etc/profile


加入
DISPLAY=127.0.0.1:0.0
export DISPLAY


然后就没问题了


回复人: ganh(水水水) ( ) 信誉:105  2004-03-31 15:10:00  得分:0
 
 
  你这个还是要安装 xwindows ,并不是很好的方法。加入系统环境变量的方法你们用错了。
我记得还是我最早在csdn中提出这个问题并解决了。当初也是到处找资料,最后在sun的bug列表中找到的。我的解决方法如下。
1:将jdk升级为jdk1.4,然后在java命令后加上运行参数 –Djava.awt.headless=true 即可,java xxxx.class -Djava.awt.headless=true 。
2:虚拟一个图形环境。一般在linux下使用Xvfb来虚拟一个图形环境,在linux命令行键入Xvfb :0 -screen 0 1024×768x16 & ,不过在使用之前要对Xvfb进行设置。我在本机上没有调试成功。各位可以试一下。
3:使用第三方工具包。可以使用 pja包,下载地址 http://www.eteks.com/pja/en/#Download ,使用方法见解决方案。


解决方案:将pja.jar ,pjatools.jar拷贝到weblogic的lib目录下,在startWebLogic.sh中将这两个文件加入到CLASSPATH中,然后将以下文字加入到$JAVACMD中,其中
/usr/java/jdk1.3.1_06 是指java的安装目录
/home/weblogic/wlserver6.1/lib 是指 pja.jar ,pjatools.jar的存放目录


-Xbootclasspath/a:/usr/java/jdk1.3.1_06/lib/rt.jar:/home/weblogic/wlserver6.1/lib/pja.jar -Djava.awt.toolkit=com.eteks.awt.PJAToolkit -Djava.awt.graphicsenv=com.eteks.java2d.PJAGraphicsEnvironment -Djava.awt.fonts=/usr/java/jdk1.3.1_06/jre/lib/fonts



添加后执行会出现一些说 font找不到的提示,不用理他。



讨论:这个问题在java中称为headless问题,是jdk1.3的bug,bug报告见http://developer.java.sun.com/developer/bugParade/bugs/4281163.html 。jdk1.4已经做了修正,文档见http://java.sun.com/j2se/1.4.1/docs/guide/awt/AWTChanges.html
我对这个问题的理解:headless是指由于一些服务器(比如大型机)运行的环境比较特殊,不存在真实的设备去处理一些输入输出,比如显卡,键盘鼠标;这时就需要虚拟一些运行环境出来,或者就不要用到这些设备的相关操作(比如输入输出)。然而运行java.awt包又需要一个的图形环境,由此产生了异常。


 
 
回复人: MarsZ(夜夜夜夜) ( ) 信誉:94  2004-04-01 10:05:00  得分:0
 
 
  thx, 我想启动xwindow也不是个好办法,但只通过加运行时加-Djava.awt.headless=true在application得时候顶用,但在servlet得时候依然报错,准备试试2、3种方法
 
 
回复人: MarsZ(夜夜夜夜) ( ) 信誉:94  2004-04-01 11:47:00  得分:0
 
 
  哭了pja不支持j2se1.4.1


PJA supports JDK 1.4.0 but doesn’t support JDK 1.4.1 at this time (unless you directly instantiate PJAImage class and don’t use java.awt.Font class). As the exception suggests, the main reason is that Sun added the following method in sun.java2d.SunGraphicsEnvironment class :
protected abstract sun.awt.FontProperties createFontProperties();
and this method isn’t implemented in com.eteks.java2d.PJAGraphicsEnvironment.
The sun.awt.FontProperties object this method is supposed to return is a JDK 1.4.1 new class that has plenty of remarks :
REMIND: remove this method and references to it from the next feature release
You can guess, this isn’t really motivating with such remarks to modify com.eteks.java2d.PJAGraphicsEnvironment to allow it to support JDK 1.4.1 !


Do you really need support for JDK 1.4.1 or are you just trying it ?
By the way, did you try to set the java.awt.headless System property to true and see if the new headless system works for your classes without PJA ?


 
 
复人: ganh(水水水) ( ) 信誉:105  2004-04-01 12:56:00  得分:0
 
 
  在servlet中也是可以使用-Djava.awt.headless=true 的。要针对不同的jsp服务器进行设置。如果使用weblogic的话,在Weblogic启动脚本中的$JAVACMD $JAVA_OPTIONS 后面加入-Djava.awt.headless=true 就可以了。几乎所有的中间件服务器都是使用java编写的,服务器启动时就是需要运行java的。tomcat 也试过,没有问题。
 
 
回复人: MarsZ(夜夜夜夜) ( ) 信誉:94  2004-04-01 14:39:00  得分:0
 
 
  嗯我是白痴。。我在servlet里得init方法中加了
System.setProperty(“java.awt.headless”, “true”);
结果不行


用得Resin,其实在resin的httpd.sh中把
args=”-Djava.awt.headless=true”
加上就行了