2008年10月12日日曜日

やさしいJavaとGroovy

Groovyの勉強をはじめたが、Groovyの本や解説サイトには「まずGroovyとJavaとの違いから」「Javaの基本的知識はあるものとして説明」という言葉だらけになっている。
自分はJava素人なので、まずJavaから勉強することにした。

用意した本は、会社にあった「やさしいJava 第3版」、「Groovyイン・アクション」の2冊。
まず、やさしいJavaのサポートページから、サンプルコードをダウンロードする。

やさしいJavaのサンプルコードを開けてみると、文字コードがShift-JISになっている。
会社で支給されているテキストエディタはTextMate。日本語化してもUTF-8しか表示できない。
なので、全部UTF-8に変換する。
Mac用でテキストエンコードの一括変換できるソフトで、MultiTextConverterというのがあったのでそれを使用。

なんかエラーが出て、全部を変換できない……。
しょうがないので1フォルダづつ変換して、上手くいかないものはJedit Xで開いて別名保存。

無事全てをUTF-8にできたので、iTermを立ち上げ、サンプルコードのディレクトリへ行く。
自分はルート以下に/work/projects/ディレクトリを作って入れている。

$ cd /work/projects/YJSample/
$ mate .



TextMateが立ち上がって、メニュー表示される。OK。

次、Javaの設定。
JavaはMacに標準でインストールされるので、「パスを通す」。この言葉は始めの頃ずいぶん悩んだけど、要はシェルで使えるようにする事なんだと気づいて納得した。

ホームディレクトリにある.bash_profileに以下を記述する。

export JAVA_HOME=/Library/Java/Home
export PATH=$JAVA_HOME/bin:$PATH


iTermから

$ java -version
java version "1.5.0_16"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b06-275)
Java HotSpot(TM) Client VM (build 1.5.0_16-132, mixed mode, sharing)


これでOK。

次、Groovyのインストールと設定。
groovyのdownloadページから最新のgroovyをダウンロードしてきて展開。
こういうのは/opt/ディレクトリを作って入れているので、そこに入れる。
パスを通す。.bash_profileに以下を記述。

export GROOVY_HOME=/opt/groovy-1.5.6
export PATH=$GROOVY_HOME/bin:$PATH


iTermから

$ groovy -version
Groovy Version: 1.5.6 JVM: 1.5.0_16-132


OK。

javacをやってみる。

$ cd /work/projects/YJSample/01
$ javac Sample1.java
Sample1.java:5: #x##:###̕####́A#G###R#[#f#B###O SJIS #Ƀ}#b#v#ł##܂######
System.out.println("ようこそJavaへ?#?");
^
Sample1.java:5: #x##:###̕####́A#G###R#[#f#B###O SJIS #Ƀ}#b#v#ł##܂######
System.out.println("ようこそJavaへ?#?");
^
#x## 2 ###
$ java Sample1
ようこそJavaへ?#?


なんか文字が化ける。。。iTermの表示はちゃんとUTF-8にしてある。

たくさんぐぐって調べると、どうもjavacはエンコーディングを明示しないとOSのデフォルト・エンコーディングで変換する様子。MacはSJISになっていて、OSのデフォルトは変更できないっぽい。
ここに書いてある方法をもとに、エンコードを指定してやってみる。

$ javac -encoding UTF-8 Sample1.java
$ java -Dfile.encoding=UTF-8 Sample1

ようこそJavaへ!

次はgroovycを試す。
試しにSample1g.groovyを書いて、以下のようにする。

println "ようこそGroovyへ!"


これをgroovycしてみる。

$ groovyc Sample1g.groovy
$ java -cp $GROOVY_HOME/embeddable/groovy-all-1.5.6.jar: Sample1g
ようこそGroovyへ?#?


javacの時と同じことが起こっているので、encodingを指定する。

$ groovyc --encoding UTF-8 Sample1g.groovy
$ java -Dfile.encoding=UTF8 -cp $GROOVY_HOME/embeddable/groovy-all-1.5.6.jar: Sample1g
ようこそGroovyへ!


毎回javacとgroovycのときに同じ事を書くのはめんどいので、.bash_profileにエイリアスを書く。

alias javac="javac -encoding UTF-8"
alias groovyc="groovyc --encoding UTF-8"
alias java="java -Dfile.encoding=UTF8 -cp $GROOVY_HOME/embeddable/groovy-all-1.5.6.jar:"


これで、JavaとGroovyを完全に同じに扱えるようになった。※追記2で変更↓

追記:
ひとつ問題発見。コンパイルじゃなく.groovyをそのまま走らせようとすると、

$ groovy Sample1g.groovy
ようこそGroovyへ?#?


という風に化ける。ああ、こっちもUTF指定しなきゃだめかと思い、

$ groovy -c UTF8 Sample1g.groovy
#悤####Groovy#ցI


はいい?もしやと思いiTermの表示をS-JISにしてみると

$ groovy -c UTF8 Sample1g.groovy
ようこそGroovyへ!


groovyコマンドは内部でコンパイルしてるわけだから、groovyc→javaってやってるわけで、→javaのときにエンコード指定を拾ってない???

追記2:
そもそも、Javaの思想に「一度書いたらどこでも動く」てのがあるわけで、各プラットフォームがそれぞれ別のデフォルトエンコーディングを持っていたら、そのエンコーディングに合わせて動かなくちゃいけない。そのためにJavaの内部的には文字コードは全てUnicodeで持っていて、各プラットフォームごとに合わせているらしい。

それを考えると、groovyコマンドがコンパイル時にだけエンコードを指定できて、中身のJavaバイトコードはUnicodeで持ち、出力はデフォルトプラットフォームに合わせる、って動きなのも合ってるような気がしてきた。

なので、iTermの画面はShift-JIS表示にして、Javaコマンドのエイリアスからは-Dfile.encoding=UTF8の指示は取る。残った.bash_profileのエイリアスは

alias javac="javac -encoding UTF-8"
alias groovyc="groovyc --encoding UTF-8"
alias java="java -cp $GROOVY_HOME/embeddable/groovy-all-1.5.7.jar:"
alias groovy="groovy -c UTF-8"


この状態で運用することに決定。
疲れた……。

追記3:2008年11月23日
さらに追記。
MacOSX 10.5で、この条件で動かしたら文字が化ける!
Mac OS 10.5で、論理工房のJava関連4Dプラグイン
Apple社のJavaバーチャルマシンでは、Mac OS 8〜10.4まで、デフォルトの文字エンコーディングとして「Shift_JIS」が採用されていましたが、Mac OS 10.5では、「UTF-8」が採用されています。

おぉ…。

そういうわけで、
・プログラムのエンコードをUTF8に統一するには、上記のエイリアスを記述する
・ターミナルコンソールは、10.4以前はShift-JIS、10.5以降はUTF8表示にする
で、こんどこそOKです。あしからず。

追記4:2010年5月11日
Java6からは、デフォルトエンコーディングがShift-JISに戻ってるみたいです。
Appleの意図がわからない……。
Groovyのエンコード設定については、@uehajさんが以下のページで詳しく書いてくれています。
groovyでスクリプトのエンコーディングを指定する - Grな日々(uehajの日記)
結論としては、/bin/startGroovy(.bat) に
export JAVA_OPTS='-Dgroovy.source.encoding=UTF-8 -Dfile.encoding=UTF-8'

の1行を書き加えるのがいいようです。

0 件のコメント: