Skip to main content

Java command line app with Spring and Gradle

Many Java developers have had to build a command line app for one reason or another over the years, and there are many(!) ways to do it.  There are a bevy of command line libraries, some people roll their own when they get to this point (which is one reason why there are so many command line libraries!), and others just pull in the arguments simply and directly, eschewing a library.

However, writing a tool, a developer should just focus on the meat of the problem rather than having to worry about the enabling functionality that allows it to work.  The Spring Framework very much supports this approach to development with its inversion of control (IoC) container and a myriad of other features.

To support that approach for command line applications, the spring-cmdline library provides a bridge between the Spring framework and the JOpt Simple command line library.

This tutorial will show how to leverage the spring-cmdline library to stand up a very simple command line application, using Gradle to accelerate getting a build up and running.


First, let's construct a Gradle build script for this project:


  1. This applies the Java plugin to the Gradle build.  This immediately provides us with support for Maven-style source source folders (src/main/java, src/main/resources, src/test/java, etc.) as well as build, compile, and test targets.
  2. The repositories declaration lists the Maven repositories we can pull dependencies from.
  3. The dependencies declaration lists the actual dependencies.  Here, we're adding only the spring-cmdline library that we'll be demonstrating.  (This pulls in a number of transitive dependencies that we don't have to list because they're implied.)

Next, let's add an Example class:


  1. Spring uses the Apache commons-logging library for logging events.  The commons-logging library is a logging wrapper that uses Log4j or java.util.logging (JUL) as logging implementations.  Since we're not loading Log4j here, JUL will be used as a fallback.  Since we don't want Spring's INFO level logging messages being dumped out to the console, we here set the threshold to  SEVERE to suppress those.  (In a production application, you should use a better logging scheme, but that's outside the scope of this tutorial.)
  2. The application's main method constructs a CommandLineAppContext object.  This is a Spring ApplicationContext-derived class that knows how to handle a command line and inject information from the command line onto your instance.  It uses Spring's type conversion natively so you can receive values other than Strings.  (It can also handle autowiring and resource acquisition, but again, that's probably suitable for a later, more advanced tutorial.)
  3. We have one command line option (@Option) which is specified like -X or --xxxxxx, Unix/Linux style syntax.
  4. We have one command line operand (@Operand), which are the parts of the command line that aren't options.  Notice these and options are just declared; we don't have to specifically write code to acquire them.  (They currently require JavaBean compatible setters to inject them.)
  5. spring-cmdline applications should implement Runnable.  The behavior of the application is contained in the run method.
The build script and the Example class are all you need for the essence of a "Hello, world!" command line application in this case.

To put this application in a self-contained jar file, we add the following to the build.gradle script:

This comes directly from a recipe in the Gradle Cookbook but has the Main-Class attribute in the manifest set so that you can run the jar file directly.

Building it should look like this:

Running the assembled jar file without anything gives you usage:

(This is because there was a command line violation detected.  You can also get this usage by specifying -h or --help on the command line.)

Using the tool as it was intended, you can see the different greetings:

(Source for the running project for this is available in a GitHub project.)

Comments

Popular posts from this blog

Groovy and String Comparisons

Though I've recently come to love working with Groovy, I'm deep enough where I'm starting to see some of its warts. The one that hit me nearly right away was the nastiness about groovy.lang.GString not extending java.lang.String .  This is mainly the fault of the latter being final and not extendable, but it mea ns that GString in stances aren't automatically comparable with plain Java strings. In Groovy, string literals can be quoted using both single and double-quotes.  GString appears when you use double-quotes around a string and expand variables into it.  See " Strings and GStrings " for more information.

Family budget crisis prompts parents to cut back on work?

Minnesota's Governor Tim Pawlenty has previously used a state-as-family metaphor , saying that when a family is stuck with a budget deficit, they have no choice but to tighten their belts.  This is not quite true, as it ignores the income side of the equation.  Most families I know have tried to acquire more jobs or longer hours in order to increase income.  Some have even invested in something that might pay off in higher income, like going back to school to finish a degree or get additional training.  Looking only at decreasing expenses is considering only half of the problem. The good news is that Governor Pawlenty now agrees that taxes may enter into the equation.  The bad news is that he's taken a George W. Bush approach to it, advocating lowering taxes to bring Minnesota out of its current financial mess.  My mind boggles at the logic.