© 2016-2024 The original authors.
1. Introduction
Eclipse Vert.x is a toolkit to build reactive and distributed systems on the top of the JVM.
The Vert.x Maven Plugin is a plugin for Apache Maven that helps to develop and/or to package Vert.x applications.
The last version of the Vert.x Maven Plugin is 2.0.1.
1.1. Using the plugin
The plugin provides a set of goals such as:
-
setup
- create a new project or adds the Vert.x Maven Plugin to an existing one -
initialize
- manage js dependencies and webjars, and initiate redeployment if needed -
package
- package a Vert.x application as an executable uber-jar -
run
- run the Vert.x application as part of the Maven build, in a separate process
Generally, you will use the following configuration:
<project>
<properties>
<vertx.verticle>org.acme.MyVerticle</vertx.verticle>
</properties>
...
<build>
<plugins>
...
<plugin>
<groupId>io.reactiverse</groupId>
<artifactId>vertx-maven-plugin</artifactId>
<version>2.0.1</version>
<executions>
<execution>
<id>vmp</id>
<goals>
<goal>initialize</goal>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
...
</project>
2. Goals
2.1. Common Configurations
All goals share the following configuration:
Element | Description | Default | Property |
---|---|---|---|
|
The main verticle class name. |
|
|
|
The launcher or application main class name. |
Depends on the Vert.x version (see below). |
|
|
Skip the processing executed by this plugin |
|
|
The Vert.x Maven Plugin computes a default launcher
value as follows:
-
For a Vert.x 4 application, the default is
io.vertx.core.Launcher
-
For a Vert.x 5 application:
-
If the
io.vertx:vertx-launcher-application
dependency is present, the default isio.vertx.launcher.application.VertxApplication
-
Otherwise, if the
io.vertx:vertx-launcher-legacy-cli
dependency is present, the default isio.vertx.core.Launcher
-
2.2. vertx:setup
This goal creates a new project, or adds the Vert.x Maven Plugin to an existing one.
2.2.1. Usage
mvn io.reactiverse:vertx-maven-plugin:2.0.1:setup
This will configure Vert.x and its dependencies to 4.5.8
, i.e. the Maven project property vertx.version
will be set to 4.5.8
.
If you wish to override the default Vert.x version, then you can run the same command as above with -DvertxVersion=<your-vertx-version>
:
mvn io.reactiverse:vertx-maven-plugin:2.0.1:setup -DvertxVersion=
You can also generate a project if you don’t have a pom.xml
file:
mvn io.reactiverse:vertx-maven-plugin:2.0.1:setup \
-DprojectGroupId=org.acme \
-DprojectArtifactId=acme-project \
-DprojectVersion=1.0-SNAPSHOT \
-Dverticle=org.acme.Foo
The verticle
parameter creates a new verticle class file.
When creating a new project, the java.specification.version
system property is used to configure the Maven compiler plugin in the new POM file.
To set a different Java version, use the javaVersion
property:
mvn io.reactiverse:vertx-maven-plugin:2.0.1:setup -DjavaVersion=11
2.3. vertx:initialize
This goal has several aims:
-
copy js dependencies to the webroot directory
-
unpack webjars dependencies to the webroot directory (optional)
-
initialize the recording of the build used for the redeployment
2.3.1. Configuration
The initialize
goal has the following parameters apart from the ones mentioned in Common Configuration:
Element | Description | Property | Default |
---|---|---|---|
|
The location where js dependencies and webjars are copied. |
|
|
|
Whether webjars are unpacked to webRoot. If not unpacked, webjars can be served from the classpath. |
|
|
|
Whether the version is stripped when unpacking webjars |
|
|
|
Whether the version is stripped when copying the JavaScript file |
|
|
The webroot
directory is generally used by the StaticHandler
from Vert.x Web.
2.3.2. Redeployment
The initialize
goal is used to configure the redeployment used in vertx:run
.
It starts observing the executed plugins in your build to replay them when a file changes.
2.4. vertx:package
This goal packages a Vert.x application as an executable uber-jar (a JAR file containing the files of the application and of its dependencies).
Being executable, it can be launched using: java -jar <my-app.jar>
.
The packaging process adds certain MANIFEST.MF entries that control how the application is launched. The plugin takes care of adding the required entries to the MANIFEST.MF with values configured using the Common Configuration.
The following are the MANIFEST.MF entries that will be added based on the configuration elements:
Property | Manifest Attribute | Remarks |
---|---|---|
|
|
The main verticle, i.e. the entry point of your application. Used when the |
|
|
The main class used to start the application. |
2.4.1. Configuration
The package
goal has the following parameters apart from the ones mentioned in Common Configuration:
Element | Description | Property | Default |
---|---|---|---|
|
Whether SPI files ( |
|
|
|
The classifier to add to the artifact generated.
If given, the artifact will be attached with that classifier and the main artifact will be deployed as the main artifact.
If this is not given (default), it will replace the main artifact and only the Vert.x uber-jar artifact will be deployed (in the Maven sense).
Attaching the artifact allows to deploy it alongside to the original one.
Attachment is controlled using the |
|
|
|
Whether the created archive needs to be attached to the project. If attached, the uber-jar is installed and deployed alongside the main artifact (plain jar). Notice that you can’t disable attachment if the classifier is not set (it would mean detaching the main artifact). |
|
|
2.5. vertx:run
This goal allows to run the Vert.x application as part of the Maven build, in a separate process.
By default, it monitors the src/main
directory and, if the code changes, rebuilds the project and restarts the application.
The plugin re-executes the mojos that ran between the generate-source and the process-classes phases.
So, to start a Vert.x application, just launch:
mvn vertx:run
If the sources aren’t compiled, the plugin executes mvn compile
for you.
2.5.1. Configuration
The run
goal has the following parameters apart from the ones mentioned in Common Configuration:
Element | Description | Property | Default |
---|---|---|---|
|
Whether redeployment is enabled. |
|
|
|
The root directory to scan for changes. |
|
|
|
A list of Ant-like patterns of files/directories to include in change monitoring.
The patterns must be expressed relatively to the |
|
|
|
A list of Ant-like patterns of files/directories to exclude from change monitoring.
The patterns must be expressed relatively to the |
|
|
|
How often, in milliseconds, should the source files be scanned for file changes. |
|
|
|
How long, in milliseconds, the plugin should wait between two redeployments. |
|
|
|
The JVM arguments that will be used when starting the Vert.x application. |
|
|
|
The list of arguments that can be passed to the main class, if it is a Vert.x launcher.
You can also pass the required run arguments using the system property. e.g. |
|
|
|
The Vert.x configuration file path that will be passed to the main class, if it is a Vert.x launcher, as |
|
|
|
The verticle configuration file path that will be passed to the main class, if it is a Vert.x launcher, as |
|
|
|
The environment for Vert.x Web apps. |
|
Defaults to either the |
|
The working directory for the Vert.x application. |
|
|
|
Whether the Vert.x application should be started with its blocked thread checker disabled. |
|
|
|
Whether the JVM running the Vert.x application should start a remote debug server. |
|
|
|
Whether the application must wait until a debugger is attached before starting. |
|
|
|
The remote debug server port. |
|
|
For example, if the projects contains a web frontend built with Node in /src/main/frontend
, you will have to exclude files that are changed as part of the frontend build:
<plugin>
<groupId>io.reactiverse</groupId>
<artifactId>vertx-maven-plugin</artifactId>
<version>${vertx-maven-plugin.version}</version>
<executions>
<execution>
<id>vmp</id>
<goals>
<goal>initialize</goal>
<goal>package</goal>
</goals>
</execution>
</executions>
<configuration>
<redeployRootDirectory>${project.basedir}/src/main</redeployRootDirectory>
<redeployExcludes>
<redeployExclude>frontend/node_modules/**</redeployExclude>
<redeployExclude>frontend/dist/**</redeployExclude>
<redeployExclude>frontend/package-lock.json</redeployExclude>
</redeployExcludes>
</configuration>
</plugin>
2.6. Archive configuration
The Vert.x Maven Plugin lets you configure the content of the created archive. Typically, you can decide:
-
which dependency needs to be embedded
-
which files need to be included
-
which resources need to be combined
Besides, you can customize the manifest.
By default, the plugin:
-
embeds all compile dependencies
-
includes all files from
target/classes
(compiled classes fromsrc/main/resources
, processed resources from `src/main/resources) -
combines resources from
META-INF/services
,META-INF/spring.*
andMETA-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat
.
If the generated uber-jar contains files under |
2.6.1. Using archive configuration
In your plugin configuration add the archive
item:
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>io.reactiverse</groupId>
<artifactId>vertx-maven-plugin</artifactId>
<version>${version}</version>
<executions>
<execution>
<id>vmp</id>
<goals>
<goal>initialize</goal>
<goal>package</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<!-- archive configuration goes here -->
</archive>
</configuration>
</plugin>
...
</plugins>
</build>
...
</project>
Configuring embedded dependencies
In the archive
configuration, you can declare dependency sets which indicate which dependencies must be included and excluded.
Also for each configure set, you can decide the file to include and exclude.
Here is an example:
<configuration>
<archive>
<dependencySets>
<set>
<excludes>
<exclude>*:commons-lang3</exclude>
</excludes>
<includes>
<include>*:log4j-core</include>
<include>*:vertx-core</include>
</includes>
<options>
<excludes>
<exclude>*.dtd</exclude>
</excludes>
</options>
</set>
</dependencySets>
</archive>
</configuration>
Notice that when a dependency set is configured, no other dependency is embedded, disabling the default. When you configure the archive without a dependency set, the default behavior (embedding all compile dependencies) is used.
On a dependency set you can configure:
-
includes
: the set of dependencies to specifically include, if not set, include all dependencies not explicitly excluded -
excludes
: the set of dependencies to exclude -
scope
: the scope of the dependency to include, default toruntime
-
useTransitiveDependencies
: a boolean indicating if transitive dependencies from included dependencies must be also included in the jar -
option
: configure the files to include / exclude from this dependency set
The option
attribute enable fine-grain tuning of the file to embed.
In the example above, the dtd
files are excluded.
Embedding specific file
The archive can be configured with a set of external file to include. For instance:
<configuration>
<archive>
<files>
<file>
<source>src/ext/hello.txt</source>
<outputDirectory>misc</outputDirectory>
<destName>lorem-ipsum.txt</destName>
</file>
</files>
</archive>
</configuration>
Each file contains:
-
the
source
- the location of the file -
the
outputDirectory
- indicating where would be the file in the archive -
the
destName
- indicating the final name
For instance, in the previous example, the file src/ext/hello.txt
is embedded in the archive as misc/lorem-ipsum.txt
.
Embedding file sets
While files
allow embedding files individually, fileSets
declare set of files:
<archive>
<fileSets>
<fileSet>
<directory>src/ext</directory>
<outputDirectory>misc</outputDirectory>
<excludes>
<exclude>h*.txt</exclude>
</excludes>
</fileSet>
</fileSets>
</archive>
In a fileSet
, you can configure:
-
the
directory
- the directory containing the files -
the
outputDirectory
- indicating where would be the file in the archive -
includes
andexcludes
pattern to choose which files you want to embed in the archive. -
useDefaultExcludes
- indicating if you want to use the default exclusion list (enabled by default)
Customizing the manifest
You can also add entries into the MANIFEST.MF
of the created archive using the manifest
entry:
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
<configuration>
<archive>
<manifest>
<key>value</key>
<name>${project.artifactId}</name>
</manifest>
</archive>
</configuration>
</execution>
</executions>
Resource combination
Resource combination is the process of merging the content of some files into a single file. It is particularly useful when building an archive embedding dependencies which contain the same files.
The files matching these patterns are combined by default:
-
META-INF/services/*
-
META-INF/spring*
-
META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat
.
The fileCombinationPatterns
attribute allows configuring which files need to be combined:
<archive>
<fileCombinationPatterns>
<pattern>misc/extension.*</pattern>
<pattern>META-INF/services/*</pattern>
<pattern>META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat</pattern>
</fileCombinationPatterns>
</archive>
If you set the fileCombinationPatterns attribute, the defaults are ignored.
|
3. Miscellaneous
3.1. How does redeployment work
During the initialize phase, the plugin starts observing the mojos (Maven plugins) that are executed.
The Vert.x Maven Plugin watches for changes in src/main
.
When a file or directory is changed (created, updated or deleted):
-
it stops the Vert.x application
-
it replays the executed mojos (all the mojos from the generate-sources to the process-classes phases, using the same configuration as the initial (observed) one)
-
it stars the Vert.x application again
Such a mechanism lets you use any Maven plugin (executed in the right set of phases). The plugin is re-executed and then the Vert.x application is restarted.
3.2. Windows: command line is too long
The Vert.x Maven Plugin runs your Vert.x application in a forked process. This process command line can grow quickly depending on:
-
the number of dependencies in the project,
-
the length of the path to JVM,
-
the length of the path to the Maven repository.
On Windows, there is a maximum length for command lines. When this maximum is reached the Vert.x application fails to start. You will see an error such as:
Command line is too long
As a workaround, you can either:
-
move the JVM and Maven repository paths closer to the root of the Windows drive, or
-
use
subst
to associate the JVM and Maven repository paths with a drive letter.
For example, you could associate the letter X
with the JVM path and Y
with the Maven repository path:
subst X: "C:\Program Files\AdoptOpenJDK\jdk-11.0.8.10-hotspot"
subst Y: "C:\Users\User\.m2\repository"
Virtual drives created with subst do not survive reboots.
To make the setup somewhat persistent, put the subst commands in a batch file and add it to the startup folder.
|
Then:
-
set the
JAVA_HOME
environment variable toX:
-
open the Maven settings file and change the
localRepository
element value toY:
Don’t forget to open a new terminal so that the environment variable change is visible. |