Commons CLIとArgs4jを比べてみる
JavaでCUIツールを作成するとき、Commons CLIとArgs4jというライブラリがあります*1。
で、どっちを使うのがいいの?ということがあると思いますので、それぞれの特徴を述べたいと思います。
まずそれぞれの最新は、Commons CLIはバージョン1.1、args4jはバージョン2.0.9になります。
Commons CLIでは2.0が開発中のようですが、正式版はまだなのでここでは取り上げません。
以下、表にしてみます。
比較表
Commons CLI | Args4j | 備考 | |
---|---|---|---|
Java | 1.3以上 | 5以上 | |
引数のバインド | Optionオブジェクト | アノテーション | |
ロングネーム | ○ | ○ | |
パーサの変更 | ○ | × | Commons CLIのパーサはBasicとGNUとPosixの3種類から選べます。 |
使用例出力 | ○ | ○ |
以下、それぞれ使用したコードと実行結果を記載します。
コード例
- Commons CLI
import org.apache.commons.cli.BasicParser; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; public class CLI { public static void main(String[] args) { Options options = new Options(); options.addOption("i", true, "user id"); options.addOption("n", true, "user name"); options.addOption("d", "debug", false, "debug option"); options.addOption(OptionBuilder .withArgName("option") .hasArg() .withDescription("optional args") .isRequired(false) .create("o") ); String[] args1 = {"-i", "317", "-n", "cactusman", "--debug"}; CommandLineParser parser = new BasicParser(); CommandLine cl = null; try { cl = parser.parse(options, args1); } catch (ParseException e) { e.printStackTrace(); return; } HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("CLI", options, true); int id = Integer.parseInt(cl.getOptionValue("i")); String name = cl.getOptionValue("n"); boolean isDebug = Boolean.parseBoolean(cl.getOptionValue("d")); String optional = cl.getOptionValue("o"); System.out.println("ID:" + id); System.out.println("Name:" + name); System.out.println("Debug:" + isDebug); System.out.println("Optional:" + optional); } }
-
- 結果
usage: CLI [-d] [-i <arg>] [-n <arg>] [-o <option>] -d,--debug debug option -i <arg> user id -n <arg> user name -o <option> optional args ID:317 Name:cactusman Debug:false Optional:null
- Args4j
import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; public class Args4j { @Option(name="-i", metaVar="id", usage="user id") private int id; @Option(name="-n", metaVar="name", usage="user name") private String name; @Option(name="-d", aliases="--debug", usage="debug option") private boolean isDebug; @Option(name="-o", usage="optional args", required=false) private String optional; public static void main(String[] args) { Args4j args4j = new Args4j(); String[] args1 = {"-i", "317", "-n", "cactusman", "--debug"}; CmdLineParser parser = new CmdLineParser(args4j); try { parser.parseArgument(args1); } catch (CmdLineException e) { e.printStackTrace(); return; } parser.printSingleLineUsage(System.out); System.out.println(); parser.printUsage(System.out); System.out.println(); System.out.println("ID:" + args4j.id); System.out.println("Name:" + args4j.name); System.out.println("Debug:" + args4j.isDebug); System.out.println("Optional:" + args4j.optional); } }
-
- 結果
[-d (--debug)] [-i id] [-n name] [-o VAL] -d (--debug) : debug option -i id : user id -n name : user name -o VAL : optional args ID:317 Name:cactusman Debug:true Optional:null
感想
使用感としてはアノテーションで記述するArgs4jのほうが記述量が少なく、使いやすいのではと思いました。
実際、postterではそれぞれのサブコマンドごとに引数が少し違う、というものを作るのに継承が使えて大変見やすくなっています。
これをCommons CLIでやろうと思えばできますが、記述量が増えて見通しも悪くなるのではないかと思います。
ただ、Args4jではPosixパターンのパーサはありませんし、Java5以上でないと使えないという制限はあります。
こういうところで好みが大きく変わりますが、自分としてはArgs4jのほうが好きですね。
*1:もちろん他にもありますが