10

Apache Commons Exec 中存在错误,或者我使用的 API 错误,但是当我使用CommandLine该类添加包含空格的参数时,会添加一些引号,然后是给定参数的一部分。

例如:当我调用时,java "what version"我得到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 common 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 回答
2

您可以尝试下一个适用于我的示例:

  CommandLine cmdLine = new CommandLine("mco");
  cmdLine.addArgument("shellcmd" );
  cmdLine.addArguments( puppetAgents.split(" ") );
  cmdLine.addArgument("-t");
  cmdLine.addArgument(timeout);
  // When writing a command with space use double "
  cmdLine.addArgument("\"\"puppet agent -t\"\"",false);
于 2014-06-10T09:38:23.437 回答
0

您要执行什么课程?您没有确切指定您希望 Java 执行什么。这需要成为你的第二个论点。

换句话说,如果您尝试运行 com.mycompany.MyExecutable,您的代码应如下所示:

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

您可以在创建 CommandLine 对象后附加参数。

于 2011-02-07T22:25:57.880 回答
0

不如按照教程中的方式尝试一下,看看是否有什么不同?

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