S(しょーもない)E(エンジニア)さんねんせいの日記 このページをアンテナに追加

2006.08.28 [Mon] Windows→linuxの壁

WinXp + Tomcat localhostアクセスで動かしてたものを,warにしてlinuxサーバに移植.ホホイのホイと動くかと思いきや….

まだまだOSの壁は厚いねぇ〜.

[] linux上でGraphicsを使用した部分で,InternalErrorが発生する問題 15:51  linux上でGraphicsを使用した部分で,InternalErrorが発生する問題を含むブックマーク

Graphicsを使用して,グラフを描く処理が入っているソースをlinux上で動かそうとしたところ,以下のようなエラーが発生.

java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.

sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)

sun.awt.X11GraphicsEnvironment.<clinit>(X11GraphicsEnvironment.java:134)

java.lang.Class.forName0(Native Method)

java.lang.Class.forName(Class.java:141)

java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:62)

java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1041)

(以下略)

回避方法としては,実行時のオプションとして,「-Djava.awt.headless=true」を追加する.

例:

# javac SampleIMGCreate.java

# java -Djava.awt.headless=true SampleIMGCreate

などと書いたものの,単体駆動なんてまずしないだろうから,Tomcatサーバ上で動かしている場合は,Tomcat実行ユーザの環境変数にこのオプションを追加し,Tomcat再起動すれば良い.

# export CATALINA_OPTS="-Djava.awt.headless=true"

参考URLhttp://java.sun.com/j2se/1.4.2/docs/guide/awt/AWTChanges.html#headless

[] linux上でjava.awt.Graphicsを使って表示した日本語が文字化け 15:51  linux上でjava.awt.Graphicsを使って表示した日本語が文字化けを含むブックマーク

先の対処で実行時エラーは解消して,絵が表示されるようになったものの,今度は日本語部分が文字化け.(Windows環境下では問題なかったのに…)

g.drawString()とかで表示する日本語部分が→「□□□」みたいな感じに化けてしまう.

原因は,linuxデフォルトフォントが日本語に対応していないからというもの.

よーするに,Graphicsオブジェクトに対して,どのFontを使うかを明示的に指定しないとダメなのでした.(WindowsではたまたまデフォルトのFontが日本語に対応していただけのハナシ)

指定しない場合はその実行環境デフォルトのFontが採用されてしまう.

というわけで,

  1. その実行環境で対応しているFont一覧を取得
  2. それらのうち日本語表示に対応しているものを見つける
  3. 日本語に対応したFontをGraphicsオブジェクトに指定する

という手順を踏まねばならない.

サンプルは以下のとおり,

(前略)
        //インストールされている全てのFontを取得
        Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();

        //その中から日本語に対応したものを抽出
        ArrayList fontList = new ArrayList();
        for(int i = 0; i < fonts.length; i++){
            if(fonts[i].canDisplay('日')){
                fontList.add(fonts[i]);
            }
        }

        //抽出したFontの中に、MS Gothic(Windowsならたいていあるはず)が入っていればそれを採用,
        //なければ「Kochi Gothic」(linuxに入っている)を採用
        //それもなければ,何でもいいから日本語に対応しているFontを採用
        Iterator itr = fontList.iterator();
        while(itr.hasNext()){
            Font f = (Font)itr.next();
            if(f.getName().equals("MS Gothic")){
                g.setFont(new Font(f.getName(), Font.PLAIN, 12));
                break;
            } else if (f.getName().equals("Kochi Gothic")){
                g.setFont(new Font(f.getName(), Font.PLAIN, 12));
                break;
            } else {
                g.setFont(new Font(f.getName(), Font.PLAIN, 12));
            }
        }
(後略)

これはあくまでもサンプルで,これやるとちょっと処理時間がかかる….


参考までに,手元の環境(WinXP / linux)が対応していたFontと日本語表示対応状況を調べてみたので,その一覧を載せます.

Windows XP SP2の場合 RedHat Linux ES4の場合

Font名日本語対応状況
Arialfalse
Arial Blackfalse
Arial Cursivafalse
Arial Negretafalse
Arial Negreta cursivafalse
Batangtrue
BatangChetrue
Bitstream Vera Sansfalse
Bitstream Vera Sans Boldfalse
Bitstream Vera Sans Bold Obliquefalse
Bitstream Vera Sans Monofalse
Bitstream Vera Sans Mono Boldfalse
Bitstream Vera Sans Mono Bold Obliquefalse
Bitstream Vera Sans Mono Obliquefalse
Bitstream Vera Sans Obliquefalse
Bitstream Vera Seriffalse
Bitstream Vera Serif Boldfalse
Comic Sans MSfalse
Comic Sans MS Negretafalse
Courier Newfalse
Courier New Cursivafalse
Courier New Negretafalse
Courier New Negreta cursivafalse
Dotumtrue
DotumChetrue
Estrangelo Edessafalse
Franklin Gothic Mediumfalse
Franklin Gothic Medium Cursivafalse
Gautamifalse
Georgiafalse
Georgia Cursivafalse
Georgia Negretafalse
Georgia Negreta cursivafalse
Gulimtrue
GulimChetrue
Gungsuhtrue
GungsuhChetrue
Impactfalse
Kartikafalse
Lathafalse
Lucida Bright Demiboldfalse
Lucida Bright Demibold Italicfalse
Lucida Bright Italicfalse
Lucida Bright Regularfalse
Lucida Consolefalse
Lucida Sansfalse
Lucida Sans Demiboldfalse
Lucida Sans Regularfalse
Lucida Sans Typewriter Boldfalse
Lucida Sans Typewriter Regularfalse
Lucida Sans Unicodefalse
Lucida Sans halvfedfalse
Lucida Sans halvfed kursivfalse
Lucida Sans kursivfalse
MS Gothictrue
MS Minchotrue
MS PGothictrue
MS PMinchotrue
MS UI Gothictrue
MV Bolifalse
Mangalfalse
Marlettfalse
Microsoft Sans Seriffalse
NSimSuntrue
OpenSymbolfalse
Palatino Linotypefalse
Palatino Linotype Cursivafalse
Palatino Linotype Negretafalse
Palatino Linotype Negreta cursivafalse
Raavifalse
Shrutifalse
SimHeitrue
SimSuntrue
Sylfaenfalse
Symbolfalse
Tahomafalse
Tahoma Negretafalse
Times New Romanfalse
Times New Roman Negretafalse
Times New Roman Negreta cursivafalse
Times New Roman cursivafalse
Trebuchet MSfalse
Trebuchet MS Cursivafalse
Trebuchet MS Negretafalse
Trebuchet MS Negreta cursivafalse
Tungafalse
Verdanafalse
Verdana Cursivafalse
Verdana Negretafalse
Verdana Negreta cursivafalse
Vrindafalse
Webdingsfalse
Wingdingsfalse
dialog.boldtrue
dialog.bolditalictrue
dialog.italictrue
dialog.plaintrue
dialoginput.boldtrue
dialoginput.bolditalictrue
dialoginput.italictrue
dialoginput.plaintrue
monospaced.boldtrue
monospaced.bolditalictrue
monospaced.italictrue
monospaced.plaintrue
sansserif.boldtrue
sansserif.bolditalictrue
sansserif.italictrue
sansserif.plaintrue
serif.boldtrue
serif.bolditalictrue
serif.italictrue
serif.plaintrue
新細明體true
細明體true

Font名日本語対応状況
Kochi Gothictrue
Kochi Minchotrue
Lucida Bright Demiboldfalse
Lucida Bright Demibold Italicfalse
Lucida Bright Italicfalse
Lucida Bright Regularfalse
Lucida Sans Demiboldfalse
Lucida Sans Demibold Obliquefalse
Lucida Sans Obliquefalse
Lucida Sans Regularfalse
Lucida Sans Typewriter Boldfalse
Lucida Sans Typewriter Bold Obliquefalse
Lucida Sans Typewriter Obliquefalse
Lucida Sans Typewriter Regularfalse
dialogfalse
dialog.boldfalse
dialog.bolditalicfalse
dialog.italicfalse
dialoginputfalse
dialoginput.boldfalse
dialoginput.bolditalicfalse
dialoginput.italicfalse
monospacedfalse
monospaced.boldfalse
monospaced.bolditalicfalse
monospaced.italicfalse
sansseriffalse
sansserif.boldfalse
sansserif.bolditalicfalse
sansserif.italicfalse
seriffalse
serif.boldfalse
serif.bolditalicfalse
serif.italicfalse

Connection: close