Parsing command line options in your program has always been a boring work; you loop through String[] and write a whole bunch of arg.equals("-foo") and arg.equals("-bar"). There are some libraries that attempt to solve this, such as Apache Commons CLI. I tried many of those, bu ]]>public class MyOptions { private boolean recursive; private File out; private String str = "(default value)"; private int num; }

You then put args4j annotations on this class. The annotations tell args4j which option maps to which field. You can also specify the human-readable description for the option, which args4j will use to generate the usage screen.

I also added another field that receives arguments (the inputs to the command line other than options)

 public class MyOptions { @Option(name="-r",usage="recursively run something") private boolean recursive; @Option(name="-o",usage="output to this file") private File out; @Option(name="-str") // no usage private String str = "(default value)"; @Option(name="-n",usage="usage can have new lines in it\n and also it can be long") private int num; // receives other command line parameters than options @Argument private List arguments = new ArrayList(); } 

In the above example I annotated fields, but I can also annotate a setter method with the same annotation. That will cause args4j to invoke the setter instead of accessing the field directly. That allows you to perform additional semantic check on the parameter, or define a set of options that interact with each other in some application-specific fashion.

Given all those annotations, I can parse arguments just like this:

 public void main(String[] args) throws IOException { MyOptions bean = new MyOptions() CmdLineParser parser = new CmdLineParser(bean); parser.parseArgument(args); 

This will parse the string array as parameters, and args4j will set the values to fields or invoke setters appropriately.

What happens if the user types a wrong option name? Just surround the parseArgument method with a try-catch block like this:

 try { parser.parseArgument(args); } catch( CmdLineException e ) { System.err.println(e.getMessage()); System.err.println("java -jar myprogram.jar [options...] arguments..."); parser.printUsage(System.err); return; } 

CmdLineException contains a human-readable error message that you can just print out. Then you can also use args4j to generate a list of options. With args4j, you don't need to maintain a separate list of options just for showing the usage screen.

The benefit of using annotations is that you can generate the list of options not only at the runtime but also at the development time. args4j comes with a tool that lets you generate HTML/XML list of all options. This is ideal for keeping the documentation of your tool in sync with the code. This can be done by running the following command:

 $ java -jar args4j-tools.jar path/to/MyOptions.java 

Both the usage screen generation and the XML/HTML generation supports internalization adequately.

If you are interested in argsj, visit the project home page and play with it. Let me know how you think of this. In the future, I'm thinking about using this annotation to parse the Ant task into the same option bean, so that you can have a single code for the CLI and the Ant task interface.