Groovyの@grabってなんぞや?
Groovyで、JNAを使うのに調べたときに、以下のソースがあって
参考にさせてもらった。
Groovy+JNA
@Grab('net.java.dev.jna:jna:3.2.2') import com.sun.jna.*; import com.sun.jna.win32.*; interface CLibrary extends Library { CLibrary INSTANCE = Native.loadLibrary("msvcrt", CLibrary.class); int _chdir(String dir); } CLibrary.INSTANCE._chdir(args[0]) println "pwd".execute().text
が、1つ疑問が残ったので、調べてみた。
1行目の@Grabってなんぞや??
http://docs.codehaus.org/pages/viewpage.action?pageId=138543162
Grapeは、モジュールのバージョン識別に関しては(用語の変更はありますが)、Ivyのやり方に従っています。
* group - モジュールが所属するモジュールグループ。MavenのgroupIdやIvyのOrganizationに相当。/groovy[x][\..*]^/ にマッチするグループは予約されていて、Groovyの標準モジュールとして特別な意味を持つ場合がある。
* module - ロードするモジュールの名前。MavenのartifactIdやIvyのartifactに相当。
* version - 利用するモジュールのバージョン。'1.1-RC3' のようなリテラルバージョンかIvyの範囲。例えば '[2.2.1,)' はバージョン2.2.1以降の意味。
ダウンロードされたモジュールは、キャッシュルート ~/.groovy/grape の下に、Ivyの標準メカニズムに従って保存されます。
使用方法
アノテーション
アノテーションが許されている場所であればどこでも、いくつでもgroovy.lang.Grabアノテーションを付けて、そのコードが特定のライブラリに依存していることをコンパイラに知らせることができます。これは、Groovyコンパイラのクラスローダにそのライブラリを追加する効果があります。このアノテーションは、スクリプト内の他のあらゆるクラス解決に先だって検出・評価されるので、@Grabアノテーションによって取り込まれたクラスも適切に解決されます。
import com.jidesoft.swing.JideSplitButton
@Grab(group='com.jidesoft', module='jide-oss', version='[2.2.1,2.3.0)')
public class TestClassAnnotation {
public static String testMethod () {
return JideSplitButton.class.name
}
}
対象クラス(スクリプト要素へのアノテーションの場合はScriptクラス)のstaticイニシャライザに、適切な grab(...) 呼び出しが追加されます。
ふむふむ
こんな感じか?
import com.sun.jna.*; import com.sun.jna.win32.*; @Grab(group='net.java.dev.jna', module='jna', version='3.2.7') println org.codehaus.groovy.runtime.InvokerHelper.getVersion()
結果はエラー・・・・
[D:\workspace\groovy_SandBox]groovy GrabAnnotation.groovy org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, D:\workspace\groovy_SandBox\GrabAnnotation.groovy: 30: unexpected token: println @ line 30, column 1. println org.codehaus.groovy.runtime.InvokerHelper.getVersion() ^ 1 error
おろ?
こうか??
@Grab(group='net.java.dev.jna', module='jna', version='3.2.7') import com.sun.jna.*; import com.sun.jna.win32.*; println org.codehaus.groovy.runtime.InvokerHelper.getVersion()
結果はエラー・・・・
[D:\workspace\groovy_SandBox\]groovy GrabAnnotation.groovy org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, D:\workspace\groovy_SandBox\GrabAnnotation.groovy: 27: unexpected token: import @ line 27, column 1. import com.sun.jna.*; ^ 1 error
あれ??
なんか構文間違ってる?@grabを抜かす
import com.sun.jna.*; import com.sun.jna.win32.*; println org.codehaus.groovy.runtime.InvokerHelper.getVersion()
結果は正しく動く
[D:\workspace\groovy_SandBox]groovy GrabAnnotation.groovy 1.6.5
Groovy 1.7.5だと?
import com.sun.jna.*; import com.sun.jna.win32.*; @Grab(group='net.java.dev.jna', module='jna', version='3.2.7') println org.codehaus.groovy.runtime.InvokerHelper.getVersion()
結果はエラー・・・
1.7.5 [D:\workspace\groovy_SandBox]groovy GrabAnnotation.groovy org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: D:\workspace\groovy_SandBox\GrabAnnotation.groovy: 31: unexpected token: println @ line 31, column 1. println org.codehaus.groovy.runtime.InvokerHelper.getVersion() ^ 1 error
ダメじゃん
(最初に戻す)@grabが先ならどうだ?
@Grab(group='net.java.dev.jna', module='jna', version='3.2.7') import com.sun.jna.*; import com.sun.jna.win32.*; println org.codehaus.groovy.runtime.InvokerHelper.getVersion()
うーむ動いた。 ( ̄Д ̄;;
[D:\workspace\groovy_SandBox]groovy GrabAnnotation.groovy 1.7.5
1.6.5で確認
1.7.5で動作した以下のソースを1.6.5で確認してみる。
@Grab(group='net.java.dev.jna', module='jna', version='3.2.7') import com.sun.jna.*; import com.sun.jna.win32.*; println org.codehaus.groovy.runtime.InvokerHelper.getVersion()
おかしいな@grabが対応されたのは、1.6のはずだし。。。
1.6.5のバグ??
1.6.5で確認
1.6系で確認してみる。
バージョン | 結果 |
---|---|
1.6.0 | エラー |
1.6.1 | エラー |
1.6.2 | エラー |
1.6.3 | エラー |
1.6.4 | エラー |
1.6.5 | エラー |
1.6.6 | エラー |
1.6.7 | エラー |
1.6.8 | エラー |
1.6.9 | エラー |
・・・( ̄. ̄;)エット( ̄。 ̄;)アノォ( ̄- ̄;)ンー なにか間違ってる??
grape listで確認
grape listってので確認が出来るみたい。
[D:\workspace\groovy_SandBox]groovy -v Groovy Version: 1.6.5 JVM: 1.6.0_12 [D:\workspace\groovy_SandBox]grape list net.java.dev.jna jna [3.2.5, 3.2.7] 1 Grape modules cached 2 Grape module versions cached
[D:\workspace\groovy_SandBox]groovy -v Groovy Version: 1.7.5 JVM: 1.6.0_12 [D:\workspace\groovy_SandBox]grape list net.java.dev.jna jna [3.2.5, 3.2.7] 1 Grape modules cached 2 Grape module versions cached
( ̄ー ̄?).....??ありゃ??よく分からん。
Groovy 1.7.5で続きを試す
シングルクォートが正式っぽいが、ダブルクォートでもよさそう
@Grab(group='net.java.dev.jna', module='jna', version='3.2.7') @Grab(group="net.java.dev.jna", module="jna", version="3.2.7")
XXX以降と指定する場合
@Grab(group='net.java.dev.jna', module='jna', version='[3.2.7,)')
1.7.5で追加された短縮記法(シンタックスシュガー)
@Grab('net.java.dev.jna:jna:3.2.7') @Grab('net.java.dev.jna:jna:[3.2.7,)')
1.7系の書き方はわかった。
どなたか、Groovy 1.6系での@grab使い方についてコメントください。m(_ _)m
実行環境
- OS:Windows XP
- Groovy Version: 1.6.0〜1.6.9、1.7.5
- JVM: 1.6.0_12
Groovyの詳細についてはJavadocと以下の書籍を参考にしている。
Groovyイン・アクションを読むならあった方が便利かな。
薄い本は「ほんたった」で立ててる