Setting Up an Application Directory Structure
In setting up Proficio’s directory structure, it is important to keep in mind that Maven emphasizes the practice of standardized and modular builds. The natural outcome of this practice is the generation of discrete and coherent components, which enable code reusability, a key goal for every software development project. The guiding principle in determining how best to decompose your application is called the Separation of Concerns (SoC).
SoC refers to the ability to identify, encapsulate, and operate on the pieces of software that are relevant to a particular concept, goal, task, or purpose. Concerns are the primary motivation for organizing and decomposing software into smaller, more manageable and comprehensible parts, each of which addresses one or more specific concerns.
As such, you will see that the Proficio sample application is made up of several Maven modules:
- Proficio API: The application programming interface for Proficio, which consists of a set of interfaces. The interfaces for the APIs of major components, like the store, are also kept here.
- Proficio CLI: The code which provides a command line interface to Proficio.
- Proficio Core: The implementation of the API.
- Proficio Model: The data model for the Proficio application, which consists of all the classes that will be used by Proficio as a whole.
- Proficio Stores: The module which itself, houses all the store modules. Proficio has a very simple
memory-basedstore and a simple
These are default naming conventions that Maven uses, but you are free to name your modules in any fashion your team decides. The only real criterion to which to adhere is that your team agrees to and uses a single naming convention. Moreover, everyone on the team needs to clearly understand the convention, and be able to easily identify what a particular module does simply by looking at its name.
In examining the top-level POM for Proficio, you can see in the modules element all the sub-modules that make up the Proficio application. A module is a reference to another Maven project, which really means a reference to another POM. This setup is typically referred to as a multi-module build and this is how it looks in the top-level Proficio POM:
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.exist.mvnbook.proficio</groupId> <artifactId>proficio</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <name>Maven Proficio</name> <url>http://maven.apache.org</url> [...] <modules> <module>proficio-model</module> <module>proficio-api</module> <module>proficio-core</module> <module>proficio-stores</module> <module>proficio-cli</module> </modules> [...] </project>
An important feature to note in the POM above is the value of the version element, which you can see is
1.0-SNAPSHOT. For an application that has multiple modules, it is very common to release all the sub-modules together, so it makes sense that all the modules have a common application version. It is recommended that you specify the application version in the top-level POM and use that version across all the modules that make up your application.
You should take note of the
packaging element, which in this case has a value of
pom. For POMs that contain modules, the packaging type must be set to value of
pom: this tells Maven that you’re going to be walking through a set of modules in a structure similar to the example being covered here. If you were to look at Proficio’s directory structure you would see the following:
Figure 3-1: Proficio directory structure
You may have noticed that the module elements in the POM match the names of the directories in the prior Proficio directory structure. Looking at the module names is how Maven steps into the right directory to process the respective POMs located there. Let’s take a quick look at the modules and examine the packaging for each:
Table 3-1: Module packaging types
The packaging type in most cases is the default type of
jar, but the interesting thing here is that we have another project with a packaging type of
pom, which is the
proficio-stores module. If you take a look at the POM for the
proficio-stores module you will see a set of modules contained therein:
<project> <parent> <groupId>com.exist.mvnbook.proficio</groupId> <artifactId>proficio</artifactId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>proficio-stores</artifactId> <name>Maven Proficio Stores</name> <packaging>pom</packaging> <modules> <module>proficio-store-memory</module> <module>proficio-store-xstream</module> </modules> </project>
Examine the directory structure inside the
proficio-stores directory and you will see the following:
Figure 3-2: Proficio-stores directory
Whenever Maven sees a POM with a packaging of type
pom Maven knows to look for a set of related sub-modules and then process each of those modules. You can nest sets of projects like this to any level, organizing your projects in groups according to concern, just as has been done with Proficio’s multiple storage mechanisms, which are all placed in one directory.