Home | History | Annotate | Download | only in doc
      1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
      2 <html> <head>
      3 <title>JCommander</title>
      4 
      5 <!--
      6 <link rel="stylesheet" href="testng.css" type="text/css" />
      7 -->
      8 
      9       <link type="text/css" rel="stylesheet" href="http://beust.com/beust.css"  />
     10       <link type="text/css" rel="stylesheet" href="http://jcommander.org/jcommander.css"  />
     11       <script type="text/javascript" src="http://beust.com/prettify.js"></script>
     12 
     13       <script type="text/javascript" src="http://beust.com/scripts/shCore.js"></script>
     14       <script type="text/javascript" src="http://beust.com/scripts/shBrushJava.js"></script>
     15       <script type="text/javascript" src="http://beust.com/scripts/shBrushXml.js"></script>
     16       <script type="text/javascript" src="http://beust.com/scripts/shBrushBash.js"></script>
     17       <script type="text/javascript" src="http://beust.com/scripts/shBrushPlain.js"></script>
     18       <link type="text/css" rel="stylesheet" href="http://beust.com/styles/shCore.css"/>
     19       <link type="text/css" rel="stylesheet" href="http://beust.com/styles/shThemeCedric.css"/>
     20       <script type="text/javascript" src="http://beust.com/toc.js"></script>
     21       <script type="text/javascript">
     22         SyntaxHighlighter.config.clipboardSwf = 'scripts/clipboard.swf';
     23         SyntaxHighlighter.defaults['gutter'] = false;
     24         SyntaxHighlighter.all();
     25       </script>
     26 </head>
     27 
     28 <table width="100%">
     29   <tr>
     30     <td align="center">
     31 <h1>JCommander</h1>
     32 <h2>Because life is too short to parse command line parameters</h2>
     33 <h3>
     34   <form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
     35   <input type="hidden" name="cmd" value="_donations">
     36   <input type="hidden" name="business" value="cedric (a] beust.com">
     37   <input type="hidden" name="lc" value="US">
     38   <input type="hidden" name="item_name" value="Cedric Beust">
     39   <input type="hidden" name="no_note" value="0">
     40   <input type="hidden" name="currency_code" value="USD">
     41   <input type="hidden" name="bn" value="PP-DonationsBF:btn_donate_LG.gif:NonHostedGuest">
     42   <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
     43   <img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
     44   </form>
     45 </h3>
     46     </td>
     47   </tr>
     48   <tr>
     49     <td align="right">
     50       Created: July 13th, 2010
     51     </td>
     52   </tr>
     53   <tr>
     54     <td align="right">
     55       Last updated: January 14th, 2015
     56     </td>
     57   </tr>
     58   <tr><td align="right"><a href="mailto:cedric (a] beust.com">C&eacute;dric Beust</a></td></tr>
     59 </table>
     60 
     61 <h2>Table of contents</h2>
     62 <div id="table-of-contents">
     63 </div>
     64 
     65 
     66 
     67 <h2><a class="section" name="Overview">Overview</a></h2>
     68 
     69 JCommander is a very small Java framework that makes it trivial to parse command line parameters.
     70 <p>
     71 You annotate fields with descriptions of your options:
     72 
     73 <pre class="brush: java">
     74 import com.beust.jcommander.Parameter;
     75 
     76 public class JCommanderExample {
     77   @Parameter
     78   private List&lt;String&gt; parameters = new ArrayList&lt;String&gt;();
     79 
     80   @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity")
     81   private Integer verbose = 1;
     82 
     83   @Parameter(names = "-groups", description = "Comma-separated list of group names to be run")
     84   private String groups;
     85 
     86   @Parameter(names = "-debug", description = "Debug mode")
     87   private boolean debug = false;
     88 }
     89 </pre>
     90 
     91 and then you simply ask JCommander to parse:
     92 
     93 <pre class="brush: java">
     94 JCommanderExample jct = new JCommanderExample();
     95 String[] argv = { "-log", "2", "-groups", "unit" };
     96 new JCommander(jct, argv);
     97 
     98 Assert.assertEquals(jct.verbose.intValue(), 2);
     99 </pre>
    100 
    101 <h2><a class="section" name="Types_of_options">Types of options</a></h2>
    102 
    103 The fields representing your parameters can be of any type. Basic types (<tt>Integer</tt>, <tt>Boolean</tt/>., etc...) are supported by default and you can write type converters to support any other type (<tt>File</tt>, etc...).
    104 
    105 <h4>Boolean</h4>
    106 
    107 When a <tt>Parameter</tt> annotation is found on a field of type <tt>boolean</tt> or <tt>Boolean</tt>, JCommander interprets it as an option with an <em>arity</em> of 0:
    108 
    109 <pre class="brush: java">
    110 @Parameter(names = "-debug", description = "Debug mode")
    111 private boolean debug = false;
    112 </pre>
    113 
    114 Such a parameter does not require any additional parameter on the command line and if it's detected during parsing, the corresponding field will be set to <tt>true</tt>.
    115 
    116 <p>
    117 
    118   If you want to define a boolean parameter that's <tt>true</tt> by default, you can declare it as having an arity of 1. Users will then have to specify the value they want explicitly:
    119 
    120   <pre class="brush: java">
    121     @Parameter(names = "-debug", description = "Debug mode", arity = 1)
    122     private boolean debug = true;
    123   </pre>
    124 
    125   Invoke with either of:
    126 
    127   <pre class="brush: plain">
    128     program -debug true
    129     program -debug false
    130   </pre>
    131 
    132 <h4>String, Integer, Long</h4>
    133 
    134 When a <tt>Parameter</tt> annotation is found on a field of type <tt>String</tt>, <tt>Integer</tt>, <tt>int</tt>, <tt>Long</tt> or <tt>long</tt>, JCommander will parse the following parameter and it will attempt to cast it to the right type:
    135 
    136 <pre class="brush: java">
    137 @Parameter(names = "-log", description = "Level of verbosity")
    138 private Integer verbose = 1;
    139 </pre>
    140 
    141 <pre class="brush: plain">
    142 java Main -log 3
    143 </pre>
    144 
    145 will cause the field <tt>verbose</tt> to receive the value 3, however:
    146 
    147 <pre class="brush: plain">
    148 java Main -log test
    149 </pre>
    150 
    151 will cause an exception to be thrown.
    152 
    153 <h4>Lists</h4>
    154 
    155 When a <tt>Parameter</tt> annotation is found on a field of type <tt>List</tt>, JCommander will interpret it as an option that can occur multiple times:
    156 
    157 <pre class="brush: java">
    158 @Parameter(names = "-host", description = "The host")
    159 private List&lt;String&gt; hosts = new ArrayList&lt;String&gt;();
    160 </pre>
    161 
    162 will allow you to parse the following command line:
    163 
    164 <pre class="brush: plain">
    165 java Main -host host1 -verbose -host host2
    166 </pre>
    167 
    168 When JCommander is done parsing the line above, the field <tt>hosts</tt> will contain the strings "host1" and "host2".
    169 
    170 <h4>Password</h4>
    171 
    172 If one of your parameters is a password or some other value that you do not wish to appear in your history or in clear, you can declare it of type <tt>password</tt> and JCommander will then ask you to enter it in the console:
    173 
    174 <pre class="brush: java">
    175 public class ArgsPassword {
    176   @Parameter(names = "-password", description = "Connection password", password = true)
    177   private String password;
    178 }
    179 </pre>
    180 
    181 When you run your program, you will get the following prompt:
    182 
    183 <pre class="brush: plain">
    184 Value for -password (Connection password):
    185 </pre>
    186 
    187 You will need to type the value at this point before JCommander resumes.
    188 
    189 <h4>Echo Input</h4>
    190 
    191 In Java 6, by default, you will not be able to see what you type for passwords entered at the prompt (Java 5 and lower will always show the password).  However, you can override this by setting <tt>echoInput</tt> to "true" (default is "false" and this setting only has an effect when <tt>password</tt> is "true"):
    192 <pre class="brush: java">
    193 public class ArgsPassword {
    194   @Parameter(names = "-password", description = "Connection password", password = true, echoInput = true)
    195   private String password;
    196 }
    197 </pre>
    198 
    199 <h2><a class="section" name="Custom_types">Custom types</a></h2>
    200 
    201 <h3>By annotation</h3>
    202 
    203 By default, JCommander parses the command line into basic types only (strings, booleans, integers and longs). Very often, your application actually needs more complex types, such as files, host names, lists, etc... To achieve this, you can write a type converter by implementing the following interface:
    204 
    205 <pre class="brush: java">
    206 public interface IStringConverter&lt;T&gt; {
    207   T convert(String value);
    208 }
    209 </pre>
    210 
    211 For example, here is a converter that turns a string into a <tt>File</tt>:
    212 
    213 <pre class="brush: java">
    214 public class FileConverter implements IStringConverter&lt;File&gt; {
    215   @Override
    216   public File convert(String value) {
    217     return new File(value);
    218   }
    219 }
    220 </pre>
    221 
    222 Then, all you need to do is declare your field with the correct type and specify the converter as an attribute:
    223 
    224 <pre class="brush: java">
    225 @Parameter(names = "-file", converter = FileConverter.class)
    226 File file;
    227 </pre>
    228 
    229 JCommander ships with a few common converters (e.g. one that turns a comma separated list into a <tt>List&lt;String&gt;)</tt>.
    230 
    231 <h3>By factory</h3>
    232 
    233 If the custom types you use appear multiple times in your application, having to specify the converter in each annotation can become tedious. To address this, you can use an <tt>IStringConverterFactory</tt>:
    234 
    235 <pre class="brush: java">
    236 public interface IStringConverterFactory {
    237   &lt;T&gt; Class&lt;? extends IStringConverter&lt;T&gt;&gt; getConverter(Class&lt;T&gt; forType);
    238 }
    239 </pre>
    240 
    241 For example, suppose you need to parse a string representing a host and a port:
    242 
    243 <pre class="brush: plain">
    244 java App -target example.com:8080
    245 </pre>
    246 
    247 You define the holder class :
    248 
    249 <pre class="brush: java">
    250 public class HostPort {
    251   private String host;
    252   private Integer port;
    253 }
    254 </pre>
    255 
    256 and the string converter to create instances of this class:
    257 
    258 <pre class="brush: java">
    259 class HostPortConverter implements IStringConverter&lt;HostPort&gt; {
    260   @Override
    261   public HostPort convert(String value) {
    262     HostPort result = new HostPort();
    263     String[] s = value.split(":");
    264     result.host = s[0];
    265     result.port = Integer.parseInt(s[1]);
    266 
    267     return result;
    268   }
    269 }
    270 </pre>
    271 
    272 The factory is straightforward:
    273 
    274 <pre class="brush: java">
    275 public class Factory implements IStringConverterFactory {
    276   public Class&lt;? extends IStringConverter&lt;?&gt;&gt; getConverter(Class forType) {
    277     if (forType.equals(HostPort.class)) return HostPortConverter.class;
    278     else return null;
    279   }
    280 </pre>
    281 
    282 You can now use the type <tt>HostPort</tt> as a parameter without any <tt>converterClass</tt> attribute:
    283 
    284 <pre class="brush: java">
    285 public class ArgsConverterFactory {
    286   @Parameter(names = "-hostport")
    287   private HostPort hostPort;
    288 }
    289 </pre>
    290 
    291 
    292 All you need to do is add the factory to your JCommander object:
    293 
    294 <pre class="brush: java">
    295   ArgsConverterFactory a = new ArgsConverterFactory();
    296   JCommander jc = new JCommander(a);
    297   jc.addConverterFactory(new Factory());
    298   jc.parse("-hostport", "example.com:8080");
    299 
    300   Assert.assertEquals(a.hostPort.host, "example.com");
    301   Assert.assertEquals(a.hostPort.port.intValue(), 8080);
    302 </pre>
    303 
    304 
    305 Another advantage of using string converter factories is that your factories can come from a dependency injection framework.
    306 
    307 <h2><a class="section" name="Parameter_validation">Parameter validation</a></h2>
    308 
    309 You can ask JCommander to perform early validation on your parameters by providing a class that implements the following interface:
    310 
    311 <pre class="brush:java">
    312 public interface IParameterValidator {
    313  /**
    314    * Validate the parameter.
    315    *
    316    * @param name The name of the parameter (e.g. "-host").
    317    * @param value The value of the parameter that we need to validate
    318    *
    319    * @throws ParameterException Thrown if the value of the parameter is invalid.
    320    */
    321   void validate(String name, String value) throws ParameterException;
    322 }
    323 
    324 </pre>
    325 
    326 Here is an example implementation that will make sure that the parameter is a positive integer:
    327 
    328 <pre class="brush:java">
    329 public class PositiveInteger implements IParameterValidator {
    330  public void validate(String name, String value)
    331       throws ParameterException {
    332     int n = Integer.parseInt(value);
    333     if (n < 0) {
    334       throw new ParameterException("Parameter " + name + " should be positive (found " + value +")");
    335     }
    336   }
    337 }
    338 </pre>
    339 
    340 Specify the name of a class implementing this interface in the <tt>validateWith</tt> attribute of your <tt>@Parameter</tt> annotations:
    341 
    342 <pre class="brush:java">
    343 @Parameter(names = "-age", validateWith = PositiveInteger.class)
    344 private Integer age;
    345 </pre>
    346 
    347 Attempting to pass a negative integer to this option will cause a <tt>ParameterException</tt> to be thrown.
    348 
    349 
    350 <h2><a class="section" name="Main_parameter">Main parameter</a></h2>
    351 So far, all the <tt>@Parameter</tt> annotations we have seen had defined an attribute called <tt>names</tt>. You can define one (and at most one) parameter without any such attribute. This parameter needs to be a <tt>List&lt;String&gt;</tt> and it will contain all the parameters that are not options:
    352 
    353 <pre class="brush: java">
    354 @Parameter(description = "Files")
    355 private List&lt;String&gt; files = new ArrayList&lt;String&gt;();
    356 
    357 @Parameter(names = "-debug", description = "Debugging level")
    358 private Integer debug = 1;
    359 </pre>
    360 
    361 will allow you to parse:
    362 
    363 <pre class="brush: plain">
    364 java Main -debug file1 file2
    365 </pre>
    366 
    367 and the field <tt>files</tt> will receive the strings "file1" and "file2".
    368 
    369 <h2><a class="section" name="Private_parameters">Private parameters</a></h2>
    370 
    371 Parameters can be private:
    372 
    373 <pre class="brush: java">
    374 public class ArgsPrivate {
    375   @Parameter(names = "-verbose")
    376   private Integer verbose = 1;
    377 
    378   public Integer getVerbose() {
    379     return verbose;
    380   }
    381 }
    382 </pre>
    383 
    384 <pre class="brush: java">
    385 ArgsPrivate args = new ArgsPrivate();
    386 new JCommander(args, "-verbose", "3");
    387 Assert.assertEquals(args.getVerbose().intValue(), 3);
    388 </pre>
    389 
    390 <h2><a class="section" name="Separators">Parameter separators</a></h2>
    391 
    392 By default, parameters are separated by spaces, but you can change this setting to allow different separators:
    393 
    394 <pre class="brush: plain">
    395 java Main -log:3
    396 </pre>
    397 
    398 or
    399 
    400 <pre class="brush: plain">
    401 java Main -level=42
    402 </pre>
    403 
    404 You define the separator with the <tt>@Parameters</tt> annotation:
    405 
    406 <pre class="brush: java">
    407 @Parameters(separators = "=")
    408 public class SeparatorEqual {
    409   @Parameter(names = "-level")
    410   private Integer level = 2;
    411 }
    412 </pre>
    413 
    414 
    415 
    416 
    417 
    418 <h2><a class="section" name="Multiple_descriptions">Multiple descriptions</a></h2>
    419 
    420 You can spread the description of your parameters on more than one
    421 class. For example, you can define the following two classes:
    422 
    423 <p>
    424 
    425 <h3 class="sourcetitle">ArgsMaster.java</h3>
    426 <pre class="brush: java">
    427 public class ArgsMaster {
    428   @Parameter(names = "-master")
    429   private String master;
    430 }
    431 </pre>
    432 
    433 <h3 class="sourcetitle">ArgsSlave.java</h3>
    434 <pre class="brush: java">
    435 public class ArgsSlave {
    436   @Parameter(names = "-slave")
    437   private String slave;
    438 }
    439 </pre>
    440 
    441 and pass these two objects to JCommander:
    442 
    443 <pre class="brush: java">
    444 ArgsMaster m = new ArgsMaster();
    445 ArgsSlave s = new ArgsSlave();
    446 String[] argv = { "-master", "master", "-slave", "slave" };
    447 new JCommander(new Object[] { m , s }, argv);
    448 
    449 Assert.assertEquals(m.master, "master");
    450 Assert.assertEquals(s.slave, "slave");
    451 </pre>
    452 
    453 
    454 <h2><a class="section" name="Syntax">@ syntax</a></h2>
    455 
    456 JCommander supports the @ syntax, which allows you to put all your options into a file and pass this file as parameter:
    457 
    458 <p>
    459 
    460 <div class="sourcetitle">/tmp/parameters</div>
    461 <pre class="brush: plain">
    462 -verbose
    463 file1
    464 file2
    465 file3
    466 </pre>
    467 <pre class="brush: plain">
    468 java Main @/tmp/parameters
    469 </pre>
    470 
    471 <h2><a class="section" name="Arities">Arities (multiple values for parameters)</a></h2>
    472 
    473 <h3><a class="section" name="fixed-arities" indent="..">Fixed arities</a></h3>
    474 
    475 If some of your parameters require more than one value, such as the
    476 following example where two values are expected after <tt>-pairs</tt>:
    477 
    478 <pre class="brush: plain">
    479 java Main -pairs slave master foo.xml
    480 </pre>
    481 
    482 then you need to define your parameter with the <tt>arity</tt>
    483 attribute and make that parameter a <tt>List&lt;String&gt;</tt>:
    484 
    485 <pre class="brush: java">
    486 @Parameter(names = "-pairs", arity = 2, description = "Pairs")
    487 private List&lt;String&gt; pairs;
    488 </pre>
    489 
    490 You don't need to specify an arity for parameters of type
    491 <tt>boolean</tt> or <tt>Boolean</tt> (which have a default arity of 0)
    492 and of types <tt>String</tt>, <tt>Integer</tt>, <tt>int</tt>,
    493 <tt>Long</tt> and <tt>long</tt> (which have a default arity of 1).
    494 
    495 <p>
    496 Also, note that only <tt>List&lt;String&gt;</tt> is allowed for
    497 parameters that define an arity. You will have to convert these values
    498 yourself if the parameters you need are of type <tt>Integer</tt> or
    499 other (this limitation is due to Java's erasure).
    500 
    501 <h3><a class="section" name="variable-arities" indent="..">Variable arities</a></h3>
    502 
    503 You can specify that a parameter can receive an indefinite number of parameters, up to the next option. For example:
    504 
    505 <pre class="brush: java">
    506 program -foo a1 a2 a3 -bar
    507 program -foo a1 -bar
    508 </pre>
    509 
    510 Such a parameter must be of type <tt>List&lt;String&gt;</tt> and have the boolean <tt>variableArity</tt> set to <tt>true</tt>
    511 
    512 <pre class="brush: java">
    513 @Parameter(names = "-foo", variableArity = true)
    514 public List&lt;String&gt; foo = new ArrayList&lt;String&gt;();
    515 </pre>
    516 
    517 <h2><a class="section" name="Multiple_option_names">Multiple option names</a></h2>
    518 
    519 You can specify more than one option name:
    520 
    521 <pre class="brush: java">
    522 
    523   @Parameter(names = { "-d", "--outputDirectory" }, description = "Directory")
    524   private String outputDirectory;
    525 
    526 </pre>
    527 
    528 will allow both following syntaxes:
    529 
    530 <pre class="brush: plain">
    531 java Main -d /tmp
    532 java Main --outputDirectory /tmp
    533 </pre>
    534 
    535 <h2><a class="section" name="Other option configurations">Other option configurations</a></h2>
    536 
    537 You can configure how options are looked up in a few different ways:
    538 
    539 <ul>
    540   <li><tt>JCommander#setCaseSensitiveOptions(boolean)</tt>: specify whether options are case sensitive. If you call this method with <tt>false</tt>, then <tt>"-param"</tt> and
    541     <tt>"-PARAM"</tt> are considered equal.
    542   </li>
    543   <li><tt>JCommander#setAllowAbbreviatedOptions(boolean)</tt>: specify whether users can
    544     pass abbreviated options. If you call this method with <tt>true</tt> then users
    545     can pass <tt>"-par"</tt> to specify an option called <tt>-param</tt>. JCommander will
    546     throw a <tt>ParameterException</tt> if the abbreviated name is ambiguous.
    547   </li>
    548 </ul>
    549 
    550 <h2><a class="section" name="Required_and_optional">Required and optional parameters</a></h2>
    551 
    552 If some of your parameters are mandatory, you can use the
    553 <tt>required</tt> attribute (which default to <tt>false</tt>):
    554 
    555 <pre class="brush: java">
    556 
    557   @Parameter(names = "-host", required = true)
    558   private String host;
    559 
    560 </pre>
    561 
    562 If this parameter is not specified, JCommander will throw an exception
    563 telling you which options are missing.
    564 
    565 <h2><a class="section" name="Default_values">Default values</a></h2>
    566 
    567 The most common way to specify a default value for your parameters is to initialize the field at declaration time:
    568 
    569 <pre class="brush: java">
    570 private Integer logLevel = 3;
    571 </pre>
    572 
    573 For more complicated cases, you might want to be able to reuse identical default values across several main classes or be able to specify these default values in a centralized location such as a .properties or an XML fie. In this case, you can use an <tt>IDefaultProvider</tt>
    574 
    575 <pre class="brush: java">
    576 public interface IDefaultProvider {
    577   /**
    578    * @param optionName The name of the option as specified in the names() attribute
    579    * of the @Parameter option (e.g. "-file").
    580    * 
    581    * @return the default value for this option.
    582    */
    583   String getDefaultValueFor(String optionName);
    584 }
    585 </pre>
    586 
    587 By passing an implementation of this interface to your <tt>JCommander</tt> object, you can now control which default value will be used for your options. Note that the value returned by this method will then be passed to a string converter, if any is applicable, thereby allowing you to specify default values for any types you need.
    588 
    589 <p>
    590 
    591 For example, here is a default provider that will assign a default value of 42 for all your parameters except "-debug":
    592 
    593 <pre class="brush: java">
    594 private static final IDefaultProvider DEFAULT_PROVIDER = new IDefaultProvider() {
    595   @Override
    596   public String getDefaultValueFor(String optionName) {
    597     return "-debug".equals(optionName) ? "false" : "42";
    598   }
    599 };
    600 
    601 // ...
    602 
    603 JCommander jc = new JCommander(new Args());
    604 jc.setDefaultProvider(DEFAULT_PROVIDER);
    605 </pre>
    606 
    607 <h2><a class="section" name="Help_parameter">Help parameter</a></h2>
    608 
    609 If one of your parameters is used to display some help or usage, you need use the <tt>help</tt> attribute:
    610 
    611 <pre class="brush: java">
    612   @Parameter(names = "--help", help = true)
    613   private boolean help;
    614 </pre>
    615 
    616 If you omit this boolean, JCommander will instead issue an error message when it tries to validate your command and it finds that you didn't specify some of the required parameters.
    617 
    618 <h2><a class="section" name="Complex">More complex syntaxes (commands)</a></h2>
    619 
    620 Complex tools such as <tt>git</tt> or <tt>svn</tt> understand a whole set of commands, each of which with their own specific syntax:
    621 
    622 <pre class="brush: plain">
    623   git commit --amend -m "Bug fix"
    624 </pre>
    625 
    626 Words such as "commit" above are called "commands" in JCommander, and you can specify them by creating one arg object per command:
    627 
    628 <pre class="brush: java">
    629 @Parameters(separators = "=", commandDescription = "Record changes to the repository")
    630 private class CommandCommit {
    631 
    632   @Parameter(description = "The list of files to commit")
    633   private List&lt;String&gt; files;
    634 
    635   @Parameter(names = "--amend", description = "Amend")
    636   private Boolean amend = false;
    637 
    638   @Parameter(names = "--author")
    639   private String author;
    640 }
    641 </pre>
    642 
    643 <pre class="brush: java">
    644 @Parameters(commandDescription = "Add file contents to the index")
    645 public class CommandAdd {
    646 
    647   @Parameter(description = "File patterns to add to the index")
    648   private List&lt;String&gt; patterns;
    649 
    650   @Parameter(names = "-i")
    651   private Boolean interactive = false;
    652 }
    653 </pre>
    654 
    655 Then you register these commands with your JCommander object. After the parsing phase, you call <tt>getParsedCommand()</tt> on your JCommander object, and based on the command that is returned, you know which arg object to inspect (you can still use a main arg object if you want to support options before the first command appears on the command line):
    656 
    657 <pre class="brush: java">
    658 CommandMain cm = new CommandMain();
    659 JCommander jc = new JCommander(cm);
    660 
    661 CommandAdd add = new CommandAdd();
    662 jc.addCommand("add", add);
    663 CommandCommit commit = new CommandCommit();
    664 jc.addCommand("commit", commit);
    665 
    666 jc.parse("-v", "commit", "--amend", "--author=cbeust", "A.java", "B.java");
    667 
    668 Assert.assertTrue(cm.verbose);
    669 Assert.assertEquals(jc.getParsedCommand(), "commit");
    670 Assert.assertTrue(commit.amend);
    671 Assert.assertEquals(commit.author, "cbeust");
    672 Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java"));
    673 </pre>
    674 
    675 <h2><a class="section" name="Exceptions">Exception</a></h2>
    676 
    677 Whenever JCommander detects an error, it will throw a
    678 <tt>ParameterException</tt>. Note that this is a Runtime Exception,
    679 since your application is probably not initialized correctly at this
    680 point.
    681 
    682 
    683 <h2><a class="section" name="Usage">Usage</a></h2>
    684 
    685 You can invoke <tt>usage()</tt> on the <tt>JCommander</tt> instance that you used to parse your command line in order to generate a summary of all the options that your program understands:
    686 
    687 <pre class="brush: plain">
    688 Usage: &lt;main class&gt; [options] 
    689   Options:
    690     -debug          Debug mode (default: false)
    691     -groups         Comma-separated list of group names to be run
    692   * -log, -verbose  Level of verbosity (default: 1)
    693     -long           A long number (default: 0)
    694 </pre>
    695 
    696 You can customize the name of your program by calling <tt>setProgramName()</tt> on your <tt>JCommander</tt> object.
    697 
    698 Options preceded by an asterisk are required.
    699 
    700 <h2><a class="section" name="Hiding">Hiding parameters</a></h2>
    701 
    702 If you don't want certain parameters to appear in the usage, you can mark them as "hidden":
    703 
    704 <pre class="brush: java">
    705 @Parameter(names = "-debug", description = "Debug mode", hidden = true)
    706 private boolean debug = false;
    707 </pre>
    708 
    709 <h2><a class="section" name="Internationalization">Internationalization</a></h2>
    710 
    711 You can internationalize the descriptions of your parameters.
    712 
    713 <p>
    714 
    715 First you use the <tt>@Parameters</tt> annotation at the top of your class to define the name of your message bundle, and then you use the <tt>descriptionKey</tt> attribute instead of <tt>description</tt> on all the <tt>@Parameters</tt> that require translations. This <tt>descriptionKey</tt> is the key to the string into your message bundle:
    716 
    717 <h3 class="sourcetitle">I18N.java</h3>
    718 <pre class="brush:java">
    719 @Parameters(resourceBundle = "MessageBundle")
    720 private class ArgsI18N2 {
    721   @Parameter(names = "-host", description = "Host", descriptionKey = "host")
    722   String hostName;
    723 }
    724 </pre>
    725 
    726 Your bundle needs to define this key:
    727 
    728 <br>
    729 
    730 <h3 class="sourcetitle">MessageBundle_fr_FR.properties</h3>
    731 <pre class="brush: plain">
    732 host: H&ocirc;te
    733 </pre>
    734 
    735 JCommander will then use the default locale to resolve your descriptions.
    736 
    737 <h2><a class="section" name="Parameter_delegates">Parameter delegates</a></h2>
    738 
    739 If you are writing many different tools in the same project, you will probably find that most of these tools can share configurations. While you can use inheritance with your objects to avoid repeating this code, the restriction to single inheritance of implementation might limit your flexibility. To address this problem, JCommander supports parameter delegates.
    740 
    741 <p>
    742 
    743 When JCommander encounters an object annotated with <tt>@ParameterDelegate</tt> in one of your objects, it acts as if this object had been added as a description object itself:
    744 
    745 <pre class="brush: java">
    746 class Delegate {
    747   @Parameter(names = "-port")
    748   private int port;
    749 }
    750 
    751 class MainParams {
    752   @Parameter(names = "-v")
    753   private boolean verbose;
    754 
    755   @ParametersDelegate
    756   private Delegate delegate = new Delegate();
    757 }
    758 </pre>
    759 
    760 The example above specifies a delegate parameter <tt>Delegate</tt> which is then referenced in <tt>MainParams</tt>. You only need to add a <tt>MainParams</tt> object to your JCommander configuration in order to use the delegate:
    761 
    762 <pre class="brush: java">
    763 MainParams p = new MainParams();
    764 new JCommander(p).parse("-v", "-port", "1234");
    765 Assert.assertTrue(p.isVerbose);
    766 Assert.assertEquals(p.delegate.port, 1234);
    767 </pre>
    768 
    769 <h2><a class="section" name="DynamicParameters">Dynamic parameters</a></h2>
    770 
    771 JCommander allows you to specify parameters that are not known at compile time, such as <tt>"-Da=b -Dc=d"</tt>. Such parameters are specified with the <tt><a href="apidocs/com/beust/jcommander/DynamicParameter.html">@DynamicParameter</a></tt> annotation and must be of type <tt>Map&lt;String, String&gt;</tt>. Dynamic parameters are allowed to appear multiple times on the command line:
    772 
    773 <pre class="brush: java">
    774 @DynamicParameter(names = "-D", description = "Dynamic parameters go here")
    775 private Map&lt;String, String&gt; params = new HashMap&lt;String, String&gt;();
    776 </pre>
    777 
    778 You can specify a different assignment string than <tt>=</tt> by using the attribute <tt>assignment</tt>.
    779 
    780 <h2><a class="section" name="Scala">JCommander in Scala</a></h2>
    781 
    782 Here is a quick example of how to use JCommander in Scala (courtesy of Patrick Linskey):
    783 
    784 <pre class="brush: java">
    785 import java.io.File
    786 import com.beust.jcommander.{JCommander, Parameter}
    787 import collection.JavaConversions._
    788 
    789 object Main {
    790   object Args {
    791     // Declared as var because JCommander assigns a new collection declared
    792     // as java.util.List because that's what JCommander will replace it with.
    793     // It'd be nice if JCommander would just use the provided List so this
    794     // could be a val and a Scala LinkedList.
    795     @Parameter(
    796       names = Array("-f", "--file"),
    797       description = "File to load. Can be specified multiple times.")
    798     var file: java.util.List[String] = null
    799   }
    800 
    801   def main(args: Array[String]): Unit = {
    802     new JCommander(Args, args.toArray: _*)
    803     for (filename <- Args.file) {
    804       val f = new File(filename)
    805       printf("file: %s\n", f.getName)
    806     }
    807   }
    808 }
    809 </pre>
    810 
    811 <h2><a class="section" name="Groovy">JCommander in Groovy</a></h2>
    812 
    813 Here is a quick example of how to use JCommander in Groovy (courtesy of Paul King):
    814 
    815 
    816 <pre class="brush: java">
    817 import com.beust.jcommander.*
    818 
    819 class Args {
    820   @Parameter(names = ["-f", "--file"], description = "File to load. Can be specified multiple times.")
    821   List&lt;String&gt; file
    822 }
    823 
    824 new Args().with {
    825   new JCommander(it, args)
    826   file.each { println "file: ${new File(it).name}" }
    827 }
    828 </pre>
    829 
    830 <h2><a class="section" name="More_examples">More examples</a></h2>
    831 
    832 TestNG uses JCommander to parse its own command line, here is <a href="http://github.com/cbeust/testng/blob/master/src/main/java/org/testng/CommandLineArgs.java">its definition file</a>.
    833 
    834 <h2><a class="section" name="Mailing_list">Mailing list</a></h2>
    835 
    836 Join the <a href="http://groups.google.com/group/jcommander">JCommander Google group</a> if you are interested in discussions about JCommander.
    837 
    838 <h2><a class="section" name="Javadocs">Javadocs</a></h2>
    839 
    840 The Javadocs for JCommander can be found <a href="apidocs/">here</a>.
    841 
    842 <h2><a class="section" name="License">License</a></h2>
    843 
    844 JCommander is released under the <a
    845 href="https://github.com/cbeust/jcommander/blob/master/license.txt">Apache 2.0</a> license.
    846 
    847 <h2><a class="section" name="Download">Download</a></h2>
    848 
    849 You can download JCommander from the following locations:
    850 
    851 <ul>
    852   <li><a href="http://github.com/cbeust/jcommander">Source on github</a></li>
    853   <li>If you are using Maven, add the following dependency to your <tt>pom.xml</tt>:
    854 
    855   <pre class="brush: xml">
    856 
    857 <dependency>
    858   &lt;groupId&gt;com.beust&lt;/groupId&gt;
    859   &lt;artifactId&gt;jcommander&lt;/artifactId&gt;
    860   &lt;version&gt;1.30&lt;/version&gt;
    861 </dependency>
    862   </pre>
    863 
    864 </ul>
    865 
    866 </body>
    867 
    868 <script type="text/javascript" src="http://beust.com/toc.js"></script>
    869 <script type="text/javascript"> generateToc(); </script>
    870 
    871 </html>
    872