Home » Java » How to parse command line arguments in Java?

How to parse command line arguments in Java?

Posted by: admin November 2, 2017 Leave a comment

Questions:

What is a good way of parsing command line arguments in Java?

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;

        try {
            cmd = parser.parse(options, args);
        } catch (ParseException e) {
            System.out.println(e.getMessage());
            formatter.printHelp("utility-name", options);

            System.exit(1);
            return;
        }

        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

Questions:
Answers:

Take a look at the more recent JCommander.

I created it. I’m happy to receive questions or feature requests.

Questions:
Answers:

I have been trying to maintain a list of java CLI parsers.

Questions:
Answers:

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.

Questions:
Answers:

Someone pointed me to args4j lately which is annotation based. I really like it!

Questions:
Answers:

Take a look at the Commons CLI project, lots of good stuff in there.

Questions:
Answers:

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.

Questions:
Answers:

Maybe these

  • picocli “a mighty tiny command line interface”. Picocli is a command line argument parser library for Java – with ANSI colored usage help and command line completion. Nested subcommands, detailed user manual and ability to include as source to avoid depending on picocli’s jar are also noteworthy.
  • 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.

Questions:
Answers:

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: http://docs.sun.com/source/816-5618-10/netscape/ldap/util/GetOpt.html, http://xml.apache.org/xalan-j/apidocs/org/apache/xalan/xsltc/cmdline/getopt/GetOpt.html

Questions:
Answers:

You might find this meta-article of unhappiness interesting as a jumping off point:

http://furiouspurpose.blogspot.com/2008/07/command-line-parsing-libraries-for-java.html

Questions:
Answers:

I wrote another one: http://argparse4j.sourceforge.net/

Argparse4j is a command line argument parser library for Java, based on Python’s argparse.

Questions:
Answers:

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));
  }

}

https://github.com/pcj/google-options

Questions:
Answers:

airline @ Github looks good. Based on annotation and trying to emulate git command line structures.

Questions:
Answers:

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.

Questions:
Answers:

Buy or build?

Many small utility-like applications probably roll their own command line parsing to avoid the additional external dependency.

picocli may be interesting. It is designed to be included as source as a simpler alternative to shading jars into an uberjar.

Another feature you may like is its colorized usage help.

Minimal usage help with ANSI colors

Parser features:

  • Annotation based: parsing is 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)
  • 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)
  • Works with Java 5 and higher

The usage help message is easy to customize with annotations (without programming). For example:

Extended usage help message (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!

picocli demo

Disclaimer: I created picocli. Feedback or questions very welcome.

Questions:
Answers:

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

Questions:
Answers:

Argparse4j is best I have found. It mimics python argparse libary which is very convinient and powerfull.