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é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<String> parameters = new ArrayList<>(); 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<String> hosts = new ArrayList<>(); 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<T> { 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<File> { 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<String>)</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 <T> Class<? extends IStringConverter<T>> getConverter(Class<T> 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<HostPort> { 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<? extends IStringConverter<?>> 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<?> getConverterInstance(Parameter parameter, Class<?> 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<String></tt> and it will contain all the parameters that are not options: 409 410<pre class="brush: java"> 411@Parameter(description = "Files") 412private List<String> files = new ArrayList<>(); 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<String></tt>: 545 546<pre class="brush: java"> 547@Parameter(names = "-pairs", arity = 2, description = "Pairs") 548private List<String> 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<String></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<String></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<String> foo = new ArrayList<>(); 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<String> 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<String> 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: <main class> [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ô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<String, String></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<String, String> params = new HashMap<>(); 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<String> 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 <groupId>com.beust</groupId> 926 <artifactId>jcommander</artifactId> 927 <version>1.48</version> 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