Using Apache Commons CLI 1.2 here. I have an executable JAR that needs to take 2 runtime options, fizz
and buzz
; both are strings that require arguments/values. I would like (if at all possible) my app to be executed like so:
java -jar myapp.jar -fizz "Alrighty, then!" -buzz "Take care now, bye bye then!"
In this case, the value for the fizz
option would be "Alrighty, then!", etc.
Here's my code:
public class MyApp {
private Options cmdLineOpts = new Options();
private CommandLineParser cmdLineParser = new GnuParser();
private HelpFormatter helpFormatter = new HelpFormatter();
public static void main(String[] args) {
MyApp myapp = new MyApp();
myapp.processArgs(args);
}
private void processArgs(String[] args) {
Option fizzOpt = OptionBuilder
.withArgName("fizz")
.withLongOpt("fizz")
.hasArg()
.withDescription("The fizz argument.")
.create("fizz");
Option buzzOpt = OptionBuilder
.withArgName("buzz")
.withLongOpt("buzz")
.hasArg()
.withDescription("The buzz argument.")
.create("buzz");
cmdLineOpts.addOption(fizzOpt);
cmdLineOpts.addOption(buzzOpt);
CommandLine cmdLine;
try {
cmdLine = cmdLineParser.parse(cmdLineOpts, args);
// Expecting to get a value of "Alright, then!"
String fizz = cmdLine.getOptionValue("fizz");
System.out.println("Fizz is: " + fizz);
} catch(ParseException parseExc) {
helpFormatter.printHelp("myapp", cmdLineOpts, true);
throw parseExc;
}
}
}
When I run this I get the following output:
Fizz is: null
What do I need to do to my code so that my app can be invoked the way I want it to? Or what's the closest I can get to it?
Bonus points: If someone can explain to me the difference between the OptionBuilder
's withArgName(...)
, withLongOpt(...)
and create(...)
arguments, as I am passing in the same value for them all like so:
Option fizzOpt = OptionBuilder
.withArgName("fizz")
.withLongOpt("fizz") } Why do I have to pass the same value in 3 times to make this work?!?
.create("fizz");
First the .hasArg()
on your OptionBuilder tells it that you expect an argument after the paramter flag.
I got it to work with this command line
--fizz "VicFizz is good for you" -b "VicBuzz is also good for you"
Using the following code - I put this in the constructor
Option fizzOpt = OptionBuilder
.withArgName("Fizz")
.withLongOpt("fizz")
.hasArg()
.withDescription("The Fizz Option")
.create("f");
cmdLineOpts.addOption(fizzOpt);
cmdLineOpts.addOption("b", true, "The Buzz Option");
Breakdown
The option settings are necessary in order to provide more usability on the command line, as well as a nice usage message (see below)
.withArgName("Fizz")
: Gives your argument a nice title in the usage
(see below).withLongOpt("fizz")
: allows for --fizz "VicFizz is good for you"
.create("f")
: is the main parameter and allows
command line -f "VicFizz is good for you"
Usage Message
Personally I love CLI programs that print out a nice usage. You can do this with the HelpFormatter
. For example:
private void processArgs(String[] args) {
if (args == null || args.length == ) {
helpFormatter.printHelp("Don't you know how to call the Fizz", cmdLineOpts);
...
This will print something usefull like:
usage: Don't you know how to call the Fizz
-b <arg> The Buzz Option
-f,--fizz <Fizz> The Fizz Option
Notice how a the short option -f
, the long option --fizz
, and a name <Fizz>
is displayed, along with the description.
Hope this helps