Command line arguments using apache common cli and maven
I am trying to build small jar using common cli but i am getting this error after building jar and when i run this command.
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/cli/Options at com.kir.App.main(App.java:10) Caused by: java.lang.ClassNotFoundException: org.apache.commons.cli.Options at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) . 1 more
package com.kir; import org.apache.commons.cli.Options; public class App < public static void main(String[] args) < Options options = new Options(); >>
4.0.0 kircom validator 1.0-SNAPSHOT commons-cli commons-cli 1.4 org.apache.maven.plugins maven-shade-plugin 3.1.1 package shade com.kir.App
Note: I am using IntelliJ. Initially, I thought that jar doesn’t include dependency jar while packing. But when I tested with JDBC connection, it worked fine.
How to build CLI from Maven project like mvn, gradle etc?
You can take a look at the appassembler-maven-plugin which can create a script based on the name and supports creating a shell and a bat variant.
For Maven, take a look at the Maven Exec Plugin, you can do something like:
. org.codehaus.mojo exec-maven-plugin 1.6.0 . java com.mycompany.BlaBla start . myproperty myvalue . .
You can then run something like mvn exec:java
There is something similar with Gradle via the Exec Task.
Though I don’t know the specific use case related to your question, it may be a better idea to use a bash script or another way specifically designed to run software. Maven and Gradle are build automation tools, their primary goal is not to run your program but compile your code, run tests and create artifact (among other things).
Use the library Apache Commons CLI. It’s a library there you can build OptionLists (arguments, parameters, etc.) like this.
package CLi; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.poi.EncryptedDocumentException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; public class CLi < /** * @see http://www.thinkplexx.com/blog/simple-apache-commons-cli-example- java-command-line-arguments-parsing * @see http://stackoverflow.com/a/10798945 * @see http://stackoverflow.com/questions/36166630/apache-commons-cli- not-parsing-as-expected * * Link to Java-Library: * @see https://commons.apache.org/proper/commons-cli/ */ /** * Variables */ private String[] args; private Options options = new Options(); private HelpFormatter formater; private CommandLineParser parser; private CommandLine cmd; private Scanner console; private String cmdLine; private boolean noParam; /** * Constructor. * @param args - The command-line arguments. */ public CLi(String[] args) < this.args = args; buildCLIOptions(); >public void parse() throws Exception < if(args.length == 0) < noParam = true; args = scanParams(); >else < try < parser = new DefaultParser(); cmd = null; cmd = parser.parse(options, args); /** * Print help. */ if (cmd.hasOption("help")) < noParam = false; help(); >/** * Shutdown. */ if (cmd.hasOption("exit")) < noParam = false; System.exit(0); >> > > /** * @throws Exception */ public void help() throws Exception < /** * This prints out some help */ formater = new HelpFormatter(); formater.printHelp("Main", options); System.out.println(" "); noParam = true; scanParams(); >/** * Scan params. * @return the Parameters * @throws Exception */ public String[] scanParams() throws Exception < System.out.println("Ready. Waiting for input. "); System.out.println(" "); console = new Scanner(System.in); while(noParam) < cmdLine = console.nextLine(); args = cmdLine.replace(" -", " #-").split(" #"); parse(); >console.close(); return args; > public void buildCLIOptions() < options.addOption("exit", "exit", false, "Exiting application."); options.addOption("help", "help", false, "show help."); >>
Introduction to Commons CLI
Simple but common use-cases: create options, create option, parse command line arguments, print usage, and more using Apache Commons CLI.
Overview
When developing Java application for command line interface (CLI), it’s essential to parse input argument correctly. However, you don’t want to reinvent the wheel because it’s not easy and you’ve more important tasks to do, right? In my own experience, I found Apache Commons CLI very useful. I used it when maintaining nuxeoctl, and when I developing command line tools for side-projects.
Today, I would like to introduce Apache Commons CLI to you. After reading this article, you will understand:
- Prerequisite
- How to create “options”
- How to create individual “option”
- How to parse command line arguments
- How to query the parsed result
- How to show usage and help
Prerequisite
If you want to use Apache Commons CLI in your Java project, you need to declared the following dependency in Maven:
Create Options
“Options” is the main entry-point of the library. “Options” represents a collection of “Option” objects, which describe the possible options for a command-line. It may flexibly parse long and short options, with or without values. Additionally, it may parse only a portion of a command line, allowing for flexible multi-stage parsing.
Options options = new Options();
Once done, you can add one or several new “Option” into “Options”, and parse “Options” afterwards.
Create Individual Option
“Option” describes a single command-line option. It maintains different information such as its short name, its long name, argument requirement, description etc. There are two ways to create a new option: via an instance of “Options”, or via option builder.
Create option via “Options”. Class org.apache.commons.cli.Options provides different methods for creating a new option. Here are some of the examples:
// Create an option with short name // "-v" for enabling the verbose mode. options.addOption("v", "Enable verbose mode"); // Create an option with short name // "-f" for configuring filepath. It // has an argument (hasArg=true). options.addOption("f", true, "Config filepath"); // Create an option with short name // "-i" or long name "--ignore", for // specifying the case-sensitive case. options.addOption("i", "ignore", false, "Ignore case");
Create option via builder. Class org.apache.commons.cli.Option.Builder can also be used to create an “Option” using descriptive methods.
Option opt = Option.builder("a") .longOpt("all") .desc("Display all") .build(); options.addOption(opt);
Parse Command Lines
Parsing command lines can be done by using CommandLineParser and an instance of “Options”. If the arguments are parsed successfully, the method will return an instance of “CommandLine”. Else, it will throw a checked exception.
public static void main(String[] args) Options options = . ; CommandLineParser parser = new DefaultParser(); try CommandLine cmd = parser.parse(options, args); > catch (ParseException e) // . > >
Query Command Line
Once you successfully created the command line instance, you can query it: to see if an option has been passed, or to retrieve the option value.
Query if the option exist:
if (cmd.hasOption("v")) // enable verbose mode. >
If exists, return the option value. Note that, if the option does not exist, the return value will be null . Be careful about NullPointerException…
if (cmd.hasOption("f")) String path = cmd.getOptionValue("f"); // return null if the option does not // exist in command line >
If your application support default value, you can give it to the method as the 2nd parameter:
String e = cmd.getOptionValue("encoding", "utf-8");
Print Usage and Help
Use HelpFormatter to generate the help with usage. The layout of the help message looks like this:
header ----- body (options) ----- footer
By default, the header is the command line syntax, provided by user. The body is generated by the library. The footer is ignored.
HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("cmd", newOptions());
usage: cmd -a,--all Display all -f Config filepath -i,--ignore Ignore case -v Enable verbose mode
However, you can enable the auto-usage for header, so that the options generated and included in header.
formatter.printHelp("cmd", newOptions(), true);
usage: cmd [-a] [-f ] [-i] [-v] -a,--all Display all -f Config filepath -i,--ignore Ignore case -v Enable verbose mode
Conclusion
In this article, we see how to create “Options” and “Option” in Apache Command CLI, how to parse “Options” using parser and exception handling, how to query the result ( CommandLine ), and print help and usage. The source code is available at mincong-h:blog/2019-08-06-cli, under directory “cli”. Hope you enjoy this article, see you the next time!
References
- Apache, “Common CLI — Home”, Apache Commons, 2019. https://commons.apache.org/proper/commons-cli/index.html
- Apache, “Commons CLI — Javadoc”, Apache Commons, 2019. https://commons.apache.org/proper/commons-cli/apidocs/org/apache/commons/cli/package-summary.html
- Nuxeo, “nuxeoctl and Control Panel Usage”, Nuxeo, 2019. https://doc.nuxeo.com/nxdoc/nuxeoctl-and-control-panel-usage/
This work is licensed under a Attribution 4.0 International license.