24

レガシー コードを移行して、サードパーティ ライブラリからの非推奨の警告を少なくしようとしています。Apachecommons-cliライブラリ (バージョン: 1.3.1 ) の場合、非推奨であり、代わりに使用する必要がある公式の JavaDocで検出しました。GnuParserDefaultParser

@deprecated 1.3 以降、{@link DefaultParser}代わりに

ただし、次のコード スニペットは期待どおりに機能しなくなります。

Options options = new Options();    
Option optionGSTypes = new Option(
        "gst","gs-types", true,
        "the supported types, comma-separated: article, category, template, all");
optionGSTypes.setArgs(3);
optionGSTypes.setValueSeparator(',');
options.addOption(optionGSTypes);

// ... other options

// parsed option values are correct, yet this is deprecated
CommandLineParser parser = new GnuParser(); 
CommandLine commands = parser.parse(options, args);

// ... interpret parsed 'commands' and related actual values via CLI

CLI がいくつかのgstsetValueSeparator(',')型をサポートできるようにするカスタム区切り文字を定義するためにここで が使用されていることに注意してください (コード スニペットを参照)。,

入力として、次のプログラム引数を使用して CLI を呼び出します。

java -jar MyCLI.jar -gst category -gsd 4

明らかに、gsd パラメーターの後にいくつかの他の引数も追加されている可能性があります。「gst」引数をセパレーターなしで使用するために期待され、正しくGnuParser解析されるオプションは次のとおりです (経由):

  1. 「カテゴリ」(他には何もない)

ただし、コードを変更して、推奨されるパーサーに切り替えると、次のようになります。

CommandLineParser parser = new DefaultParser();

結果として解析された値は、次のように誤って検出されます。

  1. "カテゴリー"
  2. 「-gsd」
  3. 「4」

ヒント: デバッガーを使用して、返された変数valuesを介してフィールドを調べて、解析プロセスの誤った結果を検証しました。org.apache.commons.cli.Optioncommands

私の予想では、パーサーの内部変更によって、既存のコードが壊れるため、別の結果が得られるはずはありません。DefaultParserいくつかのオプション値とカスタムセパレーターに切り替えるときに、Apache Commons-CLI で同じ動作に遭遇した人はいますか?

DefaultParser私が監督したかもしれないその構築/使用法に違いはありますか?

4

2 に答える 2

8

のコードをステップスルーするとDefaultParser、これはバグのようです。

最初に whichを呼び出すことにより短いオプションとしてDefaultParser認識され、が返されます。-gstOptions.hasShortOption("-gst")true

ここまでは順調ですね。

-gsdここで、 を引数値として解釈するかどうかを決定する際に、がそれ自体がオプションであるかどうかを判断する-gst DefaultParser必要があります (したがって、 の引数にすることはできません)。これは、独自の を呼び出すことによって行います。ただし、これは、コードを見ると明らかになる理由で返されます。-gsd-gstisShortOption("-gsd")false

private boolean isShortOption(String token)
{
    // short options (-S, -SV, -S=V, -SV1=V2, -S1S2)
    return token.startsWith("-") && token.length() >= 2 && 
           options.hasShortOption(token.substring(1, 2));
}

これは、オプションから最初の文字を抽出する-gstため、これを呼び出しOptions.hasShortOption("g")て を返しますfalse。コードは POSIX スタイルの単一文字オプションで機能するように設計されているようですが、使用しているような複数文字の単一ハイフン オプションでは機能しません。

どのように変えて-gstも、短いオプションとして認識されますが、認識され-gsd ないのはバグのように思えます。

于 2016-02-13T18:30:46.103 に答える
1

JavaDocoptionGSTypes.setArgs(3);によると、問題は の呼び出しである可能性があると思います。それは commons-cli に「このオプションが取ることができる引数値の数を設定する」ように指示します。つまり、次の 3 つのコマンドライン引数を引数として取るように commons-cli に指示します。 「gst」引数用。

さらに、setValueSeparator(',')等号が通常使用されるもの ( JavaDocを参照)、つまり「キー=値」のような形式のオプションを定義しているように見えるため、実際に探しているものではありません。

あなたの場合、最も簡単なオプションは、オプション引数を単純な文字列として指定し、自分で解析することだと思います。このようにして、許可される値を完全に制御し、より適切なエラー メッセージを提供できます。

于 2016-01-01T16:19:07.283 に答える