2011-02-07 12 views
9

O bien hay un error en Apache Commons Exec, o estoy usando el API incorrecto, pero cuando uso la clase CommandLine para agregar un argumento que contiene espacios, se agregan algunas comillas y luego son parte del argumento que se da.Apache Commons Exec produce demasiadas citas para los argumentos que contienen espacios?

Por ejemplo: Cuando llamo java "what version" me sale java.lang.NoClassDefFoundError: what version, y cuando llamo java "\"what version\"" (que contiene comillas escapadas, que forman parte de la línea de comandos argumento en sí), me sale java.lang.NoClassDefFoundError: "what version".

Así que la siguiente prueba falla, ya que como se puede ver en la última línea, Apache Exec está produciendo esta última versión en la que se debería haber producido la primera versión:

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

Ahora quiero saber:

  • ¿Esto es un error?
  • En caso afirmativo: ¿Hay alguna forma de eludir este problema (una solución)?
  • Si no: ¿Qué estoy haciendo mal?

Editar: Estoy tratando de ejecutar un proceso que creo que la menor cantidad de gente tendrá en su máquina. Así que estoy usando java, ya que este comando debería estar disponible en todas las máquinas donde las personas desarrollen Java. Mi punto es que el argumento de tiempo de ejecución incorrecto se pasa al proceso externo, que contiene citas escapadas, que no debería.

Editar: Hice esto un error archivado para el ejecutivo de los comunes en Jira.

Respuesta

5

Esto parece ser un real bug en Apache Commons Exec, que hasta la fecha no ha sido fijada.

+1

Increíble que esto no se haya solucionado, ¿nadie usa commons-exec con argumentos que realmente necesitan una cotización? – Miles

+0

@Miles commons-exec es horrible cuando se trata de presupuestos, y nadie lo arreglará. También estoy desconcertado por qué nadie usa commons-exec, dada la falta de alternativas. ¿Realmente todos RYO rompe las envolturas de ProcessBuilder? Hablando de eso, ¿por qué no se diseñó ProcessBuilder correctamente en primer lugar? ¿Tal vez nadie usa Java para generar procesos? –

0

¿Qué clase estás tratando de ejecutar? No está especificando exactamente qué quiere que ejecute Java. Ese debe ser su segundo argumento.

En otras palabras, si usted está tratando de ejecutar com.mycompany.MyExecutable, su código debería tener este aspecto:

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

Puede añadir argumentos ya sea después de crear el objeto de comandos.

+0

Hola y gracias por contestar. En realidad, no estoy tratando de ejecutar una clase Java, sino un proceso completamente diferente. Pero como esto es muy específico, no me gustaría escribir un caso de prueba para eso, ya que no creo que nadie tenga esto en su máquina.Por otro lado, todo el mundo que habla de Java tiene 'java' instalado en su máquina, por lo tanto, este caso de prueba ... – roesslerj

0

¿Qué le parece intentarlo de esta manera como en el tutorial, para ver si eso hace la diferencia?

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

Esto no funciona en absoluto, porque Apache Commons Exec trata correctamente las dos palabras como argumentos separados, porque están separados por un espacio. Pero en mi caso, necesito un único argumento que contenga espacios ... Pero de todos modos, gracias por la entrada. – roesslerj

5

Apache common exec tiene addArgument método con handleQuoting marca. Si está activado, coloca los argumentos entre comillas.

Por defecto se ha girado

public CommandLine addArgument(final String argument, boolean handleQuoting) 
1

puede probar el siguiente ejemplo que funciona para mí:

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