blob: 3c1d8ca104d92a9fe0e367ec1e6bb181f8467bc2 [file] [log] [blame]
= `mvnd` - the Maven Daemon
This project aims at providing faster https://maven.apache.org/[Maven] builds using techniques known from Gradle and
Takari.
Architecture overview:
* `mvnd` embeds Maven (so there is no need to install Maven separately).
* The actual builds happen inside a long living background process, a.k.a. daemon.
* One daemon instance can serve multiple consecutive requests from the `mvnd` client.
* The `mvnd` client is a native executable built using https://www.graalvm.org/reference-manual/native-image/[GraalVM].
It starts faster and uses less memory compared to starting a traditional JVM.
* Multiple daemons can be spawned in parallel if there is no idle daemon to serve a build request.
This architecture brings the following advantages:
* The JVM for running the actual builds does not need to get started anew for each build.
* The classloaders holding classes of Maven plugins are cached over multiple builds. The plugin jars are thus read
and parsed just once. SNAPSHOT versions of Maven plugins are not cached.
* The native code produced by the Just-In-Time (JIT) compiler inside the JVM is kept too. Compared to stock Maven,
less time is spent by the JIT compilation. During the repeated builds the JIT-optimized code is available
immediately. This applies not only to the code coming from Maven plugins and Maven Core, but also to all code coming
from the JDK itself.
== Additional features
`mvnd` brings the following features on top of the stock Maven:
* `-T1C` is used by default. This means builing in parallel using as many threads as CPU cores on your machine. If your
source tree does not support parallel builds, pass `-T1` on the command line to make your build serial.
* Improved console output: we believe that the output of a parallel build on a stock Maven is hard to follow. Therefore,
we implemented a simplified a non-rolling view showing the status of each build thread on a separate line. This is
what it looks like on a machine with 24 cores:
+
image::src/main/images/console-output.png[]
+
Once the build is finshed, the complete Maven output is forwarded to the console.
== How to install `mvnd`
=== Install using https://sdkman.io/[SDKMAN!]
If SDKMAN! supports your operating system, it is as easy as
[source,shell]
----
$ sdk install mvnd
----
If you used the manual install in the past, please make sure that the settings in `~/.m2/mvnd.properties` still make
sense. With SDKMAN!, the `~/.m2/mvnd.properties` file is typically not needed at all, because both `JAVA_HOME` and
`MVND_HOME` are managed by SDKMAN!.
=== Install manually
* Download the latest ZIP suitable for your platform from https://github.com/mvndaemon/mvnd/releases
* Unzip to a directory of your choice
* Add the `bin` directory to `PATH`
* Optionally, you can create `~/.m2/mvnd.properties` and set the `java.home` property in case you do not want to bother
with setting `JAVA_HOME` environment variable.
* Test whether `mvnd` works:
+
[source,shell]
----
$ mvnd --version
Maven Daemon 0.0.0 (native)
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /home/ppalaga/orgs/mvnd/mvnd/daemon/target/maven-distro
Java version: 11.0.1, vendor: AdoptOpenJDK, runtime: /home/data/jvm/adopt-openjdk/jdk-11.0.1+13
Default locale: en_IE, platform encoding: UTF-8
OS name: "linux", version: "5.6.13-200.fc31.x86_64", arch: "amd64", family: "unix"
----
+
If you are on Windows and see a message that `VCRUNTIME140.dll was not found`, you need to install
`vc_redist.x64.exe` from https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads.
See https://github.com/oracle/graal/issues/1762 for more information.
== Usage
`mvnd` is designed to accept the same command line options like stock `mvn` (plus some extras - see below), e.g.:
[source,shell]
----
mvnd clean install
----
== `mvnd` specific options
`--status` lists running daemons
`--stop` kills all running daemons
== Build `mvnd` from source
=== Prerequisites:
* `git`
* Maven
* Download and unpack GraalVM CE from https://github.com/graalvm/graalvm-ce-builds/releases[GitHub]
* Set `JAVA_HOME` to where you unpacked GraalVM in the previous step. Check that `java -version` output is as
expected:
+
[source,shell]
----
$ $JAVA_HOME/bin/java -version
openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02)
OpenJDK 64-Bit Server VM GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02, mixed mode, sharing)
----
+
* Install the `native-image` tool:
+
[source,shell]
----
$ $JAVA_HOME/bin/gu install native-image
----
* `native-image` may require additional software to be installed depending on your platform - see the
https://www.graalvm.org/docs/reference-manual/native-image/#prerequisites[`native-image` documentation].
=== Build `mvnd`
[source,shell]
----
$ git clone https://github.com/mvndaemon/mvnd.git
$ cd mvnd
$ mvn clean verify -Pnative
...
$ cd client
$ file target/mvnd
target/mvnd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=93a554f3807550a13c986d2af9a311ef299bdc5a, for GNU/Linux 3.2.0, with debug_info, not stripped
$ ls -lh target/mvnd
-rwxrwxr-x. 1 ppalaga ppalaga 25M Jun 2 13:23 target/mvnd
----
This project is still in prototype mode, so feedback is most welcomed!