Linux系统中缺少GUI设备引起的HeadlessException

时间:2022-08-30 14:56:53
  • 缺少X11显示设置
Exception in thread "AWT-EventQueue-0" java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:159)

解决方案: 在linux的启动文件/etc/profile中增加了 export  DISPLAY=localhost:0

  • 缺少X11GraphicsEnvironment  
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11GraphicsEnvironment
at java.lang.Class.forName0(Native Method)

解决方案: 在java程序启动时候,增加了-DJava.awt.headless=true参数

-DJava.awt.headless=true的作用

对于一个Java服务器来说经常要处理一些图形元素,例如地图的创建或者图形和图表等。

这些API基本上总是需要运行一个X-server以便能使用AWT(Abstract Window Toolkit,抽象窗口工具集)。然而运行一个不必要的X-server并不是一种好的管理方式.

有时你甚至不能运行X-server,因此最好的方案是运行headless服务器,来进行简单的图像处理.

-Djava.awt.headless=true

下面的内容转自 http://www.oschina.net/translate/using-headless-mode-in-java-se

Headless模式是在缺少显示屏、键盘或者鼠标时的系统配置。听起来不可思议,但事实上你可以在这中模式下完成不同的操作,甚至是用图形数据也可以。
哪里才能用到此模式呢?想想你的应用不停的生成一张图片,比如,当用户每次登陆系统是都要生成一张认证图片。
当创建图片时,你得应用既不需要显示器也不需要键盘。让我们假设一下,现在你的应用有个主架构或者专有服务器,但这个服务没有显示器,键盘或者鼠标。
理想的决定是用环境的大量视觉计算能力而不是非视觉特性。在Headless模式下生成的图片可以传递到Headful系统进行更深层次渲染。
在java.awt.toolkit和java.awt.graphicsenvironment类中有许多方法,除了对字体,图像和打印的操作外还有调用显示器,键盘和鼠标的方法。
但是有一些类中,比如Canvas 和 Panel,可以在headless模式下执行。在J2SE 1.4平台之后就提供了对Headless模式的支持。
注:这篇文章重点讲的是Java SE6 平台版本的文档。任何API的增加或其他增强Java SE平台的规范是由JSR270专家组(JSR 270 Expert Group.)的审查和批准。

Toolkit

java.awt.Toolkit类是Abstract Window Toolkit (AWT)的 所有实现类的抽象父类。Toolkit的子类用于把各种AWT组件绑定到特定的本地toolkit实现上去。

如果显示设备,键盘或鼠标不支持的话,很多组件都会受影响。一个合适的类构造器应当抛出一个HeadlessException异常:

Button
Checkbox
Choice
Dialog
FileDialog
Frame
Label
List
Menu
MenuBar
MenuItem
PopupMenu
Scrollbar
ScrollPane
TextArea
TextField
Window

这种重量级的组件需要有一个操作系统级别上对等的图形函数来支持它,在headless的机器上它们将不能正常工作。

与Canvas、Panel和Image组件相关的组件不需要抛出HeadlessException异常,因为这些组件在操作系统级别上的对等图形函数可以使用空函数,
然后作为轻量级组件来处理。一个Headless的toolkit也会把Java组件绑定到本地资源上去,但是它只有在资源中不包含显示设备或输入设备时才会这样做。

Graphics Environment

java.awt.GraphicsEnvironment类是一个抽象类,它描述了在给定平台中,可以在Java技术中使用的由GraphicsDevice对象和Font对象组成的集合。

该GraphicsEnvironment中的资源可以是本地的也可以是远程设备。GraphicsDevice对象可以是显示器,打印机或者图形缓存等,

并且它们是Graphics2D 绘制函数的目标。每一个GraphicsDevice都有许多与之关联的GraphicsConfiguration对象。

这些对象指定了不同的配置环境,在这些配置环境中可以使用GraphicsDevice。

Table 1 显示GraphicsEnvironment 方法,检查Headless模式支持 
Table 1.  Headless 模式方法

方法 描述
public static boolean 
isHeadless()
测试环境是否为headless, 对于是否不支持display  device,keyboard,mouse。如果这个方法returns true,theToolkitandGraphicsEnvironmentclasses 抛出(thrown)依赖于display device, keyboard, mouse的aHeadlessExceptionis异常.
public boolean 
isHeadlessInstance()
Returns  thisGraphicsEnvironmentcan 是否支持dieplay device,keyboard,mouse. 如果这个方法 returns  true,  theGraphicsEnvironmentthat 抛出(throw)一个依赖于 display device, keyboard, mouse的aHeadlessExceptionis 异常.

注意:isHeadless()方法检查特定的系统属性,java.awt.headless而不是系统的硬件配置.

HeadlessException 抛出的代码,这取决于display device、keyboard、mouse在一个环境称为不支持任何这些.

唯一的例外是来自一个UnsupportedOperationException,本身就是来源于一个RuntimeException.

设置 Headless模式

使用Headless模式操作,您必须首先了解如何检查和设置系统属性与此相关的模式。此外,你必须了解如何创建一个默认的工具包使用工具箱的无头实现类.

系统属性配置

为了启用headless模式,需要使用setProperty()方法去设置相应的系统属性。本方法可以让你用期望的值来设置系统属性。

System.setProperty("java.awt.headless", "true");

上面的代码中,java.awt.headless是一个系统属性,true是我们设定的值。

如果你想在一个相同的程序中使用headless和传统环境,你可以使用下面的命令行来完成:

java -Djava.awt.headless=true

创建默认Toolkit

如果名字为java.awt.headless的系统属性被设置为true,那么headless工具包就会被使用。接下来使用getDefaultToolkit()方法来创建一个headless toolkit的实例:

Toolkit tk = Toolkit.getDefaultToolkit();

Headless模式检查

要检查Headless模式的可用性,使用GraphicsEnvironment类的isHeadless()方法:

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
boolean headless_check = ge.isHeadless();

该方法检查java.awt.headless系统属性。如果这个属性有一个为true的值,那么就会从工具包和依赖于一个显示器,键盘,鼠标的GraphicsEnvironment类的区域中抛出一个HeadlessException。

在Headless模式中操作

设置好headless模式并创建一个headless工具包的实例后,您的应用程序可以执行以下操作:

  1. 创建轻量级组件,如Canvas,Panel,和Swing组件,除了top级别.
  2. 收集关于可用的字体、字体指标和字体设置的信息
  3. 设置颜色来渲染文本和图形
  4. 创造和获取图像,为渲染准备图片
  5. 使用java.awt.PrintJob, java.awt.print.*, 和 javax.print.* 类进行打印。
  6. 发出"哔哔"音频。

Canvas(画布)

下面的代码会在屏幕上绘制出一个空白的矩形区域,你可以在上面绘制线条。可以使用Canvas类创建一个新的Canvas组件。

final Canvas c = new Canvas()
{
public void paint(Graphics g)
{
Rectangle r = getBounds();
g.drawLine(0, 0, r.width - 1, r.height - 1);
g.drawLine(0, r.height - 1, r.width - 1, 0);
}
};

Fonts(字体)

这段代码显示了怎么使用Font类画一个文本字符串并设置文字的字体。Graphics对象是用来绘制这个字符串的。

public void paint(Graphics g)
{
g.setFont(new Font("Arial", Font.ITALIC, 12));
g.drawString("Test", 32, 8);
}

Colors

这段代码显示了如何使用指定的红,绿,蓝的值来设置一条线的颜色。Graphics对象是用来绘制这条线的。

public void paint(Graphics g)
{
g.setColor(new Color(255, 127, 0));
g.drawLine(0, r.height - 1, r.width - 1, 0);
}

Images

在下面的代码中,javax.imageio.ImageIO类的使用read()方法对图1所示的grapefruit.jpg文件进行解码,并返回一个缓存图片。

Image i = null;
try
{
File f = new File("grapefruit.jpg");
i = ImageIO.read(f);
}
catch (Exception z)
{
z.printStackTrace(System.err);
}

Print

这段代码演示了如何打印已经准备好的画布,你可以使用paint方法自定义打印机的的默认画面。

PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(new Printable()
{
public int print(Graphics g, PageFormat pf, int pageIndex)
{
if (pageIndex > 0)
{
return Printable.NO_SUCH_PAGE;
} ((Graphics2D)g).translate(pf.getImageableX(),
pf.getImageableY()); // Paint canvas.
c.paint(g); return Printable.PAGE_EXISTS;
}
});

Beep

下面的这段代码展示了如果使用 Toolkit类的beep方法发出嘟嘟声。

Toolkit tk = Toolkit.getDefaultToolkit();
tk.beep();

使用Headless模式简单例子

以下的HeadlessBasics例子运用了文章中描述的所有功能。

要运行这个的例子,需要用javac对下面的代码进行编译。复制grapefruit.jpg图片文件到HeadlessBasics类所在的目录下面。

import java.awt.*;
import java.io.*;
import java.awt.print.*; import javax.imageio.*; public class HeadlessBasics
{
public static void main(String[] args)
{
// Set system property.
// Call this BEFORE the toolkit has been initialized, that is,
// before Toolkit.getDefaultToolkit() has been called.
System.setProperty("java.awt.headless", "true"); // This triggers creation of the toolkit.
// Because java.awt.headless property is set to true, this
// will be an instance of headless toolkit.
Toolkit tk = Toolkit.getDefaultToolkit();
// Standard beep is available.
tk.beep(); // Check whether the application is
// running in headless mode.
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
System.out.println("Headless mode: " + ge.isHeadless()); // No top levels are allowed.
boolean created = false;
try
{
Frame f = new Frame("Frame");
created = true;
}
catch (Exception z)
{
z.printStackTrace(System.err);
created = false;
}
System.err.println("Frame is created: " + created); // No other components except Canvas and Panel are allowed.
created = false;
try
{
Button b = new Button("Button");
created = true;
}
catch (Exception z)
{
z.printStackTrace(System.err);
created = false;
}
System.err.println("Button is created: " + created); // Canvases can be created.
final Canvas c = new Canvas()
{
public void paint(Graphics g)
{
Rectangle r = getBounds();
g.drawLine(0, 0, r.width - 1, r.height - 1);
// Colors work too.
g.setColor(new Color(255, 127, 0));
g.drawLine(0, r.height - 1, r.width - 1, 0);
// And fonts
g.setFont(new Font("Arial", Font.ITALIC, 12));
g.drawString("Test", 32, 8);
}
};
// And all the operations work correctly.
c.setBounds(32, 32, 128, 128); // Images are available.
Image i = null;
try
{
File f = new File("grapefruit.jpg");
i = ImageIO.read(f);
}
catch (Exception z)
{
z.printStackTrace(System.err);
}
final Image im = i; // Print system is available.
PrinterJob pj = PrinterJob.getPrinterJob();
pj.setPrintable(new Printable()
{
public int print(Graphics g, PageFormat pf, int pageIndex)
{
if (pageIndex > 0)
{
return Printable.NO_SUCH_PAGE;
}
((Graphics2D)g).translate(pf.getImageableX(),
pf.getImageableY()); // Paint the canvas.
c.paint(g); // Paint the image.
if (im != null)
{
g.drawImage(im, 32, 32, 64, 64, null);
}
return Printable.PAGE_EXISTS;
}
});
try
{
pj.print();
}
catch (Exception z)
{
z.printStackTrace(System.err);
}
}
}

HeadlessBasics的打印输出。

Headless mode: true
java.awt.HeadlessException
at java.awt.GraphicsEnvironment.checkHeadless(Unknown Source)
at java.awt.Window.<init>(Unknown Source)
at java.awt.Frame.<init>(Unknown Source)
at HeadlessBasics.main(HeadlessBasics.java:24)
Frame is created: false
java.awt.HeadlessException
at java.awt.GraphicsEnvironment.checkHeadless(Unknown Source)
at java.awt.Button.<init>(Unknown Source)
at HeadlessBasics.main(HeadlessBasics.java:39)
Button is created: false

注:出于演示的目的,最初的代码会导致此应用程序抛出2个java.awt.HeadlessExceptions异常。

作为上一种方式的替代,你可以把标准输出信息放到一个文件中,然后把文件打印出来。在这种情况下,使用下面的命令行来运行这个例子:

java HeadlessBasics 2> standard_output.txt

把现有的应用程序转换为Headless模式。

你怎么把现有的应用程序转换为可执行的headless模式?要执行此转换的最有效的方法是分析你的源代码以确定任何的功能都是依赖于Headless模式的。

换句话说,要实现相同的功能,你必须找到那些会抛出HeadlessException异常的类和方法,然后使用独立的headless模式替换这些类和方法。

你可以使用Java SE 6 API说明来判断一个特定的类或方法是否支持headless模式。如果一个特定的组件不支持headless模式,你的程序需要捕获的唯一的异常是HeadlessException。

它会在其它可能的异常之前被抛出。这也是为什么在本节的代码示例"举例: 使用Headless模式"中,没有什么特殊的必要性来捕获其它异常。

你肯定会发现其它有用的方法来使用headless模式带来的好处。我们希望本文能帮你完成此项任务,在Java SE平台中玩出一片新天地。

获取更多信息

AWT Enhancements in J2SE 1.4: Headless Support

J2SE 1.4 platform documentation: HeadlessException

The New Modality API in Java SE 6

The java.awt.Toolkit Class

The java.awt.GraphicsEnvironment Class

Linux系统中缺少GUI设备引起的HeadlessException的更多相关文章

  1. 在Linux系统中使用ntfs、fat32格式的存储设备

    在Linux系统中使用ntfs.fat32格式的存储设备   我们通常使用的移动硬盘或U盘一般都是ntfs或fat32的文件系统,作为一名运维工程师,经常会遇到把移动硬盘或者U盘上的内容拷贝的Linu ...

  2. Linux系统中存储设备的两种表示方法

    转:https://blog.csdn.net/holybin/article/details/38637381 一.对于IDE接口的硬盘的两种表示方法: 1.IDE接口硬盘,对于整块硬盘的两种表示方 ...

  3. Linux系统中的Device Mapper学习

    在linux系统中你使用一些命令时(例如nmon.iostat 如下截图所示),有可能会看到一些名字为dm-xx的设备,那么这些设备到底是什么设备呢,跟磁盘有什么关系呢?以前不了解的时候,我也很纳闷. ...

  4. 用户管理 之 Linux 系统中的超级权限的控制

    在Linux操作系统中,root的权限是最高的,也被称为超级权限的拥有者.普通用户无法执行的操作,root用户都能完成,所以也被称之为超级管理用户. 在系统中,每个文件.目录和进程,都归属于某一个用户 ...

  5. 云服务器 ECS Linux 系统中常见的日志文件介绍

    云服务器 ECS Linux 系统中,日志文件是非常重要的文件,它们记录了很多系统中重要的事.Linux 系统中常见日志文件概述如下: /var/log/cron可以在 cron 文件中检查 cron ...

  6. 理解Linux系统中的load average(图文版)转

    一.什么是load average? linux系统中的Load对当前CPU工作量的度量 (WikiPedia: the system load is a measure of the amount ...

  7. 在Linux系统中修改IP地址

    在Linux系统中,通过编辑网络配置文件,设置系统IP地址,当然要在root权限下执行,具体步骤如下: 1.切换路径到/etc/sysconfig/network-scripts [root@Comp ...

  8. 在 Linux 系统中安装Load Generator ,并在windows 调用方法

    在 Linux 系统中安装Load Generator ,并在windows 调用 由于公司需要测试系统的最大用户承受能力,所以需要学习使用loadrunner.在安装的时候碰到了不少问题,所以写下此 ...

  9. Linux系统中常见文件系统格式

    Windows常用的分区格式有三种,分别是FAT16.FAT32.NTFS格式. 在Linux操作系统里有Ext2.Ext3.Linux swap和VFAT四种格式. FAT16: 作为一种文件名称, ...

随机推荐

  1. WCF添加服务失败一则

    原因是本机开发IIS没有安装HTTPS证书 将红色的字注释掉就好了! <services> <service behaviorConfiguration="basicSer ...

  2. 前端框架——AmazeUI学习

    AmazeUI官网: http://amazeui.org/ 前后台模板下载:链接:链接:http://pan.baidu.com/s/1c2uVfk0 密码:zuva 十大前端框架参考链接:http ...

  3. FileResult,JavaScriptResult,JsonResult

    FileResult:可以响应任意文档的属性,包括二进制格式的数据,eg:图档,pdf,excel,zip,可以传入byte[],文档路径,Stream等不同的属性,让mvc将属性回传给客户端,除此之 ...

  4. 如何获取客户端IP、操作系统、浏览器

    request.getRemoteAddr();//获取IP request.getHeader("User-Agent");//获取操作系统信息.浏览器信息. protected ...

  5. zoj 2760 How Many Shortest Path 最大流

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1760 Given a weighted directed graph ...

  6. String比较

    String str1 = "abc"; String str2 = "abc"; String str3 = new String("abc&quo ...

  7. octopress添加回到顶部按钮

    准备回到顶部的png图片一枚,可以随自己喜好google.分享我的 取名top.png,保存在octopress/source/images/top.png octopress/source/_inc ...

  8. 原生JS编写兼容IE6&comma;7&comma;8浏览器无缝自动轮播&lpar;带按钮切换&rpar;

    项目要求页面兼容IE6,7,8等浏览器,我们可能会遇到这个轮播效果,轮播板块要求:无限循环.自动轮播和手动切换功能,每一次滚动一小格,网上有很多这类插件,例如:swiper等! 但是很多都是不兼容IE ...

  9. (转)get和post的区别

    Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP ...

  10. C罗转会尤文图斯

    皇家马德里头号球星C罗转会意甲尤文图斯,结束了9年的皇马生涯,已获得5座金球奖.