← Back to home

Announcing JCommander 1.0

import com.beust.jcommander.Parameter; public class JCommanderTest { @Parameter public List parameters = Lists.newArrayList(); @Parameter(names = { “-log”, “-verbose” }, description = “Level of verbosity”) public Integer verbose = 1; @Parameter(names = “-groups”, description = “Comma-separated list of group names to be run”) public String groups; @Parameter(names = “-debug”, description = “Debug mode”) public boolean debug = false; }

Recently, I got tired of having to handle command line parsing manually. I took a look at existing frameworks and all the ones that I found (JOpts, JArgs, commons-cli) suffered from the same limitations that I was trying to avoid: they barely cut down on the boiler plate code and they are not very type safe. So I came up with my own framework, which I called JCommander. The snippet of code above should give you a pretty good idea of what JCommander looks like, and if you need more information, just head over to the main site. I have already integrated JCommander in TestNG and it has already reduced the code base to handle this simple task significantly. Let me know what you think.

Comments (26)

Simone Tripodi

Hi Cedric, that simply rocks :) Looking forward to use it!!!

Eugene Kuleshov

Kohsuke beat you to that 5 years ago. :) http://weblogs.java.net/blog/kohsuke/archive/2005/05/parsing_command.html

Oscar

Nice. I think the name is a bit misleading ( or my brain preestablished associations are ) I thought it was some sort of FileManager, probably JLineArgs but naaaahh... This is a very good use of annotations, and I have always hated command line parsing, up to the point where I prefer using system properties: -Ddebug=false but this will definitely will change the way we do command line args processing ( or should I say, the way we won't do that processing anymore ) You just miss to put in your description "... allowing you to focus on your business, instead of command line processing" :) The only question I have, in the sample from TestNG, I don't see a "main" method, how is the "String[]args" bind to this?

Cedric

Eugene: indeed! I missed that project when I looked around, I was surprised nobody had tried this before.

Cedric

Oscar: this class is just the container that holds the values, look here for the actual use: http://github.com/cbeust/testng/blob/master/src/main/java/org/testng/TestNG.java#L1080

Itay Maman

Args4j, https://args4j.dev.java.net, should also be mentioned, it is taking a similar approach for solving this problem.

Patrick

JewelCli does something similar; my favorite, stylistically: http://jewelcli.sourceforge.net/usage.html.

Michael Lee

Nice! I did not know that there is arg4j or jcommander. I wrote a wrapper over 'Jopt' to do annotation based parsing.

Wouter Lievens

Looks very nice. I'll give it a try next time I have to do this. Don't forget releasing it into a maven repository for easy importing!

Dominique Gallot

Nice use of the annotations ! I quickly check the binary and the source, and I was not able to see the licence term. Is it Apache Licence like TestNg ?

Cedric

Dominique: Yes, I just updated the pom.xml to specify the Apache 2.0 license.

Pedro Newsletter 13.07.2010 « Pragmatic Programmer Issues – pietrowski.info

[...] command line parsing library from Cedric. JCommander. BTW there are plenty of comments so I suppose all the java command line libraries are [...]

Julien Viet

I'm using Args4j for annotating Groovy commans for CRaSH (Content Repository Shell). I'll give a try to jcommander to see how it fits!

Emmanuel Bourg

Fine but how do you support i18n with this approach?

Jesse Kuhnert

Looks cool, may try replacing jopt with this as well. Always felt a little dirty looking at all that jopt code I had to write for something meant to simplify. Don't think it actually amounted to less code, just more flexible ordering/omission of arguments. More like the Cedric I respect/admire. :)

syllant

I also use JewelCli which is very close, but JCommander seems to better handle required/optional options and long/short names. I'll try it.

Simone Tripodi

Also Reinier Zwitserloot from Project Lombok is maintaining a similar project on github: http://github.com/rzwitserloot/com.zwitserloot.cmdreader

rod

I think there is a little mistake on the project page (List management description): @Parameter(names = "-hosts", description = "Level of verbosity") public List hosts = new ArrayList(); should be: @Parameter(names = "-host", description = "Level of verbosity") public List hosts = new ArrayList();

Nathan

Password input support would be super-nice. Lots of apps do this, e.g., `mysql -p`: you are prompted to enter a password and it won't show up in your command history.

Sam Pullara

I can echo that this is a good idea: http://code.google.com/p/cli-parser/ You can read about it here: http://www.javarants.com/2005/12/24/java-annotations-make-declarative-programming-easy/

Nagesh

Sam's http://code.google.com/p/cli-parser/ does static classes, delimited arrays, parameters as well as methods too.

syllant

+1 for password input support :)

Rafael Naufal

Cedric, the attributes annotated with @Parameter need to be public or it is possible to be private?

Cedric Pronzato

Hello, I think there is a little typo on 'Lists' chapter on the project page. @Parameter(names = "-host", description = "Level of verbosity") public List hosts = new ArrayList(); should be: @Parameter(names = "-host", description = "List of hosts to connect to") public List hosts = new ArrayList();

Cedric Pronzato

And another comment, I have not yet tested the framework, I am just reading the spec: It is about list and arity, does an arity of 2 imply 2 mandatory arguments or it can be 0,1,2 ? And then is no arity attribute mean any number of arguments?

pay irs credit card

without equal expos?.