Managing Environments and Plugins in Maven
Even in 2019, there are still no proper plugins for managing environments in Maven.
Join the DZone community and get the full member experience.
Join For FreeIt is amazing that in 2019, there are still no proper plugins for managing environments in Maven. The only one that makes an attempt at solving environment management issues is multienv-maven-plugin
(https://github.com/khmarbaise/multienv-maven-plugin) by Khmarbaise. In this article, we discuss details about using the environments-maven-plugin, assess what multienv-maven-plugin is lacking, and look at potential solutions to this problem. Let's get into it!
Doesn't Allow the Exclusion of Environments
For almost all of the projects I have worked on, they have resource files both for various environments and for running the code on the developer's machine but pointing to various environments. For example:dev
, dev_local
, ci
, ci_local
, qa
, qa_local
, etc. — these QA resources files are used to run the application in the QA environment. qa_local
resource files are used to run the application on the developer machine pointing to the QA environment. When a release build is run, war files for dev_local
, ci_local
, and qa_local
should not be generated. Otherwise, it slows down the build and clutters bamboo build pages, potentially causing confusion to the party performing the actual deployment.
multienv-maven-plugin is built on the philosophy that each directory under src/main/environments represents an environment, and all directories under src/main/environments are environments. Additionally, a war file is generated for each environment. This philosophy appears to provide simplicity but does so at the expense of proper functionality.
environments-maven-plugin allows for the exclusion of environments for which generation of war files is undesirable. This can be done using the excludeEnvironments
tag in the plugin configuration.
Example Configuration
<plugin>
<groupId>net.sf.environments-maven-plugin</groupId>
<artifactId>environments-maven-plugin</artifactId>
<version>1.1.0-SNAPSHOT</version>
<configuration>
<excludeEnvironments>dev01, qa01 ,qa02,</excludeEnvironments>
<parallel>true</parallel>
</configuration>
<executions>
<execution>
<goals>
<goal>configuration</goal>
</goals>
</execution>
</executions>
</plugin>
Doesn't Allow Manifest Customization
When war files are generated for different environments, there may be cases where it is necessary to add environment-specific manifest entries. multienv-maven-plugin doesn't provide this. One can do this easily with environments-maven-plugin using the environmentArchiveConfiguration
tag in the plugin configuration.
You can have one configuration for all environments or have a configuration for each of the individual environments, as shown below.
For ease, the environment is already added to each war file. The manifest entry looks like this.
Environment: ci_local
Example Configuration
<project>
...
<build>
<plugins>
<plugin>
<groupId>net.sf.environments-maven-plugin</groupId>
<artifactId>environments-maven-plugin</artifactId>
<version>1.1.0-SNAPSHOT</version>
<configuration>
<excludeEnvironments>dev01, qa01</excludeEnvironments>
<parallel>true</parallel>
<archives>
<environmentArchiveConfiguration>
<environment>dev02</environment>
<archive>
<manifestEntries>
<mode>development</mode>
<key>value</key>
</manifestEntries>
</archive>
</environmentArchiveConfiguration>
<environmentArchiveConfiguration>
<environment>prod01, prod02</environment>
<archive>
<manifestEntries>
<mode>development1</mode>
<key>value1</key>
</manifestEntries>
</archive>
</environmentArchiveConfiguration>
</archives>
</configuration>
<executions>
<execution>
<goals>
<goal>configuration</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Doesn't Have Environment-Specific Filtering
environments-maven-plugin introduces the commonDir
and filters
tags. commonDir
tag takes the path of a directory inside src/main/environnments. The common directory contains templates that are common to all environments. These templates can have variables that are enclosed by @
(@variable@
).
The filters
tag can have multiple filter
tags. Each filter
tag takes the name of a file.
When the wars are built, the plugin does the following.
- Takes the template files from the common directory.
- Retrieves the files with the names declared in
filter
tags from the environment directory. For example, if dev war is currently being built, the plugin tries to find the files fromfilter
tags in the src/main/environments/dev directory. - Merges all the key-value pairs from all the files in
filter
tags into aHashMap
. - Uses those key-value pairs from the
HashMap
to substitute variables in the template. - Packages the files from the previous step in the dev war file.
- Also packages all the files from src/main/environments/${env} directory.
Example Configuration
<plugin>
<groupId>net.sf.environments-maven-plugin</groupId>
<artifactId>environments-maven-plugin</artifactId>
<version>1.3.0-SNAPSHOT</version>
<configuration>
<commonDir>common</commonDir>
<filters>
<filter>ec.properties</filter>
</filters>
</configuration>
<executions>
<execution>
<goals>
<goal>environment</goal>
</goals>
</execution>
</executions>
</plugin>
The image below illustrates the file/directory naming/structure.
For filtering to work, both commonDir
and filters
tags should be declared.
Doesn't Provide the Facility to Place the Resource Files in a Specific Directory Inside the War File
Resource files usually belong in WEB-INF/classes directory inside the war file. To achieve this in multimaven-maven-plugin, one would have to create WEB-INF/classes directory in each of the environments inside src/main/environments and then place the resource files inside them. As shown below this is redundant and ugly.
- src
- main
- environments
- dev
- WEB-INF
- classes
- files
- classes
- WEB-INF
- dev_local
- WEB-INF
- classes
- files
- classes
- WEB-INF
- ci
- WEB-INF
- classes
- files
- classes
- WEB-INF
- ci_local
- WEB-INF
- classes
- files
- classes
- WEB-INF
- dev
- environments
- main
To solve this, environments-maven-plugin introduces a new tag called targetPath
. If this tag is declared with a directory path for value, the resources files packaged in the war are placed inside the directory. So. it looks like this.
- app_dev.jar
- WEB-INF
- classes
- files
- classes
- WEB-INF
- app_dev_local.jar
- WEB-INF
- classes
- files
- classes
- WEB-INF
- app_ci.jar
- WEB-INF
- classes
- files
- classes
- WEB-INF
- app_ci_local.jar
- WEB-INF
- classes
- files
- classes
- WEB-INF
So the directory structure looks like this in that case.
- src
- main
- environments
- dev
- files
- dev_local
- files
- ci
- files
- ci_local
- files
- dev
- environments
- main
Example Configuration
<plugin>
<groupId>net.sf.environments-maven-plugin</groupId>
<artifactId>environments-maven-plugin</artifactId>
<version>1.1.0-SNAPSHOT</version>
<configuration>
<targetPath>WEB-INF/classes</targetPath>
</configuration>
<executions>
<execution>
<goals>
<goal>environment</goal>
</goals>
</execution>
</executions>
</plugin>
Doesn't Allow Building a Single Environment
multienv-maven-plugin doesn't provide the facility to build a single environment. The result is that one will have to maintain an entirely separate set-up just for individual environments. environments-maven-plugin solves this problem with a command line option -Dem.env. The value of the option is the directory name of the environment of interest in src/main/environment.
mvn clean install -Dem.env=dev_local
Conclusion
environments-maven-plugin is a fork of mutlienv-maven-plugin. I did submit pull requests to multienv-maven-plugin, but either I said something the kind gentleman didn't want to hear or he heard something I didn't say. The net result is the pull requests didn't get approved. So I had to fork it.
There are issues with 1.0, 1.1, and 1.2. Please use the latest version: 1.3.
Project Page: https://sourceforge.net/projects/environments-maven-plugin/
Source Code: https://sourceforge.net/p/environments-maven-plugin/code/ci/master/tree/
Overview page: https://environments-maven-plugin.sourceforge.io/index.html
Lastly, the plugin is in Maven Central.
If you feel like asking why not GitHub, the answer is pretty simple— that bandwagon is already too crowded.
Opinions expressed by DZone contributors are their own.
Trending
-
A React Frontend With Go/Gin/Gorm Backend in One Project
-
What Is Envoy Proxy?
-
Cucumber Selenium Tutorial: A Comprehensive Guide With Examples and Best Practices
-
Performance Comparison — Thread Pool vs. Virtual Threads (Project Loom) In Spring Boot Applications
Comments