技術記事については、Qiitaにも稀に投稿しています。

SpringサンプルアプリがMac上で動作しないので試行錯誤してみた

step1

日本語で書かれたSpringフレームワークの書籍というのは、他のフレームワークと比べて稀少。ネットで検索したり、店頭で眺めた結果、とりあえず第一歩という思いで購入した一冊がこちら。

SpringによるWebアプリケーションスーパーサンプル第2版

[amazonjs asin="4797358114" locale="JP" title="SpringによるWebアプリケーションスーパーサンプル 第2版"]

付属のCD-ROMには、本で扱っているサンプルアプリのソースから各種ソフトウェアも入っているという親切設計。例えば、TomcatとかEclipseとか、もちろんSpringも収録。しかしこの本の動作検証環境は、Windows XP Professional SP2とある。

最近はMacをプラットフォームとした書籍も多いけれど、この本はばりばりのWindows環境。序盤はコマンドプロンプトでサンプルを動かすのだけど、Macのターミナル上で同じことをしてもエラーが連発する始末。解決するにも、そこまでのレベルに達していない。

でもなんとか解決できたので備忘録がてら残す。

とりあえずサンプルを動かしてみる

対象のサンプルソースのディレクトリまでいってからantコマンドを叩く。なお、Macには標準でantは入っていないので、事前に「brew install ant」をしているという前提。

$ sudo ant run.sample1
Buildfile: /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/build.xml

init:  
[delete] Deleting directory /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/classes  
[mkdir] Created dir: /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/classes

compile:
[javac] /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/build.xml:21: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 10 source files to /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/classes
[javac] javac: -g:lines, vars, sourceは無効なフラグです
[javac] 使用方法: javac <options> <source files>
[javac] 使用可能なオプションのリストについては、-helpを使用します

BUILD FAILED  
/Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/build.xml:21: Compile failed; see the compiler error output for details.  

エラーの内容から察するに、build.xmlの21行目にあるlinesやらvarsやらsourceやらが無効だから!残念でした!って感じ。この時点でbuild.xmlの内容は理解どころか、開いてすらいないのでまずは眺めてみる。

<target name="compile" depends="init" description="コンパイルします。">
    <javac destdir="${classes.dir}" debug="on" debuglevel="lines, vars, source">
        <src path="${src.dir}"/>
        <classpath refid="classpath"/>
    </javac>
    <copy todir="${classes.dir}">
        <fileset dir="${src.dir}">
            <include name="**/*.xml" />
        </fileset>
    </copy>
</target>

わからないので、コメントアウトしたらどうなるだろうか

さっぱりだ。怪しいのは21行目のlines, vars, sourceなので、コメントアウトしてみる。

<javac destdir="${classes.dir}" debug="on">
<!-- debuglevel="lines, vars, source"> -->

再度、動かしてみる

$ sudo ant run.sample1  
Buildfile: /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/build.xml

init:  
[delete] Deleting directory /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/classes  
[mkdir] Created dir: /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/classes

compile:  
[javac] /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/build.xml:21: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds  
[javac] Compiling 10 source files to /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/classes  
[javac] /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/src/sample2/MessageBeanJa.java:5: エラー: この文字は、エンコーディングUTF8にマップできません  
[javac] System.out.println("����ɂ��́A" + name + "����B");  
// 以下略  

相変わらず正常な動作ではないものの、エラー内容が変わった。しかも今度はコンパイルしようとはしてくれているらしい。問題は当然「この文字は、エンコーディングUTF8にマップできません」という日本語エラー。

対象のファイルはMessageBeanJa.javaと書いてあるので、まずは文字コードを調べてみることにする。

nkfコマンドが使えない

UNIXでファイルの文字コードを調べるなら[nkf -g]としたいところなのだけど、なんとMacには標準で入っていない。ので、入れておく。

こちらのサイトから最新のnkfをダウンロードし、解凍する。

cd nkf-2.1.3  
sudo make  
sudo make perl  
sudo cp nkf /usr/local/bin/  

cd NKF.mod  
sudo perl Makefile.PL  
sudo make  
sudo make test  
sudo make install  

これで[nkf]コマンドが使えるようになるはず。試しに[nkf --help]とか打ってみるとよい。

改めて、文字コードを調べる

結果は以下の通り、エラーが吐かれていたMessageBeanJa.javaはShift_JISの模様。もちろん中身を見ると日本語が使われてる。

nkf -g *  
HelloApp.java: ASCII  
MessageBean.java: ASCII  
MessageBeanEn.java: ASCII  
MessageBeanJa.java: Shift_JIS  

じゃあ、ということで、UTF-8に変換しちゃう。

$ nkf -w --overwrite *

$ nkf -g *  
HelloApp.java: ASCII  
MessageBean.java: ASCII  
MessageBeanEn.java: ASCII  
MessageBeanJa.java: UTF-8  

アスタリスクでやるのはちょっと乱暴な気がするけど、結果はMessageBeanJa.javaがUTF-8になった。

再々度、動かしてみる

$ sudo ant run.sample1  
Buildfile: /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/build.xml

init:  
[delete] Deleting directory /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/classes  
[mkdir] Created dir: /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/classes

compile:  
[javac] /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/build.xml:21: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds  
[javac] Compiling 10 source files to /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/classes

run.sample1:  
Hello, Spring!

BUILD SUCCESSFUL
Total time: 1 second

成功した。build.xmlのコメントアウトした部分の正体を突き止めたい衝動はあるけど、とりあえず先に進むことにする。

ちなみに、日本語が含まれていたJavaファイルを使ったサンプルの動作

ant run.sample2
Buildfile: /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/build.xml

init:
[delete] Deleting directory /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/classes
[mkdir] Created dir: /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/classes

compile:
[javac] /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/build.xml:21: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 10 source files to /Users/Takahiro/Development/workspace-sts-3.4.0.RELEASE/Samples/1-1/classes

run.sample2:
こんにちは、Springさん。

BUILD SUCCESSFUL
Total time: 1 second

おおー。というわけで、ちゃんと日本語で出力されましたとさ。