What is a good way of parsing command line arguments in Java?
-
5See args4j and a detailed example how to use it: http://martin-thoma.com/how-to-parse-command-line-arguments-in-java/ – Martin Thoma Feb 14 '13 at 12:46
-
Looks like I'm pretty late to this party, but I wrote a command-line argument handler for Java and put it on GitHub: [MainArgsHandler](https://github.com/Bobulous/uk.org.bobulous.java.startup). As for the thread being closed, I think this is a very helpful thread, but it should possibly be migrated to the Stack Exchange Programmers site for general programming discussion. – Bobulous Aug 03 '14 at 14:24
-
@RedGlyph - It looks like SO/SE need to simplify their rules. The question should have been: `How to parse java command line arguments?`. But no one really want to write code to do this but rather use a tool. But searching for tools and the likes isn't constructive :( – AlikElzin-kilaka May 05 '15 at 05:09
-
13Voted for reopening. @AlikElzin: Indeed, they do need to review their moderating process. I suspect there's a badge for closing so many questions, and that it's luring want-to-be-moderators to be overzealous. – RedGlyph Jul 05 '15 at 17:00
-
9This question is a honeypot for bad/one-line answers and tool recommendations. It should remain closed. – JAL Jul 06 '15 at 18:46
-
You can also find libraries tagged with "Command Line Parsers" in [mvnrepository.com](http://mvnrepository.com/open-source/command-line-parsers) – Guillaume Husta Nov 09 '15 at 14:09
-
I wouldn't recommend using `Apache Common CLI` library, as it is non-threadsafe. It uses stateful classes with static variables and methods to do internal work (e.g. `OptionBuilder`) and should only be used in single-threaded strongly controlled situations. – Jakub Aug 29 '12 at 09:56
-
15It's good to keep in mind CLI library is not thread-safe. However, I would assume command-line parsing is usually done in a single thread during application startup, and then, depending on parameters, other threads may be started. – Alexey Ivanov Aug 30 '12 at 06:49
21 Answers
Check these out:
Or roll your own:
For instance, this is how you use commons-cli
to parse 2 string arguments:
import org.apache.commons.cli.*;
public class Main {
public static void main(String[] args) throws Exception {
Options options = new Options();
Option input = new Option("i", "input", true, "input file path");
input.setRequired(true);
options.addOption(input);
Option output = new Option("o", "output", true, "output file");
output.setRequired(true);
options.addOption(output);
CommandLineParser parser = new DefaultParser();
HelpFormatter formatter = new HelpFormatter();
CommandLine cmd = null;//not a good practice, it serves it purpose
try {
cmd = parser.parse(options, args);
} catch (ParseException e) {
System.out.println(e.getMessage());
formatter.printHelp("utility-name", options);
System.exit(1);
}
String inputFilePath = cmd.getOptionValue("input");
String outputFilePath = cmd.getOptionValue("output");
System.out.println(inputFilePath);
System.out.println(outputFilePath);
}
}
usage from command line:
$> java -jar target/my-utility.jar -i asd
Missing required option: o
usage: utility-name
-i,--input <arg> input file path
-o,--output <arg> output file

- 3,039
- 1
- 24
- 30

- 330,807
- 53
- 334
- 373
-
59Note that unlike many other Apache libraries, Apache CLI has no dependencies. – Vladimir Dyuzhev Jul 09 '12 at 12:43
-
10The one downside to many apache-commons projects is they get fewer and fewer commits and eventually end up obsoleted. – Brett Ryan Sep 17 '12 at 15:55
-
5Here's the "Usage Scenarios" page for the Apache CLI project, detailing how to quickly start using it: http://commons.apache.org/cli/usage.html – Brad Parks Dec 03 '12 at 14:48
-
I don't suppose there is one exactly like Args4J/JCommander except where you define an interface and annotate the methods? I never have been able to grow fond of classes which "spooky initialise" private fields... – Hakanai Jan 06 '15 at 04:44
-
-
1@BrettRyan it's up to everyone in the community to make sure Apache projects stay alive. Open source isn't easy, it takes a village, other cliches here, please. – WattsInABox May 07 '18 at 17:15
-
20@RemkoPopma your picocli library looks just great and thank you for doing it, really. But I consider what you are doing here and in other posts (edit accepted answers and promote your library at the top of it without even disclosing it's an edit not from post's original author and it's your lib) a horrible horrible abuse of your moderation powers. Flagging this to other mods. – Alexander Malakhov Apr 08 '19 at 11:30
-
2@AlexanderMalakhov I want to rectify one thing: [anyone](https://stackoverflow.com/help/privileges) can edit (no moderation powers needed) and editing is [encouraged](https://stackoverflow.com/help/editing) to keep posts relevant and up to date (the current answer is 10 years old). That said, good edits should be balanced to avoid being considered spam and must disclose affiliation. Thank you for pointing that out. – Remko Popma Apr 11 '19 at 23:45
-
I tried commons-cli, jsap, and argparse4j, for about an hour, and liked jsap the most. Thanks! – Erhannis Aug 28 '21 at 23:52
-
In the past I used commons-cli, but was really unhappy. Now I found a better solution with picocli as mentioned below ;-) – jazz64 May 14 '22 at 11:57
Take a look at the more recent JCommander.
I created it. I’m happy to receive questions or feature requests.

- 4,945
- 31
- 38

- 15,480
- 2
- 55
- 55
-
Using it now and loving it! I would like to see automatic parsing of the - and -- for single char vs string arguments. i.e. "h" vs "-h" and "help" vs "--help" – NorthIsUp Oct 25 '10 at 23:44
-
9Glad you like JCommander :-) I didn't want to add too much semantic to how the flags are treated, so you just need to add synonyms in the annotations you use: @Parameter(names = { "-h", "--help" }) I thought it's a reasonable compromise. – Cedric Beust Oct 26 '10 at 02:13
-
15Great tool. Powerful, flexible, and you don't have to deal with the annoying, traditional option parsers. – Ian Gilham Oct 07 '11 at 16:17
-
3Yup, i think i would have wrote my own command line argument parser the exact same way you wrote JCommander. Great work. – SRG Mar 10 '12 at 00:01
-
10@CedricBeust, this is a brilliant library, I thank you very much. Since we can define our own Args classes that can then be passed around without any dependency on a libraries class it makes it extremely flexible. – Brett Ryan Sep 17 '12 at 15:50
-
2
-
Like the library, but you should update the link! Some of the links in that one are broken (Javadocs, for example). – vmrob Apr 21 '14 at 17:15
-
I am new to Java, but still this package is so easy to use and worked like charm. Great package – Talespin_Kit May 19 '16 at 18:32
-
Downside is that it doesn't have automatic help message generation :( – Qix - MONICA WAS MISTREATED Jun 21 '16 at 09:26
-
1@Qix: It does: just call the `usage()` method on your JCommander object and you'll see a help screen with all your parameters and their description. – Cedric Beust Jun 22 '16 at 13:53
-
Great tool, but can't handle unordered usage help (to be ordered by the field order), so I use args4j instead of. – Daniel Hári Feb 07 '17 at 21:23
-
@DanielHári I'm open to adding this to JCommander, although since the field order can't be reliably instrospected, it would probably be an integer attribute on the `@Parameter` annotation. – Cedric Beust Feb 08 '17 at 22:23
-
@CedricBeust Why can't reliably introspected? Other libraries can solve field order by default and without integer parameter. See: JAXB, Gson, Args4j, etc... – Daniel Hári Feb 11 '17 at 18:34
-
I mean that just because you list your fields in a certain order in your class doesn't mean the introspection API will return them in that order. You will need to specify them manually with an annotation. I can add that, feel free to file an issue on github. – Cedric Beust Feb 12 '17 at 19:31
-
I just released a new JCommander that allows you to order the options in the usage(): http://jcommander.org/#_usage – Cedric Beust Feb 12 '17 at 21:26
-
I like JCommander. Is it possible to have just a class-level annotation (specify a CLI style), so as to avoid all annotations on each fields, like lombok does? – Nan Wang Mar 24 '20 at 08:45
-
Does it support sub-programs/sub-parsers? I would like to have different arguments for `myprog foo ...` and different for `myprog bar`. Is it possible? – Danon Jun 03 '20 at 08:27
I have been trying to maintain a list of Java CLI parsers.
- Airline
- Active Fork: https://github.com/rvesse/airline
- argparse4j
- argparser
- args4j
- clajr
- cli-parser
- CmdLn
- Commandline
- DocOpt.java
- dolphin getopt
- DPML CLI (Jakarta Commons CLI2 fork)
- Dr. Matthias Laux
- Jakarta Commons CLI
- jargo
- jargp
- jargs
- java-getopt
- jbock
- JCLAP
- jcmdline
- jcommander
- jcommando
- jewelcli (written by me)
- JOpt simple
- jsap
- naturalcli
- Object Mentor CLI article (more about refactoring and TDD)
- parse-cmd
- ritopt
- Rop
- TE-Code Command
- picocli has ANSI colorized usage help and autocomplete

- 155
- 1
- 7

- 7,158
- 6
- 37
- 57
-
8@Ben Flynn hehe, there are some quite surprising and interesting shaped wheels in there. I guess its a mostly harmless way to show that there's many more than one way to do it! – lexicalscope Oct 31 '11 at 18:05
-
18I note the author of JOpt Simple maintains a very similar list! What we need text is to turn these lists into a table, listing features and points of interest, so us poor users can make an informed choice. – Tom Anderson Feb 24 '12 at 13:23
-
Feel free to add https://github.com/Softhouse/jargo to that list. It's pretty stable by now. Some early feedback from this community would be greatly appreciated. – jontejj Apr 26 '13 at 16:04
-
1I've built [Rop](http://central.maven.org/maven2/com/github/ryenus/rop/) - [github.com/ryenus/rop](https://github.com/ryenus/rop), which features annotation based solution that you declare commands and options via plain classes and fields, pretty much a declarative way to build command line parsers. it can build either Git (single-cmd) or Maven (multi-cmd) like apps. – ryenus Dec 18 '13 at 07:24
-
1
-
15Most of the projects listed are essentially abandonware. After going through the list I'd say the big hitters, that are actively maintained and popular, seem to commons-cli, jcommander, args4j, jopt-simple and picocli. Apologies to the authors of things like argparse4j and cli-parser - I had to make a somewhat arbitrary ranking, and chose a top five, clearly other projects in the list are popular and still under active development too. – George Hawkins Sep 25 '17 at 13:07
-
1...and here is a [video of a truck with 72 wheels](https://www.youtube.com/watch?v=B_ksZ4gLsfA) -__________________________________- – Andrey Tyukin Oct 14 '18 at 14:08
-
4I challenge someone to include the date of the last stable release of each parser. – Sledge Apr 01 '19 at 02:47
-
Your jewel-cli library is very nice. It's very unique compared to other libraries I've come across because using interfaces remove a lot of bloat and allow for nice multiple inheritance. – retodaredevil Sep 09 '19 at 21:31
It is 2022, time to do better than Commons CLI... :-)
Should you build your own Java command line parser, or use a library?
Many small utility-like applications probably roll their own command line parsing to avoid the additional external dependency. picocli may be an interesting alternative.
Picocli is a modern library and framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It lives in 1 source file so apps can include it as source to avoid adding a dependency.
It supports colors, autocompletion, subcommands, and more. Written in Java, usable from Groovy, Kotlin, Scala, etc.
Features:
- Annotation based: declarative, avoids duplication and expresses programmer intent
- Convenient: parse user input and run your business logic with one line of code
- Strongly typed everything - command line options as well as positional parameters
- POSIX clustered short options (
<command> -xvfInputFile
as well as<command> -x -v -f InputFile
) - Fine-grained control: an arity model that allows a minimum, maximum and variable number of parameters, e.g,
"1..*"
,"3..5"
- Subcommands (can be nested to arbitrary depth)
- Feature-rich: composable arg groups, splitting quoted args, repeatable subcommands, and many more
- User-friendly: usage help message uses colors to contrast important elements like option names from the rest of the usage help to reduce the cognitive load on the user
- Distribute your app as a GraalVM native image
- Works with Java 5 and higher
- Extensive and meticulous documentation
The usage help message is easy to customize with annotations (without programming). For example:
(source)
I couldn't resist adding one more screenshot to show what usage help messages are possible. Usage help is the face of your application, so be creative and have fun!
Disclaimer: I created picocli. Feedback or questions very welcome.

- 35,130
- 11
- 92
- 114
-
8Pure genius! It's a shame this answer is buried at the bottom. Apache Commons CLI is verbose, buggy, and hasn't been updated in a long time. And I don't want to use Google's CLI parser because I don't want targeted advertisements based on my command line argument usage history. But it looks a little more verbose than picocli anyway. – Pete Sep 01 '18 at 04:10
-
4I second @Pete here... I went through the list above which was a complete waste of time with this buried at the bottom. This should be the top answer by a mile. Great job! My requirements couldn't be covered by apache CLI or most of these other parsers. They were challenging even for picocli but it was able to give me the closest thing to the syntax/behavior I wanted and was flexible enough to hack to what I really needed. As a bonus it's great looking thanks to the ANSI stuff. – Shai Almog Oct 01 '19 at 11:25
-
1@ShaiAlmog The top-voted answer is 10 years old and outdated. I agree that recommending Commons CLI in 2019 is misleading IMHO. Please consider [rewriting](https://stackoverflow.com/help/editing) the top answer to make it more up to date. – Remko Popma Oct 02 '19 at 09:51
-
I see you already tried that, I don't think that will work for me either... If you would have chosen a name like 1Picoli we could have sorted the 3rd answer alphabetically ;-) – Shai Almog Oct 03 '19 at 02:53
-
I think the reason my change was reverted is that I didn’t disclose my affiliation (that I’m the author). Other people should not have that issue. – Remko Popma Oct 03 '19 at 02:59
-
1
-
1this is the correct answer ! you cannot go wrong with this library – Peter Thomas Mar 17 '20 at 07:48
-
1Thank you Remko (one up from me)! I tried your picocli and was able to use it in a simple tool of mine. Now I'm really happy (with commons-cli in the past, I always had to write a wrapper to keep my code clean: one extra class, too much extra code). – jazz64 May 14 '22 at 12:03
-
1before I found this library (picocli) I thought that there was no better option for creating cli programs other than cobra and golang, now it's different there is another powerful option for cli programs (of course I mean picocli and java) – SinaMobasheri Jul 29 '22 at 13:12
Someone pointed me to args4j lately which is annotation based. I really like it!

- 67,400
- 29
- 193
- 254

- 12,971
- 3
- 33
- 45
-
1+1 for Args4J! Extremely human-friendly, flexible, and understandable. I think it should be the standard go-to library for building Java CLI apps. – Zearin Jul 18 '13 at 15:46
-
Great that it can handle unordered (sorted by field order) usage print, that JCommander can't, and it's more flexible. – Daniel Hári Feb 07 '17 at 21:26
-
@DanielHári Just for information, this functionnality was added in JCommander (sometime along late february 2017). – Turtle Nov 30 '17 at 12:56
-
Suggestion: You might want to add an example to your answer, which would be more helpful than just an external link. – not2savvy Sep 23 '21 at 13:23
I've used JOpt and found it quite handy: http://jopt-simple.sourceforge.net/
The front page also provides a list of about 8 alternative libraries, check them out and pick the one that most suits your needs.

- 23,950
- 10
- 60
- 73
I know most people here are going to find 10 million reasons why they dislike my way, but nevermind. I like to keep things simple, so I just separate the key from the value using a '=' and store them in a HashMap like this:
Map<String, String> argsMap = new HashMap<>();
for (String arg: args) {
String[] parts = arg.split("=");
argsMap.put(parts[0], parts[1]);
}
You could always maintain a list with the arguments you are expecting, to help the user in case he forgot an argument or used a wrong one... However, if you want too many features this solution is not for you anyway.

- 342
- 4
- 6
This is Google's command line parsing library open-sourced as part of the Bazel project. Personally I think it's the best one out there, and far easier than Apache CLI.
https://github.com/pcj/google-options
Installation
Bazel
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
sha1 = "85d54fe6771e5ff0d54827b0a3315c3e12fdd0c7",
)
Gradle
dependencies {
compile 'com.github.pcj:google-options:1.0.0'
}
Maven
<dependency>
<groupId>com.github.pcj</groupId>
<artifactId>google-options</artifactId>
<version>1.0.0</version>
</dependency>
Usage
Create a class that extends OptionsBase
and defines your @Option
(s).
package example;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;
import java.util.List;
/**
* Command-line options definition for example server.
*/
public class ServerOptions extends OptionsBase {
@Option(
name = "help",
abbrev = 'h',
help = "Prints usage info.",
defaultValue = "true"
)
public boolean help;
@Option(
name = "host",
abbrev = 'o',
help = "The server host.",
category = "startup",
defaultValue = ""
)
public String host;
@Option(
name = "port",
abbrev = 'p',
help = "The server port.",
category = "startup",
defaultValue = "8080"
)
public int port;
@Option(
name = "dir",
abbrev = 'd',
help = "Name of directory to serve static files.",
category = "startup",
allowMultiple = true,
defaultValue = ""
)
public List<String> dirs;
}
Parse the arguments and use them.
package example;
import com.google.devtools.common.options.OptionsParser;
import java.util.Collections;
public class Server {
public static void main(String[] args) {
OptionsParser parser = OptionsParser.newOptionsParser(ServerOptions.class);
parser.parseAndExitUponError(args);
ServerOptions options = parser.getOptions(ServerOptions.class);
if (options.host.isEmpty() || options.port < 0 || options.dirs.isEmpty()) {
printUsage(parser);
return;
}
System.out.format("Starting server at %s:%d...\n", options.host, options.port);
for (String dirname : options.dirs) {
System.out.format("\\--> Serving static files at <%s>\n", dirname);
}
}
private static void printUsage(OptionsParser parser) {
System.out.println("Usage: java -jar server.jar OPTIONS");
System.out.println(parser.describeOptions(Collections.<String, String>emptyMap(),
OptionsParser.HelpVerbosity.LONG));
}
}

- 30,738
- 21
- 105
- 131

- 595
- 6
- 6
-
Hi Paul. When I read your answer or your project documentation I do not have any idea what kind of command line it can handle. For instance, you may provide something like `myexecutable -c file.json -d 42 --outdir ./out`. And I do not see how you define short/long/description options... Cheers – oHo Sep 13 '17 at 16:25
Take a look at the Commons CLI project, lots of good stuff in there.

- 44,628
- 11
- 58
- 63
Yeap.
I think you're looking for something like this: http://commons.apache.org/cli
The Apache Commons CLI library provides an API for processing command line interfaces.

- 196,001
- 113
- 385
- 569
If you are already using Spring Boot, argument parsing comes out of the box.
If you want to run something after startup, implement the ApplicationRunner
interface:
@SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(ApplicationArguments args) {
args.containsOption("my-flag-option"); // test if --my-flag-option was set
args.getOptionValues("my-option"); // returns values of --my-option=value1 --my-option=value2
args.getOptionNames(); // returns a list of all available options
// do something with your args
}
}
Your run
method will be invoked after the context has started up successfully.
If you need access to the arguments before you fire up your application context, you can just simply parse the application arguments manually:
@SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
ApplicationArguments arguments = new DefaultApplicationArguments(args);
// do whatever you like with your arguments
// see above ...
SpringApplication.run(Application.class, args);
}
}
And finally, if you need access to your arguments in a bean, just inject the ApplicationArguments
:
@Component
public class MyBean {
@Autowired
private ApplicationArguments arguments;
// ...
}

- 9,812
- 7
- 72
- 81
Maybe these
JArgs command line option parsing suite for Java - this tiny project provides a convenient, compact, pre-packaged and comprehensively documented suite of command line option parsers for the use of Java programmers. Initially, parsing compatible with GNU-style 'getopt' is provided.
ritopt, The Ultimate Options Parser for Java - Although, several command line option standards have been preposed, ritopt follows the conventions prescribed in the opt package.

- 35,130
- 11
- 92
- 114

- 2,670
- 2
- 21
- 28
I wrote another one: http://argparse4j.sourceforge.net/
Argparse4j is a command line argument parser library for Java, based on Python's argparse.

- 404
- 5
- 4
-
Welcome to Stack Overflow! Thanks for posting your answer! Please be sure to read the [FAQ on Self-Promotion](http://stackoverflow.com/faq#promotion) carefully. – Andrew Barber Sep 04 '12 at 14:27
If you are familiar with gnu getopt, there is a Java port at: http://www.urbanophile.com/arenn/hacking/download.htm.
There appears to be a some classes that do this:

- 30,738
- 21
- 105
- 131

- 9,841
- 8
- 50
- 90
airline @ Github looks good. It is based on annotation and is trying to emulate Git command line structures.

- 30,738
- 21
- 105
- 131

- 4,917
- 2
- 19
- 8
Argparse4j is best I have found. It mimics Python's argparse libary which is very convenient and powerful.

- 30,738
- 21
- 105
- 131

- 3,821
- 2
- 24
- 41
I want to show you my implementation: ReadyCLI
Advantages:
- for lazy programmers: a very small number of classes to learn, just see the two small examples on the README in the repository and you are already at 90% of learning; just start coding your CLI/Parser without any other knowledge; ReadyCLI allows coding CLIs in the most natural way;
- it is designed with Developer Experience in mind; it largely uses the Builder design pattern and functional interfaces for Lambda Expressions, to allow a very quick coding;
- it supports Options, Flags and Sub-Commands;
- it allows to parse arguments from command-line and to build more complex and interactive CLIs;
- a CLI can be started on Standard I/O just as easily as on any other I/O interface, such as sockets;
- it gives great support for documentation of commands.
I developed this project as I needed new features (options, flag, sub-commands) and that could be used in the simplest possible way in my projects.

- 72
- 3
If you want something lightweight (jar size ~ 20 kb) and simple to use, you can try argument-parser. It can be used in most of the use cases, supports specifying arrays in the argument and has no dependency on any other library. It works for Java 1.5 or above. Below excerpt shows an example on how to use it:
public static void main(String[] args) {
String usage = "--day|-d day --mon|-m month [--year|-y year][--dir|-ds directoriesToSearch]";
ArgumentParser argParser = new ArgumentParser(usage, InputData.class);
InputData inputData = (InputData) argParser.parse(args);
showData(inputData);
new StatsGenerator().generateStats(inputData);
}
More examples can be found here

- 21
- 3
As one of the comments mentioned earlier (https://github.com/pcj/google-options) would be a good choice to start with.
One thing I want to add-on is:
1) If you run into some parser reflection error, please try use a newer version of the guava. in my case:
maven_jar(
name = "com_google_guava_guava",
artifact = "com.google.guava:guava:19.0",
server = "maven2_server",
)
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
server = "maven2_server",
)
maven_server(
name = "maven2_server",
url = "http://central.maven.org/maven2/",
)
2) When running the commandline:
bazel run path/to/your:project -- --var1 something --var2 something -v something
3) When you need the usage help, just type:
bazel run path/to/your:project -- --help

- 21
- 1
For Spring users, we should mention also https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/SimpleCommandLinePropertySource.html and his twin brother https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/JOptCommandLinePropertySource.html (JOpt implementation of the same functionality). The advantage in Spring is that you can directly bind the command line arguments to attributes, there is an example here https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/CommandLinePropertySource.html

- 1,954
- 1
- 25
- 27
Take a look at Spring Shell
Spring Shell’s features include
- A simple, annotation driven, programming model to contribute custom commands
- Use of Spring Boot auto-configuration functionality as the basis for a command plugin strategy
- Tab completion, colorization, and script execution
- Customization of command prompt, shell history file name, handling of results and errors
- Dynamic enablement of commands based on domain specific criteria
- Integration with the bean validation API
- Already built-in commands, such as clear screen, gorgeous help, exit
- ASCII art Tables, with formatting, alignment, fancy borders, etc.

- 4,930
- 1
- 46
- 76