Diese Seite ist eine kleine Einführung zum commons Framework von Apache. Um für JAVA Anwendungen einfach die Kommandozeilenargumente zu verwalten.
Download des CLI Projektes von der Jakarta Apace homepage unter http://commons.apache.org/cli/. Das benötigte Archive heißt cli-current.zip und wer will kann auch noch die Sourcen dazu aus cli-curent-src.zip laden. Nach dem auspacken der Archive brauch nur das commons-cli-1.0.0.jar dem CLASSPATH hinzugefügt zu werden. Dann noch ein import org.apache.commons.cli.*.
Das jar ist nur 30 kB groß, und wenn nicht nur ein oder zwei Argumente ausgewertet werden sollen, lohnt sich der Einsatz.
Hier die wichtigtsten Klassen des Frameworks:
Als erstes wird ein Options Objekt angelegt. Dann für alle benötigten Optionen jeweils ein Option (ohne s) Objekt das den Options hinzugefügt werden.
Options lvOptions = new Options();
lvOptions.addOption("h", "hilfe", false, "zeigt diese Hilfe an.");
Hierbei ist der erste Parameter der kurz Name der Option. Hier im Beispiel das h. Auf der Kommandozeile muss dann -h angegeben werden. Als Alternative ist der 2. Parameter, der den langen Namen der Option enthält. Dies kann von der Kommandozeile mit --hilfe aufgerufen werden. Der 3. Parameter gibt an, ob die Option ein Argument enthält (=true) oder nicht (=false). Der letzte Parameter gibt einen Text an, der die Option beschreibt. Dieser Text wird dann als Hilfe ausgegeben.
Option lvName = new Option("name", true, "der Namen des Nutzers.");
lvOptions.addOption(lvName);
Mit Hilfe der Klasse OptionBuilder können die Optionen leicht mit statischen Methoden definiert werden. Z.b. wird hier eine Option erzeugt die mit der langen Bezeichnung tage heißt und mit der kurzen Bezeichnung t. Die Option ist mit isRequired als Pflichtfeld deklariert. Fehlt diese Option, liefert der Parser eine Fehlermeldung. Mit withValueSeparator kann ein Zeichen angegeben werden das die Option von dem Parameter trennt. In der Kommandozeile wird es dann mit --tage = 155 oder -t = 144 aufgerufen.
lvOptions.addOption(OptionBuilder
.withLongOpt("tage")
.withDescription("die Anzahl der Tage mit Gleichheitszeichen als Separator.")
.isRequired()
.withValueSeparator('=')
.hasArg()
.create("t"));
Wenn aus einer Gruppe von Optionen nur eine möglich sein soll, kann die Klasse OptionGroup verwendet werden. Es werden nach anlegen des OptionGroup Objektes alle nötigen Optionen mit addOption hinzugefügt. Auf der Kommandozeile währe dann gültig: --gruppe2 oder -g2 aber nicht --gruppe2 -g1 oder -g1 -g2.
OptionGroup lvGruppe = new OptionGroup();
lvGruppe.addOption(OptionBuilder
.withLongOpt("gruppe1")
.withDescription("gruppe 1")
.create("g1"));
lvGruppe.addOption(OptionBuilder
.withLongOpt("gruppe2")
.withDescription("gruppe 2")
.create("g2"));
lvGruppe.addOption(OptionBuilder
.withLongOpt("gruppe3")
.withDescription("gruppe 3")
.create("g3"));
lvOptions.addOptionGroup(lvGruppe);
Nach dem Anlegen aller Option und hinzufügen zum Options Objekt wird ein Instanz des BasicParser angelegt. Diesem parser wird mit der parse Methode die Options und die Kommandozeilen Argumente übergeben.
CommandLineParser lvParser = new BasicParser();
CommandLine lvCmd = null;
try {
lvCmd = lvParser.parse(lvOptions, args);
} catch (ParseException pvException) {
System.out.println(pvException.getMessage());
}
Es kann einfach eine Hilfe mit alle Optionen ausgegeben werden. Dazu einfach eine Instanz vom HelpFormatter anlegen, dem die Optionen übergeben werden, und mit printHelp ausgeben.
HelpFormatter lvFormater = new HelpFormatter();
lvFormater.printHelp("Programm_Name", lvOptions);
Die Kommandozeilen Parameter können wie folgt ausgewertet werden. Wenn die Option einen Paramteter erwartet mit getOptionValue und für boolean mit hasOption.
System.out.println("Der Name lautet :" + lvCmd.getOptionValue("name"));
System.out.println("Die Option g ist true oder false? :" + lvCmd.hasOption("g"));
Ein vollständiges Beispiel:
package de.wenzlaff.cli;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
public class Demo {
private static final String KLASSEN_NAME = "de.wenzlaff.cli.Demo";
public static void main(String[] args) {
CommandLine lvCmd = null;
HelpFormatter lvFormater = new HelpFormatter();
CommandLineParser lvParser = new BasicParser();
Options lvOptions = new Options();
Option lvHilfe = new Option("h", "hilfe", false, "zeigt diese Hilfe an.");
Option lvName = new Option("name", true, "der Namen.");
lvOptions.addOption(lvHilfe);
lvOptions.addOption(lvName);
lvOptions.addOption(OptionBuilder
.withLongOpt("tage")
.withDescription("die Anzahl der Tage mit Gleichheitszeichen als Separator.")
.isRequired()
.withValueSeparator('=')
.hasArg()
.create("t"));
lvOptions.addOption(OptionBuilder
.withLongOpt("size")
.withArgName("ARGUMENTEN_NAME")
.withDescription("ist der Name der Datei.")
.hasArg()
.create("s"));
lvOptions.addOption(OptionBuilder
.withLongOpt("anzahl")
.withDescription("die Anzahl der Tage als Pflichtfeld.")
.isRequired()
.hasArg()
.create("a"));
Option lvGleich = OptionBuilder
.withLongOpt("gleich")
.withDescription("die gleiche Anweisung wie oben nur ohne Argument und optional.")
.isRequired(false)
.create("g");
lvOptions.addOption(lvGleich);
OptionGroup lvGruppe = new OptionGroup();
lvGruppe.addOption(OptionBuilder
.withLongOpt("gruppe1")
.withDescription("der 1. Parameter von der Gruppe")
.create("g1"));
lvGruppe.addOption(OptionBuilder
.withLongOpt("gruppe2")
.withDescription("der 2. Parameter von der Gruppe")
.create("g2"));
lvGruppe.addOption(OptionBuilder
.withLongOpt("gruppe3")
.withDescription("der 3. Parameter von der Gruppe")
.create("g3"));
lvOptions.addOptionGroup(lvGruppe);
try {
lvCmd = lvParser.parse(lvOptions, args);
if (lvCmd.hasOption('h')) {
lvFormater.printHelp(KLASSEN_NAME, lvOptions);
return;
}
} catch (ParseException pvException) {
lvFormater.printHelp(KLASSEN_NAME, lvOptions);
System.out.println("Parse Fehler:" + pvException.getMessage());
return;
}
System.out.println("Der Namen :" + lvCmd.getOptionValue("name"));
System.out.println("Der Size mit s :" + lvCmd.getOptionValue("s"));
System.out.println("Die Anzahl mit a :" + lvCmd.getOptionValue("a"));
System.out.println("Gleich g ist :" + lvCmd.hasOption("g"));
System.out.println("Gruppe 1 :" + lvCmd.hasOption("g1"));
System.out.println("Gruppe 2 :" + lvCmd.hasOption("g2"));
System.out.println("Gruppe 3 :" + lvCmd.hasOption("g3"));
}
}
Folgende Kommandozeilen Parameter:
-a "Pflichtfeld" -t = 55 --size SIZE -name "THOMAS WENZLAFF" -g2
Liefern diese Ergebnis:
Der Namen :THOMAS WENZLAFF Der Size mit s :SIZE Die Anzahl mit a :Pflichtfeld Gleich g ist :false Gruppe 1 :false Gruppe 2 :true Gruppe 3 :false
Eine fehlerhafte Kommandozeile mit z.b. zwei Optionen aus einer Gruppe in der Kommandozeile:
-a "Pflichtfeld" -t = 55 --size SIZE -name "THOMAS WENZLAFF" -g2 -g1
liefert diese Hilfetext mit Fehlermeldung:
usage: de.wenzlaff.cli.Demo
-a,--anzahl die Anzahl der Tage als Pflichtfeld.
-g,--gleich die gleiche Anweisung wie oben nur ohne
Argument und optional.
-g1,--gruppe1 der 1. Parameter von der Gruppe
-g2,--gruppe2 der 2. Parameter von der Gruppe
-g3,--gruppe3 der 3. Parameter von der Gruppe
-h,--hilfe zeigt diese Hilfe an.
-name der Namen.
-s,--size <ARGUMENTEN_NAME> ist der Name der Datei.
-t,--tage die Anzahl der Tage mit Gleichheitszeichen
als Separator.
Parse Fehler:an option from this group has already been selected: 'g2'