10

Apache Commons Exec にバグがあるか、間違った API を使用していますが、CommandLineクラスを使用してスペースを含む引数を追加すると、いくつかの引用符が追加され、与えられた引数の一部になります。

例: java "what version"get を呼び出すと、(コマンド ライン引数自体の一部であるエスケープされた引用符が含まれている) を呼び出すと、 get が取得されjava.lang.NoClassDefFoundError: what versionます。java "\"what version\""java.lang.NoClassDefFoundError: "what version"

したがって、次のテストは失敗します。これは、最後の行でわかるように、Apache Exec が最初のバージョンを生成する必要がある場所で、後者のバージョンを生成しているためです。

@Test
public void testArgumentQuoting() throws Exception {
    DefaultExecutor executor = new DefaultExecutor();
    DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    PumpStreamHandler streamHandler = new PumpStreamHandler(out, out);
    executor.setStreamHandler(streamHandler);
    CommandLine cmdLine = new CommandLine("java");
    cmdLine.addArgument("what version");
    executor.execute(cmdLine, resultHandler);
    resultHandler.waitFor();
    String resultPattern = "Exception in thread \"main\" java\\.lang\\.NoClassDefFoundError: ([\\w \"]+)";
    Pattern pattern = Pattern.compile(resultPattern);
    Matcher matcher = pattern.matcher(out.toString());
    Assert.assertTrue(matcher.find());
    // Note: Result should be <what version> and NOT <"what version">!
    Assert.assertEquals("what version", matcher.group(1));
}

今私は知りたい:

  • これはバグですか?
  • もしそうなら: この問題を回避する方法 (回避策) はありますか?
  • そうでない場合: 何が間違っていますか?

編集:私は、自分のマシンで実行する人が最も少ないと思われるプロセスを実行しようとしています。したがってjava、このコマンドは Java を開発するすべてのマシンで使用できるはずなので、代わりに使用しています。私の要点は、間違ったランタイム引数が外部プロセスに渡され、エスケープされた引用符が含まれているということです。

編集: 私はこれをJiraの commons exec のバグとして報告しました。

4

5 に答える 5

7

Apache共通execにはフラグaddArgument付きのメソッドがあります。handleQuotingオンにすると、引数が引用符で囲まれます。

デフォルトではオンになっています

public CommandLine addArgument(final String argument, boolean handleQuoting) 
于 2012-10-29T13:32:29.110 に答える
6

これはApache Commons Execの実際のバグのようで、現在も修正されていません。

于 2011-07-05T17:49:24.493 に答える
0

チュートリアルのように試してみて、違いがあるかどうかを確認してみてはいかがでしょうか?

...
String line = "java what version";
CommandLine cmdLine = CommandLine.parse(line);
executor.execute(cmdLine, resultHandler);
...
于 2011-02-10T09:33:07.300 に答える
0

どのクラスを実行しようとしていますか? Javaに実行させたいものを正確に指定していません。それはあなたの2番目の引数である必要があります。

つまり、com.mycompany.MyExecutable を実行しようとしている場合、コードは次のようになります。

CommandLine cmdLine = new CommandLine("java com.mycompany.MyExecutable");

CommandLine オブジェクトの作成後に引数を追加できます。

于 2011-02-07T22:25:57.880 に答える