Building a Packaged Command-Line Application

In the Running the Simple Weather Program” section, earlier in this chapter, we executed our application using the Maven Exec plugin. Although that plugin executed the program and produced some output, you shouldn’t look to Maven as an execution container for your applications. If you are distributing this command-line application to others, you will probably want to distribute a JAR or an archive as a ZIP or TAR’d GZIP file. This section outlines a process for using a predefined assembly descriptor in the Maven Assembly plugin to produce a distributable JAR file, which contains the project’s bytecode and all of the dependencies.

You can use the Maven Assembly plugin to create arbitrary distributions for your applications. Use it to assemble the output of your project in any format you desire by defining a custom assembly descriptor. In a later chapter, we will show you how to create a custom assembly descriptor that produces a more complex archive for the simple weather application. In this chapter, we’re going to use the predefined jar-with-dependencies format. To configure the Assembly Plugin, we need to add the plugin configuration shown in Example 4-19 to our existing build configuration in the pom.xml.

Example 4-19. Configuring the Maven Assembly descriptor

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

Once you’ve added this configuration, you can build the assembly by running mvn assembly:assembly, like so:

$ mvn install assembly:assembly
...
[INFO] [jar:jar]
[INFO] Building jar: ~/examples/simple-weather/target/simple-weather-1.0.jar
[INFO] [assembly:assembly]
[INFO] Processing DependencySet (output=)
[INFO] Expanding: \
       .m2/repository/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar into \
       /tmp/archived-file-set.1437961776.tmp
[INFO] Expanding: .m2/repository/commons-lang/commons-lang/2.1/\
                     commons-lang-2.1.jar
       into /tmp/archived-file-set.305257225.tmp
... (Maven Expands all dependencies into a temporary directory) ...
[INFO] Building jar: \
       ~/examples/simple-weather/target/\
         simple-weather-1.0-jar-with-dependencies.jar

Once the assembly is assembled in target/simple-weather-1.0-jar-with-dependencies.jar, you can run the Main class again from the command line. To run the simple weather app’s Main class, execute the following from your project’s base directory:

$ cd target
$ java -cp simple-weather-1.0-jar-with-dependencies.jar \
                    org.sonatype.mavenbook.weather.Main 10002
0    INFO  YahooRetriever  - Retrieving Weather Data
221  INFO  YahooParser  - Creating XML Reader
399  INFO  YahooParser  - Parsing XML Response
474  INFO  WeatherFormatter  - Formatting Weather Data
*********************************
 Current Weather Conditions for:
  New York, NY, US
  
 Temperature: 44
   Condition: Fair
    Humidity: 40
  Wind Chill: 40
*********************************

The jar-with-dependencies format creates a single JAR file that includes all of the bytecode from the simple-weather project as well as the unpacked bytecode from all of the dependencies. This somewhat unconventional format produces a 9 MiB JAR file containing approximately 5,290 classes, but it does provide for an easy distribution format for applications you’ve developed with Maven. Later in this book, we’ll show you how to create a custom assembly descriptor to produce a more standard distribution.

Get Maven: The Definitive Guide now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.