new icon example borderfactory java command-line-interface apache-commons apache-commons-cli

example - my icon java



¿Por qué las opciones CLI detectadas son diferentes cuando se usa DefaultParser en lugar de GnuParser? (2)

Al pasar por el código de DefaultParser , esto parece un error.

First DefaultParser reconoce -gst como una opción corta al llamar a Options.hasShortOption("-gst") que devuelve true .

Hasta ahora tan bueno.

Ahora, cuando se trata de decidir si interpretar -gsd como un valor de argumento para -gst DefaultParser debe averiguar si -gsd es en sí misma una opción (y, por lo tanto, no puede ser un argumento para -gst ). Lo hace llamando a su propio isShortOption("-gsd") . Sin embargo, esto devuelve false por razones que se vuelven obvias si miras el código:

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

Esto extrae la primera letra de la opción -gst , por lo tanto, llama a Options.hasShortOption("g") que devuelve false . El código parece estar diseñado para funcionar con las opciones de una sola letra del estilo POSIX, pero se descompone para las opciones de un solo guión de varias letras, como las que está utilizando.

Sin embargo, lo conviertes, -gst que te reconozcan como una opción corta, pero que no sea reconocido me parezca un error.

Estoy a punto de migrar algunos códigos heredados para contener advertencias menos obsoletas de las bibliotecas de terceros. Para la biblioteca de Apache commons-cli (versión: 1.3.1 ), detecté en el GnuParser oficial que GnuParser está en desuso y que DefaultParser debería usarse en su lugar:

@deprecated since 1.3, use el {@link DefaultParser} lugar

Sin embargo, el siguiente fragmento de código deja de funcionar como se esperaba:

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

Tenga en cuenta que setValueSeparator('','') se usa aquí para definir un carácter de separador personalizado , para permitir que la CLI admita los tipos de gst sevaral (consulte el fragmento de código).

Como entrada, los siguientes argumentos del programa se utilizan para llamar a la CLI:

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

Obviamente, muchos otros argumentos también podrían haberse agregado después del parámetro gsd. Las opciones esperadas y analizadas correctamente para el uso sin separador del argumento "gst" son (a través de GnuParser ):

  1. "categoría" (y nada más)

Sin embargo, cuando cambio mi código y me dirijo al analizador recomendado a través de:

CommandLineParser parser = new DefaultParser();

Los valores analizados resultantes se detectan incorrectamente como:

  1. "categoría"
  2. "-gsd"
  3. "4"

Sugerencia: usé un depurador para verificar el resultado incorrecto del proceso de análisis mediante la inspección de los values campo en org.apache.commons.cli.Option través de la variable de commands devueltos.

Mi expectativa sería que el cambio interno del analizador no produzca resultados diferentes, ya que esto rompe el código existente. ¿Alguna vez alguien ha encontrado el mismo comportamiento con Apache Commons-CLI al cambiar a DefaultParser y varios valores de opción y separadores personalizados?

¿Hay alguna diferencia en la construcción / uso de DefaultParser que podría haber supervisado?


Creo que el problema podría ser la llamada a optionGSTypes.setArgs(3); Según el JavaDoc , ordena commons-cli a "Establece el número de valores de argumento que esta opción puede tomar", es decir, le ordena a commons-cli que tome los siguientes tres argumentos de commnadline como argumentos para el argumento "gst".

Además, setValueSeparator('','') parece definir para qué usualmente se usa el signo igual, (ver el JavaDoc ), es decir, opciones con formato como "clave = valor", así que no es lo que realmente está buscando.

En su caso, creo que la opción más fácil es especificar el argumento de la opción como una cadena simple y hacer el análisis usted mismo. De esta manera, puede controlar completamente qué valores se permiten y también proporcionar un mejor mensaje de error.