Wednesday, May 9, 2012

InvokedynamicでGroovyライフをリスタートしよう

Groovyは5/7にリリースされたバージョン2.0 beta 3でinvokedynamic (indy)に対応しました。これはindyであなたのGroovyライフをリスタートする方法をお見せするだけの短い投稿です。Indyはダイナミックなメソッド呼び出しのためのJava SE 7の新たなバイトコード命令です。もしあなたがindyについて知らないのであればJSRを読んでください。

さぁ、では始めましょう。まずはindyに対応したバージョンのGroovyをインストールしてください。現時点(2.0 beta 3)ではindyはデフォルトで対応されていないためです。次のいずれかの方法が選べます。

* アーカイブをダウンロードしてlib/内のgroovy.jarあるいはembeddable/内のgroovy-all.jarの代わりにindy/にあるgroovy-indy.jarかgroovy-all-indy.jarを使う。

* indyを有効にするオプションを使ってソースからビルドする

ant install -DuseIndy=true -DskipTests=true

2番目に、あなたの目的に応じた方法で次のようにindyを有効にするオプションを付けてコンパイルします:

* groovy

groovy --indy YourScript.groovy

* groovyc

groovyc --indy YourScript.groovy

* GroovyShell class

import org.codehaus.groovy.control.CompilerConfiguration

def conf = new CompilerConfiguration()
conf.optimizationOptions.indy = true
def shell = new GroovyShell(conf)
shell.evaluate(/* your script */)

これだけです! それでは良いGroovyライフを!

Friday, May 4, 2012

Exploring JavaFX 2 - アプリケーションパラメタへのアクセス

JavaFXはApplicationクラスオブジェクトからアプリケーションパラメタにアクセスする方法としてApplication.getParameters()を提供します。例えば、ユーザがGNU形式でオプション(名前付きパラメタ)に幅と高さ、引数(名前なしパラメタ)にメッセージを指定すれば:
java AccessApplicationParametersDemo --width=200 --height=100 hello
アプリケーションは次のようにパラメタを受け取れます:
public class AccessApplicationParametersDemo {

    public static void main(String[] args) {
        Application.launch(UsingGetParametersApplication.class, args);
    }

}
public class UsingGetParametersApplication extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Map opts = getParameters().getNamed();
        System.out.println("width=" + opts.get("width"));
        System.out.println("height=" + opts.get("height"));
        
        List args = getParameters().getUnnamed(); 
        System.out.println("message=" + args.get(0));
    }

}
但しgetParameters()は今のところ(v2.2-b06)オプションのパーサが貧弱で使い勝手がよくありません。省略オプションやPOSIX形式に対応してなく、次の形式のどれも扱えません:
-w=200 -h=100
--width 200 --height 100
-w 200 -h 100
getParemters()をカスタマイズすればいいでしょうか?しかし実装クラスへのアクセスが中でハードコードされていて、メソッドがfinalだと聞いたらどうでしょう?つまりgetParameters()から直接オプションや引数を取得するのは今のところ良い選択ではありません。getParameters()には運搬役に徹してもらい、主な作業はApache Commons CLIに任せるのがお勧めです:
public class UsingCommonsCliApplication extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Options options = new Options();
        options.addOption("w", "width", true, "");
        options.addOption("h", "height", true, "");
        CommandLineParser parser = new PosixParser();
        CommandLine cmd = parser.parse(
            options, 
            getParameters().getRaw().toArray(
                new String[getParameters().getRaw().size()]
            )
        );
        System.out.println("width=" + cmd.getOptionValue("width")); 
        System.out.println("height=" + cmd.getOptionValue("height")); 
        System.out.println("message=" + cmd.getArgList().get(0));
    }

}
この問題に対するJavaFXチームからの回答は"将来のバージョンでは検討可能"ということなのでそのうち解消されるかもしれません。そもそもこのような機能はパラメタを固定された形式で受けとるAppletやJWSでのみ必要とされるはずなので、JavaFXはAppletApplicationやJWSApplicationのような各環境用のクラスを持ち、それらにのみこの機能を持たせる方が良さそうです。