While passing arguments in Java through CLI we generally pass like
java -cp jar classname \"args[0]\" \"args[1]\"
I want to
You can do this easily just the same as you would for parsing normal program arguments. Here is a small example:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
System.out.println(Arrays.toString(args));
String host = args[1];
String user = args[3];
String password = args[5];
System.out.println("Host: " + host);
System.out.println("User: " + user);
System.out.println("Password: " + password);
}
}
If I run this program with the following command:
java Main --host hostname --user username --password password
This is the output:
[--host, hostname, --user, username, --password, password]
Host: hostname
User: username
Password: password
Alternatively, you can use a library like the Apache Commons CLI which includes a lot of utilities to parse command line arguments and options:
import org.apache.commons.cli.*;
public class Main {
public static void main(String[] args) {
Options options = new Options();
Option host = Option.builder()
.longOpt("host")
.hasArg()
.valueSeparator(' ')
.build();
Option user = Option.builder()
.longOpt("user")
.hasArg()
.valueSeparator(' ')
.build();
Option password = Option.builder()
.longOpt("password")
.hasArg()
.valueSeparator(' ')
.build();
options.addOption(host);
options.addOption(user);
options.addOption(password);
CommandLineParser parser = new DefaultParser();
try {
CommandLine line = parser.parse(options, args);
System.out.println("Host: " + line.getOptionValue("host"));
System.out.println("User: " + line.getOptionValue("user"));
System.out.println("Pass: " + line.getOptionValue("password"));
} catch (ParseException e) {
System.err.println("Parsing failed. Reason: " + e.getMessage());
}
}
}
However, this route requires you to add the Apache Commons CLI to your classpath and include it with your program (or add it as a dependency for a dependency management program like Maven or Gradle). It might seem like more work, but the Apache Commons CLI is very powerful and flexible and can make parsing a lot of command line options much less painful.
Here is the output of that sample class with the Apache Commons CLI:
Host: hostname
User: username
Password: password
You can use commons-cli library as follows:
import org.apache.commons.cli.*;
public class Main {
public static void main(String[] args) throws Exception {
Options options = new Options();
Option host = new Option("h", "host", true, "host address");
host .setRequired(true);
options.addOption(host);
Option user = new Option("u", "user", true, "user login");
user.setRequired(true);
options.addOption(user);
Option password = new Option("p", "password", true, "user's password");
password.setRequired(true);
options.addOption(password);
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("my-program", options);
System.exit(1);
return;
}
String inputHost = cmd.getOptionValue("host");
String inputUser = cmd.getOptionValue("user");
String inputPassword = cmd.getOptionValue("password");
}
}
In 2019, there are better libraries for building CLI applications than Apache Commons CLI.
Consider using picocli to get an ultra-compact program that automatically has colored help and optionally has command line autocompletion.
Your program could look like this:
@Command(name = "myapp", description = "Does cool stuff.", mixinStandardHelpOptions = true)
class MyApp implements Callable<Integer> {
@Option(names = {"-s", "--host"}, required = true, description = "host name")
String hostname;
@Option(names = {"-u", "--user"}, required = true, description = "user name")
String username;
@Option(names = {"-p", "--password"}, interactive = true, description = "pass phrase")
char[] password;
public Integer call() {
// business logic here...
System.out.printf("host=%s, user=%s%n", hostname, username);
return 0; // exit code signalling normal termination
}
public static void main(String[] args) {
// in 1 line, parse the args, handle errors,
// handle requests for help/version info, call the business logic
// and obtain an exit status code:
int exitCode = new CommandLine(new MyApp()).execute(args);
System.exit(exitCode);
}
}
Some advantages of using picocli:
Callable
or Runnable
, you can set up and execute your program in one line of code in the main
method. The business logic goes in the call
(or run
) method.mixinStandardHelpOptions = true
means that --help
and --version
options are added automatically. These work as expected without requiring further coding.char[]
array so it can be nulled out from memory when the work is done - these are good security practices.See Autocomplete for Java Command Line Applications for adding TAB autocompletion to this program.
Disclaimer: I maintain picocli.
Use longOpt
.
Example:
options.addOption(Option.builder().argName("date")
.desc("The start date (YYYY-MM-DD) from where to retrieve information.").hasArg(true).longOpt("sd")
.numberOfArgs(1).required(false).build());