- Knowledge Base
- Java Tutorials
- Core Java Tutorials
- Java 8 Tutorials
- Enterprise Java Tutorials
- Spring Tutorials
- Spring Boot Tutorials
- Spring Data Tutorials
- Spring Integration Tutorials
- Spring MVC Tutorials
- Spring Security Tutorials
- Hibernate Tutorials
- JPA Tutorials
- ElasticSearch Tutorials
- JBoss Drools Tutorials
- JMeter Tutorials
- Apache Camel Tutorials
- Apache Hadoop Tutorials
- Java SLF4J Tutorials
- Spring Tutorials
- Desktop Java Tutorials
- Core Java Tutorials
- Android Tutorials
- Android Core Tutorials
- Android Game Tutorials
- Scala Tutorials
- DevOps Tutorials
- Docker Tutorials
- NoSQL Tutorials
- MongoDB Tutorials
- Groovy Tutorials
- Git Tutorials
- Java Tutorials
- Our Projects
- Join Us
- Submission Guidelines
- Terms Conditions
- About JCGs
About Dustin Marx
Java Command-Line Interfaces (Part 25): JCommando
Posted by: Dustin Marx
in Core Java
October 20th, 2017
JCommando is described on the JCommando site as “a Java argument parser for command-line parameters.” JCommando reads XML configuration to generate a Java class that handles parsing from a Java application. The only Java-based library previously covered in this series of posts on Java command-line parsing libraries that provided XML configuration is JSAP , but it’s a secondary form of configuration with that library and I did not cover XML configuration in my post on JSAP .
Because JCommando uses XML to specify command line options to be parsed, the “definition” stage with JCommando is accomplished via XML specification. As with the previous posts in this series , the examples in this post are based on command line options for file path and name and verbosity and their definition in JCommando-compliant XML is shown in the next code listing (
JCommando via XML Portion of “Definition” Stage:
<jcommando> <option long="file" short="f" type="String"> <description>Path and name of file</description> </option> <option long="verbose" short="v"> <description>Verbosity enabled</description> </option> <commandless allow-optionless="true"> <or> <option-ref /> </or> </commandless> </jcommando>
JCommando uses the XML file an input and, based on that XML, generates a Java source code file that parses the options specified in the XML. There are two ways to instruct JCommando to parse this XML and use the details to generate Java source code. One way is to use the executable jcomgen executable provided with the JCommando distribution (in its bin directory). The second approach for generating a Java class from the XML is the approach shown here: using Apache Ant and a JCommando-provided Ant task. This is demonstrated in the next XML/Ant listing.
Ant Target for Generating Source from XML with JCommando
<target name="generateSourceForJCommando" description="Generate command line parsing source code that uses JCommando"> <taskdef name="jcommando" classname="org.jcommando.ant.JCommando"> <classpath> <pathelement location="C:\lib\jcommando-1.2\lib\jcommando.jar"/> </classpath> </taskdef> <jcommando inputfile="jcommando/options.xml" classname="MainParser" destdir="src" packagename="examples.dustin.commandline.jcommando"/> </target>
The above Ant target shows how JCommando allows the input XML file (
options.xml) to be specified as the “
inputfile” and that the generated Java source code file will be placed in the
src directory in a subdirectory structure matching the designated package “
examples.dustin.commandline.jcommando“. The execution of the Ant target and source code generation is shown in the next screen snapshot.
The result of this Ant target is the generated Java source class
MainParser.java whose listing is shown next.
Generated Java Source Class
package examples.dustin.commandline.jcommando; import org.jcommando.Command; import org.jcommando.JCommandParser; import org.jcommando.Option; import org.jcommando.Grouping; import org.jcommando.And; import org.jcommando.Or; import org.jcommando.Xor; import org.jcommando.Not; public abstract class MainParser extends JCommandParser public MainParser() Option file = new Option(); file.setId("file"); file.setShortMnemonic("f"); file.setLongMnemonic("file"); file.setDescription("Path and name of file"); addOption(file); Option verbose = new Option(); verbose.setId("verbose"); verbose.setShortMnemonic("v"); verbose.setLongMnemonic("verbose"); verbose.setDescription("Verbosity enabled"); addOption(verbose); Command execute = new Command(); execute.setName("commandless"); execute.setId("execute"); execute.addOption(file); execute.setGrouping( createExecuteGrouping() ); addCommand(execute); public abstract void setFile(String file); public abstract void setVerbose(); public abstract void doExecute(); private Grouping createExecuteGrouping() Or or1 = new Or(); or1.addOption(getOptionById("file")); return or1;
With the Java source code generated, we now have our options definitions. A custom class is written to extend the generated
MainParser and to access its parent for parsing. This is demonstrated in the next code listing of the custom written
Main class that extends the generated
Custom Class Extending Generated Class
package examples.dustin.commandline.jcommando; import static java.lang.System.out; public class Main extends MainParser private String file; private boolean verbose; @Override public void setFile(final String newFilePathAndName) file = newFilePathAndName; @Override public void setVerbose() verbose = true; public static void main(final String arguments) final Main instance = new Main(); instance.parse(arguments); public void doExecute() out.println("File path/name is " + file + " and verbosity is " + verbose);
As shown in the custom
Main.java source code shown above, the “parsing” stage is accomplished in JCommando via execution of the
parse(String) method inherited from the class that JCommando generated based on the configuration XML (and that generated class gets its definition of that
parse method from its parent JCommandParser class).
The custom class that extends the generated class needed to have the “set” methods for the options implemented. With these properly implemented, the “interrogation” stage in JCommando-based applications is as simple as accessing the fields set by those custom implemented “set” methods. This was demonstrated in the
doExecute() method shown in the last code listing. That
doExecute method was generated as an
abstract method in the generated parent class because of the specification of the
<commandless> element with
id of “
execute” in the configuration XML.
The JCommandParser class that the custom class ultimately extends has a method printUsage() that can be used to write “help”/”usage” output to standard output. This can be seen in the source code for
Main.java available on GitHub .
The next two screen snapshots demonstrate execution of the sample code discussed in this post. The first screen snapshot shows the “usage information that can be automatically printed, in this case when the required “file” option was not specified. The second screen snapshot demonstrates the combinations of long and short option names for the “vile” and “verbose” options.
The steps involved with using JCommando that have been discussed in this blog post are summarized here.
- Define options in XML file.
- Generate Java parser source code from XML using one of two approaches.
jcomgentool provided in JCommando’s
- Use Ant target with JCommand-provided Ant task as demonstrated in this post.
- Write Java class that extends generated parser class.
There are characteristics of JCommando to consider when selecting a framework or library to help with command-line parsing in Java.
- JCommando is open source and available under the zlib/libpng License (Zlib) .
- The jcommando.jar JAR is approximately 27 KB in size and there is no third-party dependency.
- Defining options in JCommando via XML is a different approach than the other libraries covered in this series, but what I find more interesting about JCommando’s options definition is the easy ability to express relationships between options such as “and”, “or”, “xor”, and nested combinations of these.
JCommando implements some novel concepts in terms of Java-based command line options parsing. It requires XML configuration of the potential command line options, but makes it easy to establish relationships between those options. JCommando generates Java source from the XML options configuration and a custom parsing class extends that generated class. JCommando is also the first of the libraries covered in this series to use the Zlib license .
- JCommando Tutorial
- JCommando XML Tag Reference
- JCommando API Documentation (Javadoc)
- JCommando Downloads
|Published on Java Code Geeks with permission by Dustin Marx, partner at our JCG program . See the original article here: Java Command-Line Interfaces (Part 25): JCommando |
Opinions expressed by Java Code Geeks contributors are their own.
You need to be a registered member to rate this.
Like This Article? Read More From Java Code Geeks
Leave a Reply
This site uses Akismet to reduce spam. Learn how your comment data is processed .
With monthly unique visitors and over authors we are placed among the top Java related sites around. Constantly being on the lookout for partners; we encourage you to join us. So If you have a blog with unique and interesting content then you should check out our JCG partners program. You can also be a guest writer for Java Code Geeks and hone your writing skills!