24

Ich bin dabei, einige Legacy-Code zu migrieren, um weniger veraltete Warnungen von 3rd -Party-Bibliotheken enthalten. Für Apache commons-cli Bibliothek (Version: 1.3.1 ) entdeckte ich in der official JavaDoc dass GnuParser veraltet und DefaultParser sollte stattdessen verwendet werden:Warum werden die erkannten CLI-Optionen bei der Verwendung von DefaultParser anstelle von GnuParser unterschieden?

@deprecated seit 1.3, verwenden Sie die {@link DefaultParser} statt

Das folgende Code-Snippet funktioniert jedoch nicht mehr wie erwartet:

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 

Beachten Sie, dass setValueSeparator(',') wird hier verwendet, um ein benutzerdefiniertes Trennzeichen zu definieren ,, um die CLI zu aktivieren, um mehrere gst-Typen zu unterstützen (siehe Code-Snippet).

Wie geben Sie die folgenden Programmargumente verwendet, um die CLI zu nennen:

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

Offensichtlich einige andere Argumente auch hinzugefügt wurden nach dem gsd Parameter könnten. Die erwartete und richtig analysiert Optionen für den Separator lose Verwendung des "gst" Argument sind (via GnuParser):

  1. "Kategorie" (und sonst nichts)

Allerdings, wenn ich ändern meinen Code und wechseln auf den empfohlenen Parser über:

CommandLineParser parser = new DefaultParser(); 

der resultierenden, analysiert Werte falsch als erkannt werden:

  1. "Kategorie"
  2. "-GSD"
  3. "4"

Hinweis: benutzte ich einen Debugger das falsche Ergebnis des Parsing-Prozess über Inspektion des Feldes values in org.apache.commons.cli.Option zu überprüfen über die zurückgegebene commands Variable.

Meine Erwartung wäre, dass die interne Änderung des Parsers nicht unterschiedliche Ergebnisse ergeben, da dies bestehenden Code bricht. Hat jemand jemals das gleiche Verhalten bei Apache Commons-CLI beim Wechsel zu DefaultParser und mehreren Optionswerten und benutzerdefinierten Trennzeichen festgestellt?

Gibt es einen Unterschied in der Konstruktion/Verwendung von DefaultParser, die ich hätte übersehen können?

+0

Das ist eine ziemlich tiefe Frage und es klingt wie ein Bug. Vorschlag: Sie finden eher eine sachkundige Antwort auf der Commons-Mailing-Liste: [email protected] –

+0

ist die "gsd" -Option auch auf den Optionen konfiguriert? – jtahlborn

+1

Ja, ist es. Ich habe nur das Code-Fragment gekürzt. rate mal was: es funktioniert, wenn 'GnuParser' zuständig ist: Sowohl gst als auch gsd werden so erkannt, wie ich es erwarten würde. – MWiesner

Antwort

1

Ich denke, das Problem könnte der Anruf zu optionGSTypes.setArgs(3); sein, entsprechend der JavaDoc, es commons-cli an "Setzt die Anzahl der Argumente Werte diese Option kann.", D.Sie weisen commons-cli an, die nächsten drei commnadline-Argumente als Argumente für das Argument "gst" zu nehmen. Die setValueSeparator(',') scheint zu definieren, wofür normalerweise das Gleichheitszeichen verwendet wird (siehe JavaDoc), d.

In Ihrem Fall denke ich, die einfachste Option besteht darin, das Optionsargument als einfache Zeichenfolge anzugeben und die Analyse selbst durchzuführen. Auf diese Weise können Sie vollständig steuern, welche Werte zulässig sind, und Sie erhalten eine bessere Fehlermeldung.

+0

Ich lese die JavaDoc-Snippets, auf die Sie verweisen, aber es galt auch für 'GnuParser', die die oben genannten Programmargumente richtig analysierte. Darüber hinaus bezieht sich "can have" auf die maximal zulässige Anzahl von Argumenten, die - in meinem Anwendungsfall - auftreten können, also ist dies genau das, wonach ich suche. Die Frage ist: Warum verändert eine Änderung in der Parser-Implementierung, was vorher richtig funktioniert hat? – MWiesner

+3

Dann ist es entweder ein Fehler in 'DefaultParser' oder ein" undokumentiertes "Verhalten in' GnuParser', in beiden Fällen müssen Sie wahrscheinlich mit den Betreuern von commons-cli direkt diskutieren, da nur sie angeben können, welche der zwei Fälle ist es. – centic

+0

Sie können Recht haben! Meine bisherige Hoffnung: Einer der Betreuer kommt vorbei und findet diese StOf-Frage. Vielleicht ist es eine Prämie wert? – MWiesner

7

Beim Durchschreiten des Codes DefaultParser scheint dies wie ein Fehler.

Erste DefaultParser erkennt -gst als Short-Option durch Options.hasShortOption("-gst") Aufruf, die true zurückgibt.

So weit so gut.

Nun, wenn es darum geht zu entscheiden, ob -gsd als Argument Wert -gstDefaultParser Bedürfnisse zu interpretieren, um herauszufinden, ob -gsd selbst eine Option (und daher kann kein Argument zu -gst sein). Es tut dies, indem es sein eigenes isShortOption("-gsd") nennt. Dies gibt jedoch false aus Gründen, die deutlich werden, wenn man sich den Code anschauen:

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

Dies extrahiert den ersten Buchstaben aus dem -gst Option daher Options.hasShortOption("g") Aufruf, die false zurückgibt. Der Code scheint so zu sein, dass er für POSIX-ähnliche Ein-Buchstaben-Optionen verwendet werden kann, aber er bricht für mehrbuchstabige Einzel-Bindestrich-Optionen wie die, die Sie verwenden, ab.

aber Sie es drehen, -gst als kurze Option erkannt zu werden, aber -gsdnicht immer scheint ein Bug zu mir erkannt.

+0

interessant! würde meine Beobachtungen bestätigen.Die Schlussfolgerung, dass es sich um einen Bug handeln könnte, erscheint nach einem ersten Blick auf Ihre Debug-Ergebnisse vernünftig. – MWiesner

Verwandte Themen