📜 ⬆️ ⬇️

Perfect maven. Part 2: project structure

This is the second article on mavena and its use for organizing my projects. The purpose of this article will be the structure of the project under the control of maven. You will not find special revelations, rather a set of general rules for my projects. The first article can be read here .


Project structure


As I said, I will not describe here the typical structure of the project in maven - you know it or you can easily find it at the link: Standard Directory Layout . In this part I will focus on the features that I apply in my projects, so:


Modules


Virtually any of my projects have several modules. Practice shows that when it is necessary to add another module to the project it is much easier to do it in the case of an initially modular project. In my projects there are 3 types of "modules" - POM (always one), several developer modules with code and BOM - if dev. modules more than one. In principle, POM is not a module in the understanding of maven, but I always draw it up almost as a “module” (I will show below). The result is something like this:



General principles for all POMs - they contain the minimum information necessary to build a project, all versions, all plug-in settings that are not specific to this project, are located in the super (“corporate”) POM. All “modules”, except for the project POM, contain a link to the local version of the parent relativePath .

Project POM


Let's start with the project POM'a. I almost always put it in a separate directory called pom. I do this for several reasons:



Project POM contains a link to a super POM, a list of modules, versions of projects on which it depends (not libraries of third countries, namely projects that are parallel to development in this company) and the definition of version for modules and projects (dependencyManagement). Here is a typical POM for a small project:


 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>org.jresearch.pom</artifactId> <groupId>org.jresearch</groupId> <version>29-SNAPSHOT</version> </parent> <groupId>org.jresearch.commons.base.resources</groupId> <artifactId>org.jresearch.commons.base.resources.pom</artifactId> <version>1.0.43-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>../api</module> <module>../impl</module> <module>../test</module> <module>../bom</module> </modules> <properties> <jrs.open.base.domain.ver>1.0.34-SNAPSHOT</jrs.open.base.domain.ver> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.jresearch.commons.base</groupId> <artifactId>org.jresearch.commons.base.domain</artifactId> <version>${jrs.open.base.domain.ver}</version> </dependency> <dependency> <groupId>org.jresearch.commons.base.resources</groupId> <artifactId>org.jresearch.commons.base.resources.api</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.jresearch.commons.base.resources</groupId> <artifactId>org.jresearch.commons.base.resources.test</artifactId> <version>${project.version}</version> </dependency> </dependencies> </dependencyManagement> </project> 

In this example:
version of the project on which it depends


  <properties> <jrs.open.base.domain.ver>1.0.34-SNAPSHOT</jrs.open.base.domain.ver> </properties> 

and versioning for modules and projects


 <dependencyManagement> <dependencies> <dependency> <groupId>org.jresearch.commons.base</groupId> <artifactId>org.jresearch.commons.base.domain</artifactId> <version>${jrs.open.base.domain.ver}</version> </dependency> <dependency> <groupId>org.jresearch.commons.base.resources</groupId> <artifactId>org.jresearch.commons.base.resources.api</artifactId> <version>${project.version}</version> </dependency> </dependencies> </dependencyManagement> 

Why do you need it? To completely eliminate the use of versions in developer modules. With this configuration, all versions are fixed in the super POM (for external libraries) and in project POMs (for the project itself and its dependencies on internal projects). This not only makes the POMs in the modules cleaner, but also necessary for the release of the process I use.


BOM POM


This “ bill of materials ” is a list of the artifacts that the project exports. In my projects, it appears if the number of developer modules is more than one. This allows you to manage dependency versions between internal projects using only one entry in the dependencyManagement section.
BOM example:


 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>org.jresearch.commons.base.resources.pom</artifactId> <groupId>org.jresearch.commons.base.resources</groupId> <version>1.0.43-SNAPSHOT</version> <relativePath>../pom/pom.xml</relativePath> </parent> <packaging>pom</packaging> <artifactId>org.jresearch.commons.base.resources.bom</artifactId> <name>JRS-COMMONS: Base resource (DAO) BOM</name> <dependencyManagement> <dependencies> <dependency> <groupId>org.jresearch.commons.base.resources</groupId> <artifactId>org.jresearch.commons.base.resources.api</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.jresearch.commons.base.resources</groupId> <artifactId>org.jresearch.commons.base.resources.impl</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.jresearch.commons.base.resources</groupId> <artifactId>org.jresearch.commons.base.resources.test</artifactId> <version>${project.version}</version> </dependency> </dependencies> </dependencyManagement> </build> </project> 

Module with code


The most primitive POM. Includes a link to the project POM, artefactId, a list of dependencies without versions. If necessary, the build section with links to plugins. The version and groupId are inherited from the parent POM.
Example:


 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>org.jresearch.commons.base.resources.pom</artifactId> <groupId>org.jresearch.commons.base.resources</groupId> <version>1.0.43-SNAPSHOT</version> <relativePath>../pom/pom.xml</relativePath> </parent> <artifactId>org.jresearch.commons.base.resources.api</artifactId> <dependencies> <dependency> <groupId>org.jresearch.commons.base</groupId> <artifactId>org.jresearch.commons.base.domain</artifactId> </dependency> <dependency> <groupId>com.google.code.findbugs</groupId> <artifactId>jsr305</artifactId> </dependency> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> </dependency> </dependencies> </project> 

Artifact name


groupId is the name of the package in Java for this project - recently it has become practically standard. With artifactId are a few wonders; for my projects, I always take the group name plus the module name, something like this:


 <artifactId>org.jresearch.orika.spring</artifactId> 

Why? The name of the final artifact should be unique (too often everyone is dumped into one directory), the idea itself I brought out and the world eclipse - this is how plugins are called. At first it is unusual, but it is quite unique, it is very simple to think of it. When you see an artifact in the directory by name, you can quickly find the artifact in the repository and source control.


Why not use finalName in a super POM (eg <finalName>${ groupId}.${artifactId}-${version}</finalName> )? Historically, at the dawn of the mavenization, a lot of plug-ins ignored the rules, and it was easier to write it by hand. Now, probably, it is not.


Following this convention with names is optional. The main thing is the uniqueness of the name of the final artifact.


General principles for the structure of my projects.


  1. Versions of dependencies and plugins only in super or project POMs
  2. All modules inherit the version and group that are defined in the project POM.
  3. If I am firmly (by 146%) sure that the project will contain only one module with a code, I am doing a classic maven project (eg https://bitbucket.org/JRS/open-base-util/src )
  4. If I know that I will add several modules at once bom module (eg https://bitbucket.org/JRS/open-base-resources/src )
  5. If not sure, then a project from one module without BOM (eg https://bitbucket.org/JRS/open-base/src )
  6. artifactId is always groupId + module name
  7. directory structure for the project: root directory - project name (short), pom directory for project POM, bom for BOM POM, other directories for modules.
  8. relativePath - in all the “modules”, except for the project POM, one maven project is one project in source control. All communications between projects only through maven.

According to the structure of projects, this is probably all.


')

Source: https://habr.com/ru/post/344480/


All Articles