Apache CommonsCLIを使用したコマンドライン解析

時々、Javaベースのアプリケーションまたはテスト対象のクラス内で直接単純なテストメカニズムを提供するmain()関数実装のいずれかのために、Javaでコマンドライン引数を処理する必要があることに気付きます。Java開発者には、コマンドライン解析のための多くの選択肢があります。コマンドライン引数が1つ、2つ、または少数しかない場合(特に、付随する値ではなくフラグの有無だけが必要な場合)、これらのコマンドを処理するためのコードを数行記述します。ラインオプションは大したことではありません。より多くのオプションがある場合、および/または一部のオプションに値がある場合は、コマンドライン解析のより高度なサポートにアクセスすると便利です。

このブログエントリでは、Apache Commons CLIライブラリの使用について説明しますが、args4j、TEコードコマンドライン解析、CLAJR(Javaリフレクションを使用したコマンドライン引数)、JArgs、JSAP(Java Simple)など、他にも多数の選択肢があります。引数プロセッサ)、および他のいくつか(さらにここに)。

Apache CommonsCLIライブラリはApacheCommonsの一部ですが、これは、Apache Commons ModelerのJARダウンロードおよびApacheCommons LangのJARダウンロードとは別の(JAR)ダウンロードです。このブログエントリでは、CLI 2.0のリリースが予定されていないため、CLI 1.1を使用しています(詳細については、このエントリの最後にあります)。

Apache Common CLIの非常に簡単な例をいくつか示し、このライブラリの使用に関する他のリソースへのリンクをいくつか含めます。

Apache Common CLIを使用する2つの重要なクラスは、org.apache.commons.cli.Optionクラスと密接に関連するorg.apache.commons.cli.Options(Optionクラスの複数のインスタンスを含む)です。これらのクラスは、予想されるコマンドラインオプションを表すために使用されます。次の2つのコードスニペットは、PosixスタイルのオプションとGNUスタイルのオプションのOptionsクラスの設定を示しています。

複数のオプションインスタンスでのオプションクラスの使用

 /** * Construct and provide Posix-compatible Options. * * @return Options expected from command-line of Posix form. */ public static Options constructPosixOptions() { final Options posixOptions = new Options(); posixOptions.addOption("display", false, "Display the state."); return posixOptions; } /** * Construct and provide GNU-compatible Options. * * @return Options expected from command-line of GNU form. */ public static Options constructGnuOptions() { final Options gnuOptions = new Options(); gnuOptions.addOption("p", "print", false, "Option for printing") .addOption("g", "gui", false, "HMI option") .addOption("n", true, "Number of copies"); return gnuOptions; } 

オプションの設定例では、PosixスタイルとGNUスタイルのオプションの処理にまだ違いがないことに注意してください。これまでのところ、オプションは同じように扱うことができます。

これらの予想されるオプションに基づいたCLIによるコマンドライン引数の解析のデモンストレーションに進む前に、org.apache.commons.cli.HelpFormatterクラスを介したCLIによる使用情報とヘルプ情報のサポートに注目する価値があります。この便利なユーティリティクラスには、オーバーロードされたバージョンのprintHelp、オーバーロードされたバージョンのprintUsage、およびその他のいくつかの出力メソッドと関連メソッドなどのメソッドが含まれています。

次のコードスニペットは、HelpFormatterのprintUsageメソッドの1つとそのクラスのprintHelpメソッドの1つを利用するメソッドを示しています。

printUsage()およびprintHelp()

 /** * Print usage information to provided OutputStream. * * @param applicationName Name of application to list in usage. * @param options Command-line options to be part of usage. * @param out OutputStream to which to write the usage information. */ public static void printUsage( final String applicationName, final Options options, final OutputStream out) { final PrintWriter writer = new PrintWriter(out); final HelpFormatter usageFormatter = new HelpFormatter(); usageFormatter.printUsage(writer, 80, applicationName, options); writer.close(); } /** * Write "help" to the provided OutputStream. */ public static void printHelp( final Options options, final int printedRowWidth, final String header, final String footer, final int spacesBeforeOption, final int spacesBeforeOptionDescription, final boolean displayUsage, final OutputStream out) { final String commandLineSyntax = "java -cp ApacheCommonsCLI.jar"; final PrintWriter writer = new PrintWriter(out); final HelpFormatter helpFormatter = new HelpFormatter(); helpFormatter.printHelp( writer, printedRowWidth, commandLineSyntax, header, options, spacesBeforeOption, spacesBeforeOptionDescription, footer, displayUsage); writer.close(); } 

次のコードスニペットは、上記のprintHelp()メソッドとprintUsage()メソッドの呼び出しを示し、その後にそれらの実行からの出力を示す画面スナップショットが続きます。

 System.out.println("-- USAGE --"); printUsage(applicationName + " (Posix)", constructPosixOptions(), System.out); displayBlankLines(1, System.out); printUsage(applicationName + " (Gnu)", constructGnuOptions(), System.out); displayBlankLines(4, System.out); System.out.println("-- HELP --"); printHelp( constructPosixOptions(), 80, "POSIX HELP", "End of POSIX Help", 3, 5, true, System.out); displayBlankLines(1, System.out); printHelp( constructGnuOptions(), 80, "GNU HELP", "End of GNU Help", 5, 3, true, System.out); 

最初の画面のスナップショットは、上記のコードが示されているとおりに実行されたときの結果を示しています(オプションを使用部分に含める必要があることを示すためtrueに、printHelpメソッドの両方の使用に渡されます)。2番目の画面のスナップショットは、2番目の呼び出しにprintHelpfalseが渡され、オプションが表示されない場合に何が起こるかを示しています。

printUsageおよびprintHelp

1つのprintHelpがオプションを表示しないprintUsageとprintHelp

オプションに関する使用法とヘルプ情報は、その名前が示すように、有用で有用ですが、コマンドライン引数を使用する本当の理由は、通常、アプリケーションの動作を制御することです。次のコードリストは、GNUスタイルとPosixスタイルのコマンドライン引数を解析するための2つの方法を示しています。オプションの設定では、オプション自体を指定する以外は特定のスタイルを気にしませんでしたが、使用する適切なパーサーを決定するには、オプションのタイプが重要になります。

usePosixParser()およびuseGnuParser()

 /** * Apply Apache Commons CLI PosixParser to command-line arguments. * * @param commandLineArguments Command-line arguments to be processed with * Posix-style parser. */ public static void usePosixParser(final String[] commandLineArguments) { final CommandLineParser cmdLinePosixParser = new PosixParser(); final Options posixOptions = constructPosixOptions(); CommandLine commandLine; try { commandLine = cmdLinePosixParser.parse(posixOptions, commandLineArguments); if ( commandLine.hasOption("display") ) { System.out.println("You want a display!"); } } catch (ParseException parseException) // checked exception { System.err.println( "Encountered exception while parsing using PosixParser:\n" + parseException.getMessage() ); } } /** * Apply Apache Commons CLI GnuParser to command-line arguments. * * @param commandLineArguments Command-line arguments to be processed with * Gnu-style parser. */ public static void useGnuParser(final String[] commandLineArguments) { final CommandLineParser cmdLineGnuParser = new GnuParser(); final Options gnuOptions = constructGnuOptions(); CommandLine commandLine; try { commandLine = cmdLineGnuParser.parse(gnuOptions, commandLineArguments); if ( commandLine.hasOption("p") ) { System.out.println("You want to print (p chosen)!"); } if ( commandLine.hasOption("print") ) { System.out.println("You want to print (print chosen)!"); } if ( commandLine.hasOption('g') ) { System.out.println("You want a GUI!"); } if ( commandLine.hasOption("n") ) { System.out.println( "You selected the number " + commandLine.getOptionValue("n")); } } catch (ParseException parseException) // checked exception { System.err.println( "Encountered exception while parsing using GnuParser:\n" + parseException.getMessage() ); } } 

上記のコードを実行すると、その出力は次の2つの画面スナップショットに示すようになります。

PosixParserの結果

GNUパーサーの結果

完全な例

上に示した部分のサンプルアプリケーションの完全なコードを、便宜上リストします。