kagamihogeの日記

kagamihogeの日記です。

JCommanderでJavaのコマンドライン引数をパースする

http://jcommander.org/

Javaプログラム実行時のコマンドライン引数をパースするライブラリ。引数の値はプロパティに格納され、引数の各値とプロパティとの関連付けはアノテーションで指定する。

環境

説明

準備

<dependency>
    <groupId>com.beust</groupId>
    <artifactId>jcommander</artifactId>
    <version>1.48</version>
</dependency>

概要

以下はJCommanderのOverviewのサンプルコードから、実行に必要最小限必要な部分のみ抜粋してきたもの。

package kagamihoge.expr.jcommanderexpr;

import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;

public class Main2 {

    public static void main(String[] args) {
        Argument arg = new Argument();
        String[] argv = { "-log", "2"};
        JCommander jc = new JCommander(arg, argv);
        
        System.out.println("-log:" + arg.verbose);
    }

    public static class Argument {
        @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity")
        private Integer verbose = 1;
    }

}

コマンドライン引数の各値と自前定義クラスのプロパティは対応関係にある。対応関係の設定はアノテーション@Parameterで行う。上記の例では-logもしくは-verboseの値はArgumentクラスのverboseプロパティに関連付けられている。

コマンドライン引数のパースは、JCommanderコンストラクタに引数の文字列と対応関係を定義したクラスのインスタンスを渡すことで実行される。上記の例では、実際のコマンドライン引数(いわゆるString[] args)ではなく、簡易的に文字列配列を作り-log 2相当の引数として実行している。

結果として、上記プログラムの実行結果は-log:2と表示される。

Overviewの抜粋

以下はJCommanderのOverviewのサンプルコードから抜粋したもの。上で書いたものより、もうちょい詳しい使い方について。

package kagamihoge.expr.jcommanderexpr;

import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;

public class Main3 {

    public static void main(String[] args) {
        Argument arg = new Argument();
        String[] argv = {"-groups", "unit", "-debug", "-password"};
        JCommander jc = new JCommander(arg, argv);
        
        System.out.println("log:" + arg.verbose + " groups:" + arg.groups + " debug:" + arg.debug + " password:" + arg.password);
        jc.usage();
    }

    public static class Argument {
        @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity")
        private Integer verbose = 1;

        @Parameter(names = "-groups", description = "Comma-separated list of group names to be run")
        private String groups;

        @Parameter(names = "-debug", description = "Debug mode")
        private boolean debug = false;
        
        @Parameter(names = "-password", description = "Connection password", password = true)
        private String password;
    }
}

上記プログラムを実行すると以下のような結果がコンソールに表示される。

Connection password: asd
log:1 groups:unit debug:true password:asd
Usage: <main class> [options]
  Options:
    -debug
       Debug mode
       Default: false
    -groups
       Comma-separated list of group names to be run
    -password
       Connection password
    -log, -verbose
       Level of verbosity
       Default: 1

booleanのプロパティとして-debugを定義しており、これは引数にその要素があればtrue、なければfalseとなる。

@Parameterアノテーションの値にpassword = trueを設定しており、また、引数に-passwordを指定している。こうすると、Connection password:のように、プロンプトで入力を求められるようになる。

デフォルト値を指定したい場合は、その値で初期化しておけばよい。上記の例では引数に-logは指定していないが、初期化値である1が表示されている。もっと複雑な方法は14 - Default valuesを参照。

最後に、JCommander#usage()とすると、使用法として@Parameterアノテーションdescriptionの文字列などが表示される。

参考