• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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: July 6th, 2015
56    </td>
57  </tr>
58  <tr><td align="right"><a href="mailto:cedric@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
69JCommander is a very small Java framework that makes it trivial to parse command line parameters.
70<p>
71You annotate fields with descriptions of your options:
72
73<pre class="brush: java">
74import com.beust.jcommander.Parameter;
75
76public class JCommanderExample {
77  @Parameter
78  private List&lt;String&gt; parameters = new ArrayList&lt;&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
91and then you simply ask JCommander to parse:
92
93<pre class="brush: java">
94JCommanderExample jct = new JCommanderExample();
95String[] argv = { "-log", "2", "-groups", "unit" };
96new JCommander(jct, argv);
97
98Assert.assertEquals(jct.verbose.intValue(), 2);
99</pre>
100
101An example that mirrors more of what you might see in the "real world" might
102look like this:
103
104<pre class="brush: java">
105class Main {
106    @Parameter(names={"--length", "-l"})
107    int length;
108    @Parameter(names={"--pattern", "-p"})
109    int pattern;
110
111    public static void main(String ... args) {
112        Main main = new Main();
113        new JCommander(main, args);
114        main.run();
115    }
116
117    public void run() {
118        System.out.printf("%d %d", length, pattern);
119    }
120}
121</pre>
122
123If you were to run <code>java Main -l 512 --pattern 2</code>, this would
124output:
125
126<pre>512 2</pre>
127
128<h2><a class="section" name="Types_of_options">Types of options</a></h2>
129
130The 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...).
131
132<h4>Boolean</h4>
133
134When 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:
135
136<pre class="brush: java">
137@Parameter(names = "-debug", description = "Debug mode")
138private boolean debug = false;
139</pre>
140
141Such 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>.
142
143<p>
144
145  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:
146
147  <pre class="brush: java">
148    @Parameter(names = "-debug", description = "Debug mode", arity = 1)
149    private boolean debug = true;
150  </pre>
151
152  Invoke with either of:
153
154  <pre class="brush: plain">
155    program -debug true
156    program -debug false
157  </pre>
158
159<h4>String, Integer, Long</h4>
160
161When 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:
162
163<pre class="brush: java">
164@Parameter(names = "-log", description = "Level of verbosity")
165private Integer verbose = 1;
166</pre>
167
168<pre class="brush: plain">
169java Main -log 3
170</pre>
171
172will cause the field <tt>verbose</tt> to receive the value 3, however:
173
174<pre class="brush: plain">
175java Main -log test
176</pre>
177
178will cause an exception to be thrown.
179
180<h4>Lists</h4>
181
182When 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:
183
184<pre class="brush: java">
185@Parameter(names = "-host", description = "The host")
186private List&lt;String&gt; hosts = new ArrayList&lt;&gt;();
187</pre>
188
189will allow you to parse the following command line:
190
191<pre class="brush: plain">
192java Main -host host1 -verbose -host host2
193</pre>
194
195When JCommander is done parsing the line above, the field <tt>hosts</tt> will contain the strings "host1" and "host2".
196
197<h4>Password</h4>
198
199If 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:
200
201<pre class="brush: java">
202public class ArgsPassword {
203  @Parameter(names = "-password", description = "Connection password", password = true)
204  private String password;
205}
206</pre>
207
208When you run your program, you will get the following prompt:
209
210<pre class="brush: plain">
211Value for -password (Connection password):
212</pre>
213
214You will need to type the value at this point before JCommander resumes.
215
216<h4>Echo Input</h4>
217
218In 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"):
219<pre class="brush: java">
220public class ArgsPassword {
221  @Parameter(names = "-password", description = "Connection password", password = true, echoInput = true)
222  private String password;
223}
224</pre>
225
226<h2><a class="section" name="Custom_types">Custom types</a></h2>
227
228<h3>By annotation</h3>
229
230By 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:
231
232<pre class="brush: java">
233public interface IStringConverter&lt;T&gt; {
234  T convert(String value);
235}
236</pre>
237
238For example, here is a converter that turns a string into a <tt>File</tt>:
239
240<pre class="brush: java">
241public class FileConverter implements IStringConverter&lt;File&gt; {
242  @Override
243  public File convert(String value) {
244    return new File(value);
245  }
246}
247</pre>
248
249Then, all you need to do is declare your field with the correct type and specify the converter as an attribute:
250
251<pre class="brush: java">
252@Parameter(names = "-file", converter = FileConverter.class)
253File file;
254</pre>
255
256JCommander ships with a few common converters (e.g. one that turns a comma separated list into a <tt>List&lt;String&gt;)</tt>.
257
258<h3>By factory</h3>
259
260If 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>:
261
262<pre class="brush: java">
263public interface IStringConverterFactory {
264  &lt;T&gt; Class&lt;? extends IStringConverter&lt;T&gt;&gt; getConverter(Class&lt;T&gt; forType);
265}
266</pre>
267
268For example, suppose you need to parse a string representing a host and a port:
269
270<pre class="brush: plain">
271java App -target example.com:8080
272</pre>
273
274You define the holder class :
275
276<pre class="brush: java">
277public class HostPort {
278  private String host;
279  private Integer port;
280}
281</pre>
282
283and the string converter to create instances of this class:
284
285<pre class="brush: java">
286class HostPortConverter implements IStringConverter&lt;HostPort&gt; {
287  @Override
288  public HostPort convert(String value) {
289    HostPort result = new HostPort();
290    String[] s = value.split(":");
291    result.host = s[0];
292    result.port = Integer.parseInt(s[1]);
293
294    return result;
295  }
296}
297</pre>
298
299The factory is straightforward:
300
301<pre class="brush: java">
302public class Factory implements IStringConverterFactory {
303  public Class&lt;? extends IStringConverter&lt;?&gt;&gt; getConverter(Class forType) {
304    if (forType.equals(HostPort.class)) return HostPortConverter.class;
305    else return null;
306  }
307</pre>
308
309You can now use the type <tt>HostPort</tt> as a parameter without any <tt>converterClass</tt> attribute:
310
311<pre class="brush: java">
312public class ArgsConverterFactory {
313  @Parameter(names = "-hostport")
314  private HostPort hostPort;
315}
316</pre>
317
318
319All you need to do is add the factory to your JCommander object:
320
321<pre class="brush: java">
322  ArgsConverterFactory a = new ArgsConverterFactory();
323  JCommander jc = new JCommander(a);
324  jc.addConverterFactory(new Factory());
325  jc.parse("-hostport", "example.com:8080");
326
327  Assert.assertEquals(a.hostPort.host, "example.com");
328  Assert.assertEquals(a.hostPort.port.intValue(), 8080);
329</pre>
330
331
332Another advantage of using string converter factories is that your factories can come from a dependency injection framework.
333
334
335<h3>By instance factory</h3>
336
337Since version 1.57, instance factories are supported:
338
339<pre class="brush: java">
340public interface IStringConverterInstanceFactory {
341    IStringConverter&lt;?&gt; getConverterInstance(Parameter parameter, Class&lt;?&gt; forType);
342}
343</pre>
344
345This allows to return converters using
346<a href="https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html">anonymous classes</a>,
347<a href="https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html">Java 8 lambda expressions</a>,
348among others.
349
350<h2><a class="section" name="Parameter_validation">Parameter validation</a></h2>
351
352Parameter validation can be performed in two different ways: at the individual parameter level or globally.
353
354<h3><a class="section" indent=".." id="individual_validation">Individual parameter validation</a></h3>
355You can ask JCommander to perform early validation on your parameters by providing a class that implements the following interface:
356
357<pre class="brush:java">
358public interface IParameterValidator {
359 /**
360   * Validate the parameter.
361   *
362   * @param name The name of the parameter (e.g. "-host").
363   * @param value The value of the parameter that we need to validate
364   *
365   * @throws ParameterException Thrown if the value of the parameter is invalid.
366   */
367  void validate(String name, String value) throws ParameterException;
368}
369
370</pre>
371
372Here is an example implementation that will make sure that the parameter is a positive integer:
373
374<pre class="brush:java">
375public class PositiveInteger implements IParameterValidator {
376 public void validate(String name, String value)
377      throws ParameterException {
378    int n = Integer.parseInt(value);
379    if (n < 0) {
380      throw new ParameterException("Parameter " + name + " should be positive (found " + value +")");
381    }
382  }
383}
384</pre>
385
386Specify the name of a class implementing this interface in the <tt>validateWith</tt> attribute of your <tt>@Parameter</tt> annotations:
387
388<pre class="brush:java">
389@Parameter(names = "-age", validateWith = PositiveInteger.class)
390private Integer age;
391</pre>
392
393Attempting to pass a negative integer to this option will cause a <tt>ParameterException</tt> to be thrown.
394
395
396<h3><a class="section" indent=".." id="global_validation">Global parameter validation</a></h3>
397
398After parsing your parameters with JCommander, you might want to perform additional validation
399across these parameters, such as making sure that two mutually exclusive parameters are not
400both specified. Because of all the potential combinations involved in such validation,
401JCommander does not provide any annotation-based solution to perform this validation because such
402an approach would necessarily be very limited by the very nature of Java annotations. Instead,
403you should simple perform this validation in Java on all the arguments that JCommander
404just parsed.
405
406
407<h2><a class="section" name="Main_parameter">Main parameter</a></h2>
408So 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:
409
410<pre class="brush: java">
411@Parameter(description = "Files")
412private List&lt;String&gt; files = new ArrayList&lt;&gt;();
413
414@Parameter(names = "-debug", description = "Debugging level")
415private Integer debug = 1;
416</pre>
417
418will allow you to parse:
419
420<pre class="brush: plain">
421java Main -debug file1 file2
422</pre>
423
424and the field <tt>files</tt> will receive the strings "file1" and "file2".
425
426<h2><a class="section" name="Private_parameters">Private parameters</a></h2>
427
428Parameters can be private:
429
430<pre class="brush: java">
431public class ArgsPrivate {
432  @Parameter(names = "-verbose")
433  private Integer verbose = 1;
434
435  public Integer getVerbose() {
436    return verbose;
437  }
438}
439</pre>
440
441<pre class="brush: java">
442ArgsPrivate args = new ArgsPrivate();
443new JCommander(args, "-verbose", "3");
444Assert.assertEquals(args.getVerbose().intValue(), 3);
445</pre>
446
447<h2><a class="section" name="Separators">Parameter separators</a></h2>
448
449By default, parameters are separated by spaces, but you can change this setting to allow different separators:
450
451<pre class="brush: plain">
452java Main -log:3
453</pre>
454
455or
456
457<pre class="brush: plain">
458java Main -level=42
459</pre>
460
461You define the separator with the <tt>@Parameters</tt> annotation:
462
463<pre class="brush: java">
464@Parameters(separators = "=")
465public class SeparatorEqual {
466  @Parameter(names = "-level")
467  private Integer level = 2;
468}
469</pre>
470
471
472
473
474
475<h2><a class="section" name="Multiple_descriptions">Multiple descriptions</a></h2>
476
477You can spread the description of your parameters on more than one
478class. For example, you can define the following two classes:
479
480<p>
481
482<h3 class="sourcetitle">ArgsMaster.java</h3>
483<pre class="brush: java">
484public class ArgsMaster {
485  @Parameter(names = "-master")
486  private String master;
487}
488</pre>
489
490<h3 class="sourcetitle">ArgsSlave.java</h3>
491<pre class="brush: java">
492public class ArgsSlave {
493  @Parameter(names = "-slave")
494  private String slave;
495}
496</pre>
497
498and pass these two objects to JCommander:
499
500<pre class="brush: java">
501ArgsMaster m = new ArgsMaster();
502ArgsSlave s = new ArgsSlave();
503String[] argv = { "-master", "master", "-slave", "slave" };
504new JCommander(new Object[] { m , s }, argv);
505
506Assert.assertEquals(m.master, "master");
507Assert.assertEquals(s.slave, "slave");
508</pre>
509
510
511<h2><a class="section" name="Syntax">@ syntax</a></h2>
512
513JCommander supports the @ syntax, which allows you to put all your options into a file and pass this file as parameter:
514
515<p>
516
517<div class="sourcetitle">/tmp/parameters</div>
518<pre class="brush: plain">
519-verbose
520file1
521file2
522file3
523</pre>
524<pre class="brush: plain">
525java Main @/tmp/parameters
526</pre>
527
528<p>The file is read using the default charset unless <code>JCommander#setAtFileCharset</code> had been called.</p>
529
530<p>Ths feature can be disabled by calling <code>JCommander#setExpandAtSign</code>.</p>
531
532<h2><a class="section" name="Arities">Arities (multiple values for parameters)</a></h2>
533
534<h3><a class="section" name="fixed-arities" indent="..">Fixed arities</a></h3>
535
536If some of your parameters require more than one value, such as the
537following example where two values are expected after <tt>-pairs</tt>:
538
539<pre class="brush: plain">
540java Main -pairs slave master foo.xml
541</pre>
542
543then you need to define your parameter with the <tt>arity</tt>
544attribute and make that parameter a <tt>List&lt;String&gt;</tt>:
545
546<pre class="brush: java">
547@Parameter(names = "-pairs", arity = 2, description = "Pairs")
548private List&lt;String&gt; pairs;
549</pre>
550
551You don't need to specify an arity for parameters of type
552<tt>boolean</tt> or <tt>Boolean</tt> (which have a default arity of 0)
553and of types <tt>String</tt>, <tt>Integer</tt>, <tt>int</tt>,
554<tt>Long</tt> and <tt>long</tt> (which have a default arity of 1).
555
556<p>
557Also, note that only <tt>List&lt;String&gt;</tt> is allowed for
558parameters that define an arity. You will have to convert these values
559yourself if the parameters you need are of type <tt>Integer</tt> or
560other (this limitation is due to Java's erasure).
561
562<h3><a class="section" name="variable-arities" indent="..">Variable arities</a></h3>
563
564You can specify that a parameter can receive an indefinite number of parameters, up to the next option. For example:
565
566<pre class="brush: java">
567program -foo a1 a2 a3 -bar
568program -foo a1 -bar
569</pre>
570
571Such a parameter must be of type <tt>List&lt;String&gt;</tt> and have the boolean <tt>variableArity</tt> set to <tt>true</tt>
572
573<pre class="brush: java">
574@Parameter(names = "-foo", variableArity = true)
575public List&lt;String&gt; foo = new ArrayList&lt;&gt;();
576</pre>
577
578<h2><a class="section" name="Multiple_option_names">Multiple option names</a></h2>
579
580You can specify more than one option name:
581
582<pre class="brush: java">
583
584  @Parameter(names = { "-d", "--outputDirectory" }, description = "Directory")
585  private String outputDirectory;
586
587</pre>
588
589will allow both following syntaxes:
590
591<pre class="brush: plain">
592java Main -d /tmp
593java Main --outputDirectory /tmp
594</pre>
595
596<h2><a class="section" name="Other option configurations">Other option configurations</a></h2>
597
598You can configure how options are looked up in a few different ways:
599
600<ul>
601  <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
602    <tt>"-PARAM"</tt> are considered equal.
603  </li>
604  <li><tt>JCommander#setAllowAbbreviatedOptions(boolean)</tt>: specify whether users can
605    pass abbreviated options. If you call this method with <tt>true</tt> then users
606    can pass <tt>"-par"</tt> to specify an option called <tt>-param</tt>. JCommander will
607    throw a <tt>ParameterException</tt> if the abbreviated name is ambiguous.
608  </li>
609</ul>
610
611<h2><a class="section" name="Required_and_optional">Required and optional parameters</a></h2>
612
613If some of your parameters are mandatory, you can use the
614<tt>required</tt> attribute (which default to <tt>false</tt>):
615
616<pre class="brush: java">
617
618  @Parameter(names = "-host", required = true)
619  private String host;
620
621</pre>
622
623If this parameter is not specified, JCommander will throw an exception
624telling you which options are missing.
625
626<h2><a class="section" name="Default_values">Default values</a></h2>
627
628The most common way to specify a default value for your parameters is to initialize the field at declaration time:
629
630<pre class="brush: java">
631private Integer logLevel = 3;
632</pre>
633
634For 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>
635
636<pre class="brush: java">
637public interface IDefaultProvider {
638  /**
639   * @param optionName The name of the option as specified in the names() attribute
640   * of the @Parameter option (e.g. "-file").
641   *
642   * @return the default value for this option.
643   */
644  String getDefaultValueFor(String optionName);
645}
646</pre>
647
648By 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.
649
650<p>
651
652For example, here is a default provider that will assign a default value of 42 for all your parameters except "-debug":
653
654<pre class="brush: java">
655private static final IDefaultProvider DEFAULT_PROVIDER = new IDefaultProvider() {
656  @Override
657  public String getDefaultValueFor(String optionName) {
658    return "-debug".equals(optionName) ? "false" : "42";
659  }
660};
661
662// ...
663
664JCommander jc = new JCommander(new Args());
665jc.setDefaultProvider(DEFAULT_PROVIDER);
666</pre>
667
668<h2><a class="section" name="Help_parameter">Help parameter</a></h2>
669
670If one of your parameters is used to display some help or usage, you need use the <tt>help</tt> attribute:
671
672<pre class="brush: java">
673  @Parameter(names = "--help", help = true)
674  private boolean help;
675</pre>
676
677If 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.
678
679<h2><a class="section" name="Complex">More complex syntaxes (commands)</a></h2>
680
681Complex tools such as <tt>git</tt> or <tt>svn</tt> understand a whole set of commands, each of which with their own specific syntax:
682
683<pre class="brush: plain">
684  git commit --amend -m "Bug fix"
685</pre>
686
687Words such as "commit" above are called "commands" in JCommander, and you can specify them by creating one arg object per command:
688
689<pre class="brush: java">
690@Parameters(separators = "=", commandDescription = "Record changes to the repository")
691private class CommandCommit {
692
693  @Parameter(description = "The list of files to commit")
694  private List&lt;String&gt; files;
695
696  @Parameter(names = "--amend", description = "Amend")
697  private Boolean amend = false;
698
699  @Parameter(names = "--author")
700  private String author;
701}
702</pre>
703
704<pre class="brush: java">
705@Parameters(commandDescription = "Add file contents to the index")
706public class CommandAdd {
707
708  @Parameter(description = "File patterns to add to the index")
709  private List&lt;String&gt; patterns;
710
711  @Parameter(names = "-i")
712  private Boolean interactive = false;
713}
714</pre>
715
716Then 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):
717
718<pre class="brush: java">
719CommandMain cm = new CommandMain();
720JCommander jc = new JCommander(cm);
721
722CommandAdd add = new CommandAdd();
723jc.addCommand("add", add);
724CommandCommit commit = new CommandCommit();
725jc.addCommand("commit", commit);
726
727jc.parse("-v", "commit", "--amend", "--author=cbeust", "A.java", "B.java");
728
729Assert.assertTrue(cm.verbose);
730Assert.assertEquals(jc.getParsedCommand(), "commit");
731Assert.assertTrue(commit.amend);
732Assert.assertEquals(commit.author, "cbeust");
733Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java"));
734</pre>
735
736<h2><a class="section" name="Exceptions">Exception</a></h2>
737
738Whenever JCommander detects an error, it will throw a
739<tt>ParameterException</tt>. Note that this is a Runtime Exception,
740since your application is probably not initialized correctly at this
741point.
742
743
744<h2><a class="section" name="Usage">Usage</a></h2>
745
746You 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:
747
748<pre class="brush: plain">
749Usage: &lt;main class&gt; [options]
750  Options:
751    -debug          Debug mode (default: false)
752    -groups         Comma-separated list of group names to be run
753  * -log, -verbose  Level of verbosity (default: 1)
754    -long           A long number (default: 0)
755</pre>
756
757You can customize the name of your program by calling <tt>setProgramName()</tt> on your <tt>JCommander</tt> object.
758
759Options preceded by an asterisk are required.
760
761<h2><a class="section" name="Hiding">Hiding parameters</a></h2>
762
763If you don't want certain parameters to appear in the usage, you can mark them as "hidden":
764
765<pre class="brush: java">
766@Parameter(names = "-debug", description = "Debug mode", hidden = true)
767private boolean debug = false;
768</pre>
769
770<h2><a class="section" name="Internationalization">Internationalization</a></h2>
771
772You can internationalize the descriptions of your parameters.
773
774<p>
775
776First 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:
777
778<h3 class="sourcetitle">I18N.java</h3>
779<pre class="brush:java">
780@Parameters(resourceBundle = "MessageBundle")
781private class ArgsI18N2 {
782  @Parameter(names = "-host", description = "Host", descriptionKey = "host")
783  String hostName;
784}
785</pre>
786
787Your bundle needs to define this key:
788
789<br>
790
791<h3 class="sourcetitle">MessageBundle_fr_FR.properties</h3>
792<pre class="brush: plain">
793host: H&ocirc;te
794</pre>
795
796JCommander will then use the default locale to resolve your descriptions.
797
798<h2><a class="section" name="Parameter_delegates">Parameter delegates</a></h2>
799
800If 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.
801
802<p>
803
804When 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:
805
806<pre class="brush: java">
807class Delegate {
808  @Parameter(names = "-port")
809  private int port;
810}
811
812class MainParams {
813  @Parameter(names = "-v")
814  private boolean verbose;
815
816  @ParametersDelegate
817  private Delegate delegate = new Delegate();
818}
819</pre>
820
821The 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:
822
823<pre class="brush: java">
824MainParams p = new MainParams();
825new JCommander(p).parse("-v", "-port", "1234");
826Assert.assertTrue(p.isVerbose);
827Assert.assertEquals(p.delegate.port, 1234);
828</pre>
829
830<h2><a class="section" name="DynamicParameters">Dynamic parameters</a></h2>
831
832JCommander 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:
833
834<pre class="brush: java">
835@DynamicParameter(names = "-D", description = "Dynamic parameters go here")
836private Map&lt;String, String&gt; params = new HashMap&lt;&gt;();
837</pre>
838
839You can specify a different assignment string than <tt>=</tt> by using the attribute <tt>assignment</tt>.
840
841<h2><a class="section" name="Scala">JCommander in Scala</a></h2>
842
843Here is a quick example of how to use JCommander in Scala (courtesy of Patrick Linskey):
844
845<pre class="brush: java">
846import java.io.File
847import com.beust.jcommander.{JCommander, Parameter}
848import collection.JavaConversions._
849
850object Main {
851  object Args {
852    // Declared as var because JCommander assigns a new collection declared
853    // as java.util.List because that's what JCommander will replace it with.
854    // It'd be nice if JCommander would just use the provided List so this
855    // could be a val and a Scala LinkedList.
856    @Parameter(
857      names = Array("-f", "--file"),
858      description = "File to load. Can be specified multiple times.")
859    var file: java.util.List[String] = null
860  }
861
862  def main(args: Array[String]): Unit = {
863    new JCommander(Args, args.toArray: _*)
864    for (filename <- Args.file) {
865      val f = new File(filename)
866      printf("file: %s\n", f.getName)
867    }
868  }
869}
870</pre>
871
872<h2><a class="section" name="Groovy">JCommander in Groovy</a></h2>
873
874Here is a quick example of how to use JCommander in Groovy (courtesy of Paul King):
875
876
877<pre class="brush: java">
878import com.beust.jcommander.*
879
880class Args {
881  @Parameter(names = ["-f", "--file"], description = "File to load. Can be specified multiple times.")
882  List&lt;String&gt; file
883}
884
885new Args().with {
886  new JCommander(it, args)
887  file.each { println "file: ${new File(it).name}" }
888}
889</pre>
890
891<h2><a class="section" name="More_examples">More examples</a></h2>
892
893TestNG 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>.
894
895<h2><a class="section" name="Mailing_list">Mailing list</a></h2>
896
897Join the <a href="http://groups.google.com/group/jcommander">JCommander Google group</a> if you are interested in discussions about JCommander.
898
899<h2><a class="section" name="Javadocs">Javadocs</a></h2>
900
901The Javadocs for JCommander can be found <a href="apidocs/">here</a>.
902
903<h2><a class="section" name="License">License</a></h2>
904
905JCommander is released under the <a
906href="https://github.com/cbeust/jcommander/blob/master/license.txt">Apache 2.0</a> license.
907
908<h2><a class="section" name="Download">Download</a></h2>
909
910You can download JCommander from the following locations:
911
912<ul>
913  <li><a href="http://github.com/cbeust/jcommander">Source on github</a></li>
914  <li>Gradle
915
916  <pre class="brush: plain">
917    compile "com.beust:jcommander:1.48"
918  </pre>
919
920  <li>Maven:
921
922  <pre class="brush: xml">
923
924<dependency>
925  &lt;groupId&gt;com.beust&lt;/groupId&gt;
926  &lt;artifactId&gt;jcommander&lt;/artifactId&gt;
927  &lt;version&gt;1.48&lt;/version&gt;
928</dependency>
929  </pre>
930
931</ul>
932
933</body>
934
935<script type="text/javascript" src="http://beust.com/toc.js"></script>
936<script type="text/javascript"> generateToc(); </script>
937
938</html>
939