ホーム   »  スポンサー広告  »     »  Unix/Linux  »  Xvfb - 仮想フレームバッファ

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Xvfb - 仮想フレームバッファ

Java 上で利用できるほとんどの画像操作用ライブラリは Java 標準の AWT をベースにしている。Unix 上で AWT を使用するためには X が起動されていなければならないが、サーバ用途の Unix ではそもそも GUI 環境がインストールされていないこともある。X が起動されていない状態で強引に AWT を利用しようとすれば以下のようなエラーが出るだろう。

torao@cobalt$ java Awt
Exception in thread "main" java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.
        at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
        at sun.awt.X11GraphicsEnvironment.<clinit>(X11GraphicsEnvironment.java:63)
        at java.lang.Class.forName1(Native Method)
        at java.lang.Class.forName(Class.java:134)
        at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:64)
        at java.awt.Window.<init>(Window.java:191)
        at java.awt.Window.<init>(Window.java:233)
        at java.awt.Frame.<init>(Frame.java:318)
        at java.awt.Frame.<init>(Frame.java:297)
        at Awt.<init>(Awt.java:5)
        at Awt.main(Awt.java:9)
torao@cobalt$

もちろんこれは AWT から X にアクセスしようとして失敗しているのが原因だ。サーバ用途のマシンで常に X を立ち上げた状態にしておくというのは非常に無駄な話でもあるわけだが、AWT はサムネールやグラフなどの画像を作成するような場合に必要になってくる。

ここでは Xvfb (X Virtual Frame Buffer / 仮想フレームバッファ) と呼ばれているライブラリを導入してみよう。Xvfb は仮想的な X フレームバッファのみの環境を構築するため、X が起動していないマシンでも X のライブラリを使用するためのものだ。これさえ起動しておけばコンソールだけのサーバマシンでも AWT を使用した画像処理を行うことが出来るようになる。

◆ インストール

大抵の Linux はインストール時に Xvfb を選択することが出来るようになっているが、ほとんどはデフォルトでチェックが外れているので、意図的に入れなければ入ってないだろう。後から入れるのであれば、まずインストールに使用した CD-ROM に Xvfb の RPM が入っていないかを探すのが無難だ。また、最近の Linux では GUI メニューから 「アプリケーションの追加/削除」 でも追加できるようだ。

このほかに XFree86 のサイトからダウンロードすることもできる 。実行環境によっていくつか適切なバージョンがあるようだが、例えば glibc-2.1 を使用しているのであればftp://ftp.xfree86.org/pub/XFree86/4.0.1/binaries/Linux-ix86-glibc21/ から Xvfb.tgz をダウンロードするといった具合だ。このファイルを解凍すると /bin/Xvfb という実行ファイルが作成されるので、これを /usr/X11R6/bin に放り込む。

◆ Xvfb の起動

早速 Xvfb を起動してみよう。コマンドラインから以下のように入力する。

root@sapphire$ export DISPLAY="localhost:1.0"
root@sapphire$ /usr/X11R6/bin/Xvfb :1 -screen 0 1024x768x8 &
[1] 23058
root@sapphire$ PEXExtensionInit: Couldn't open default PEX font file  Roman_M
Could not init font path element /usr/X11R6/lib/X11/fonts/CID/, removing from list!
root@sapphire$

デフォルトのフォントが見つからないというようなエラーが出ているが、どうやら起動したようだ。引き続き本当に AWT が動作するかどうかテストしよう。

テスト用に以下のような画像縮小用 Java アプリケーションを作成した。コマンドライン引数 1 で指定された画像を 100x100 の大きさに縮小して引数 2 のファイルに保存する。もちろんこれは X が起動していなければエラーになってしまう。

public class Jpeg{
    public static void main(String[] args) throws IOException{
        InputStream in = new BufferedInputStream(new FileInputStream(args[0]));
        JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(in);
        BufferedImage img = decoder.decodeAsBufferedImage();
        BufferedImage icon = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
        Graphics g = icon.getGraphics();
        g.drawImage(img.getScaledInstance(100, 100, Image.SCALE_SMOOTH), 0, 0, null);
        FileOutputStream out = new FileOutputStream(args[1]);
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        encoder.encode(icon);
        out.flush();
        out.close();
        in.close();
        return;
    }
}

このアプリケーションを実行したところ、まんまと縮小画像を保存することに成功した。まだフォントの警告が出ているようだが、どうやら X を起動しなくても Xvfb で AWT を利用することが出来るようになったようだ。

root@sapphire$ java Jpeg img.1.jpg img.2.jpg
Warning: Cannot convert string "-watanabe-mincho-medium-r-normal--*-140-*-*-c-*-jisx0208.1983-0" to type FontStruct
PEXExtensionInit: Couldn't open default PEX font file  Roman_M
Could not init font path element /usr/X11R6/lib/X11/fonts/CID/, removing from list!
root@sapphire$ ps aux
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND

root     23058  0.0  0.6  7612 3528 pts/0    S    17:50   0:00 /usr/X11R6/bin/Xvfb :1 -screen 0 1024x768x8

root@sapphire$

プロセスの状態を見るとだいたい 3.5MB 程度で常駐しているようだ。

◆ XVfb の自動起動設定

Xvfb は画像を扱う Java よりも前に起動しておく必要がある。Tomcat などのような常駐型だけでなく、通常の Java アプリケーションでも AWT の機能を利用できるように、Linux の起動と同時に XVfb も起動するように設定してみよう。

Linux マシン上で root ユーザになり /etc/rc.d/init.d/ ディレクトリの直下に xvfb というファイルを作成する。

#!/bin/bash
#
# chkconfig: - 91 35
# description: Starts and stops XVfb. \
#              used to provide virtual frame buffer.

# Source function library.
. /etc/init.d/functions

prog=$"Xvfb"

# Xvfb program
XVFB=/usr/X11R6/bin/Xvfb

start() {
    echo -n $"Starting $prog: "
    daemon /usr/X11R6/bin/Xvfb :1 -screen 0 1024x768x24 &
    echo
}

stop() {
    echo -n $"Shutting down $prog: "
    killproc Xvfb
    echo
}

# See how we were called.
case "$1

ファイルを作成したら実行権限を与えて実際に実行してみよう。

root@sapphire$ chmod 755 xvfb
root@sapphire$ ./xvfb start
Xvfbを起動中:                                              [  OK  ]
root@sapphire$ ps -ef | grep Xvfb
root      3100  3099  0 05:53 pts/0    00:00:00 /usr/X11R6/bin/Xvfb :1 -screen 0
root@sapphire$ ./xvfb stop
Xvfbを停止中:                                              [  OK  ]
root@sapphire$

実行できることが確認できたら chkconfig コマンドを用いてシステム起動時に xvfb が起動するよう設定を行う。chkconfig --list で xvfb がランレベル 3 でオンになっていることを確認。

root@sapphire$ chkconfig --add xvfb
root@sapphire$ chkconfig xvfb on
root@sapphire$ chkconfig --list

xvfb            0:オフ  1:オフ  2:オフ  3:オン  4:オン  5:オン  6:オフ

root@sapphire$

以上でシステム起動時と同時に XVfb を起動するための操作は終了。ここで実際にマシンを再起動してちゃんと起動するかどうか確認を行っておくと良いだろう。

◆ Tomcat シェルの設定

Tomcat から AWT の処理を利用するためには環境変数 DISPLAY を定義しておかなければいけない。Tomcat 4 は /usr/bin/dtomcat4 スクリプトから起動するため、このファイルの先頭に設定を加えておきます。


#
#   JSSE_HOME       (Optional) May point at your Java Secure Sockets Extension
#                   (JSSE) installation, whose JAR files will be added to the
#                   system class path used to start Tomcat.
#
# $Id: index.html,v 1.1 2004/11/04 16:44:05 torao Exp $
# -----------------------------------------------------------------------------
DISPLAY="localhost:1.0"
export DISPLAY


# OS specific support.  $var _must_ be set to either true or false.
cygwin=false
case "`uname`" in
CYGWIN*) cygwin=true;;
esac

◇ 検証環境

JDK 1.4 + Linux+ IA32
 java version "1.4.2_06"
  Java™ 2 Runtime Environment, Standard Edition (build 1.4.2_06-b03)
  Java HotSpot™ Client VM (build 1.4.2_06-b03, mixed mode)
 Fecora Core 3
  2.6.12-1.1381_FC3
 IBM ThinkCentre A50 NN85T55
  Intel® Celeron®  D Processor 335 2.80GHz
  640MB PC-2700 DDR SDRAM
  hda - 40GB 7,200rpm Barracuda ST340014A Ultra IDE/ATA100
  hdd - 120GB 7,200rpm Maxtor 6Y120L0 Ultra IDE/ATA133
  sda - 160GB 7,200rpm Maxtor OneTouch USB/2.0,FireWire
  sdb - 250GB 7,200rpm Maxtor OneTouch USB/2.0,FireWire

※J2SE 5.0 で XAWT の実装が X11 になるべく依存しない方針で修正され、画像の操作程度であれば仮想フレームバッファは必要なくなりました。

コメント
トラックバック
トラックバック URL
コメントの投稿
管理者にだけ表示を許可する
Profile
Takami Torao
Takami Torao
C/C++ 使いだった 1996年、運命の Java と出会い現在に至る。のらアーキテクト。
Yah, this is image so I don't wanna eat spam, sorry!
Search

Google
MOYO Laboratory
Web

カテゴリー
最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
ブロとも申請フォーム
RSSフィード
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。