English 中文(简体)
Apache Commons Exec produces too many quotes for arguments containing spaces?
原标题:

Either there is a bug in Apache Commons Exec, or I am using the API wrong, but when I use the CommandLine class to add a argument that contains spaces, some quotes are added and are then part of the argument that is given.

For example: When I call java "what version" I get java.lang.NoClassDefFoundError: what version, and when I call java ""what version"" (which contains escaped quotes, that are part of the command line argument itself), I get java.lang.NoClassDefFoundError: "what version".

So the following test fails, because as you can see in the last line, Apache Exec is producing the latter version where it should have produced the first version:

@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));
}

Now I want to know:

  • Is this a bug?
  • If so: Is there a way to circumvent this problem (a workaround)?
  • If not: What am I doing wrong?

Edit: I am trying to execute a process which I think fewest people will have on their machine. So I am using java instead as this command should be available on all machines where people develop Java. My point is that the wrong runtime argument is passed to the external process, containing escaped quotes, which it shouldn t.

Edit: I made this a filed bug for commons exec at Jira.

最佳回答

This seems to be a real bug in Apache Commons Exec, which to date has not been fixed.

问题回答

Apache common exec has addArgument method with handleQuoting flag. If it s turned on, then it wraps arguments in quotation marks.

By default it s turned on

public CommandLine addArgument(final String argument, boolean handleQuoting) 

you can try the next example it works for me :

  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);

What class are you trying to execute? You re not specifying exactly what you want Java to execute. That needs to be your second argument.

In other words, if you re trying to run com.mycompany.MyExecutable, your code should look like this:

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

You can either append arguments after the CommandLine object is created.

How about trying it this way as in the tutorial, to see if that makes a difference?

...
String line = "java what version";
CommandLine cmdLine = CommandLine.parse(line);
executor.execute(cmdLine, resultHandler);
...




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签