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é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<String> parameters = new ArrayList<String>(); 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<String> hosts = new ArrayList<String>(); 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<T> { 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<File> { 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<String>)</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 <T> Class<? extends IStringConverter<T>> getConverter(Class<T> 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<HostPort> { 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<? extends IStringConverter<?>> 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<String></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<String> files = new ArrayList<String>(); 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<String></tt>: 484 485 <pre class="brush: java"> 486 @Parameter(names = "-pairs", arity = 2, description = "Pairs") 487 private List<String> 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<String></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<String></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<String> foo = new ArrayList<String>(); 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<String> 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<String> 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: <main class> [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ô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<String, String></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<String, String> params = new HashMap<String, String>(); 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<String> 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 <groupId>com.beust</groupId> 859 <artifactId>jcommander</artifactId> 860 <version>1.30</version> 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