2010年5月10日月曜日

Groovyのファイル名ハマりどころメモ

ちょっと焦ったのでメモ。

その1:
groovyスクリプトを書くとき、たとえば
println('Hello, World!')
とだけ書いて、ファイル名を「これは最初のスクリプトだから……」とか思って
01_println.groovy
とつけて実行すると、
Caught: java.lang.ClassFormatError: Illegal class name "01_println" in class file 01_println
というエラーが出て動かない。
groovyはいったんJavaのクラスとしてコンパイルされてから実行される。その際ファイル名のクラスが作られるので、ファイル名の頭文字が数字だと動かない。

その2:
groovyスクリプト内にclassを書く時、
class Test {
def name = 'kanemu'
}

def test = new Test()
println test.name
のようなスクリプトを書いたとして、ファイル名を
Test.groovy
にすると、
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
/Users/kanemu/Desktop/groovytest/Test.groovy: 1: Invalid duplicate class definition of class Test : The source /Users/kanemu/Desktop/groovytest/Test.groovy contains at least two definitions of the class Test.
One of the classes is a explicit generated class using the class statement, the other is a class generated from the script body based on the file name. Solutions are to change the file name or to change the class name.
@ line 1, column 1.
class Test {
^

1 error
のようなエラーが出て、動かない。
これも上と同じ理由で、いったんJavaクラスとして実行される際、ファイル名をとってTest.classを作っているので、スクリプト内のTestクラスとかぶってエラーが出てる。
中で使うクラス名と、ファイル名は別にしておかないといけない。

うーん、これはちょっとどうかと思うよ。

2 件のコメント:

ksky さんのコメント...

その2は非常にありがちな落とし穴ですよね。よくやります。最近はエラーメッセージがわかりやすいんでまだましになりましたが...

fumokmm さんのコメント...

その2への対処方法として私はScalaでスクリプトとして書くときのファイル名のルールを、Groovyでスクリプトとして書くときにもよく使っています。

ルールは単純にJavaのメソッド名の規約に従ったファイル名にすることです。
たとえば test.groovy なら今回のその2は動きます。単語が多くなってきたら testHogeHoge.groovy みたいにするといった感じです。

これならクラス名は大文字で始めるという命名に従っていれば名前はかぶらない。