ramdisk
Use ramdisk (tmpfs) for the build directory (target)
💡
What
Switch Maven build directories to ramdisk/tmpfs (such that all generated files are in-memory).
🔬
Why
- Faster builds
- Save SSD/HDD from ephemeral churn
On local desktop (with projects on SATA3 SSD), I observe a 20-30% reduction in build time (with/out parallel build settings).
🔩
How
Hooks into the build at various points, swapping ${project} (by default ./target) with a symbolic-link pointing to a directory in tmpfs (intentionally avoiding modification of build properties, implicit default or otherwise.
This approach has the lightest touch, allowing presumptuous plugins and tests to continue in oblivion. However it does requires running the plugin with extensions enabled or as a standalone extension.
If you’re using feature-branching, or similar (effectively parallel builds of the same groupId:artifactId:version), then you must explicitly state the branch identifier in the POM. Alternatively you may manage this by setting the tmpfs base path as a property.
By way of example: a mapping into tmpfs has the form /run/user/1000/maven/groupId/artifactId/version/HEAD - parallel builds need some unique combination of tmpfs_root + groupId + artifactId + version + branchId (note: the tmpfs root can be different per user).
🔨
Usage
As previously stated, this is both a plugin and a build extension.
This provides opportunity for use without modifying checkouts or remembering to augment maven commands.
Review the dis/advantages of options, below and select the best fit for your use-case.
Usage Option 1: Maven distribution extension
Add the uber jar to ${MAVEN_HOME}/lib/ext
- Advantages:
- Ensure all Maven projects using this distribution are built in ram (exceptional cases can skipped with property)
- No modification to checked out project
- No augmentation of maven commands
- Disadvantages:
- All the issues that come with monkey-patching
- No version update reporting
- No transparency (not so bad if you codify this monkey-patch via CD, eg. Dockerfile, Puppet, Ansible, etc)
Usage Option 2: Project core extension
Define core extensions, by downloading
extensions.xml and saving as ${project}/.mvn/extensions.xml (or otherwise editing existing to include).
- Prerequisite: Maven >= 3.3.1
- Advantages:
- Doesn’t alter existing checked out files
- Determined on a per-project basis
- Safe; ignored if unsupported (eg. Windows)
- Disadvantages:
- Not inherited (only applied to explicitly stated child modules)
- Still modifies the checked out project (if not committed, which may not be possible)
- Not sure this would covered by version update (reporting and automating update)
- Not much transparency (given most IDEs and file browsers don’t show .hidden directories by default)
Usage Option 3: POM build extension or plugin
The double-edged sword of explicit definition.
In the <build> section, include the following:
<extensions> <extension> <groupId>io.earcam.maven.plugin</groupId> <artifactId>io.earcam.maven.plugin.ramdisk</artifactId> <version>${version.this.plugin}</version> </extension> </extensions>
Or:
<plugin> <groupId>io.earcam.maven.plugin</groupId> <artifactId>io.earcam.maven.plugin.ramdisk</artifactId> <version>${version.this.plugin}</version> <extensions>true</extensions> </plugin>
Note: <extensions>true</extensions> in the above is vital.
- Advantages:
- Explicit definition (immediately obvious to developer)
- Can be defined in a common parent and inherited
- Safe; ignored if unsupported (eg. Windows)
- Subject to version update reports
- Disadvantages:
- Explicit definition (requires author to apply, or client modification of XML)
- Might make non-Linux users more sad
🗑
Removing
If you decide to remove the plugin/extension, then you may be left with dead softlinks. The following goal can be executed manually to remove softlinks (dead or alive):
mvn ramdisk:cleanup
Or (if not defined in the project’s pom):
mvn io.earcam.maven.plugin:io.earcam.maven.plugin.ramdisk:0.0.4:cleanup
🔧
Properties
Skip execution
Set the property either cmdline -D or in the pom.xml’s <properties>:
<earcam.ramdisk.skip>true</earcam.ramdisk.skip>
Force base path
Set the property either cmdline -D or in the pom.xml’s <properties>:
<earcam.ramdisk.dir>/tmp/build/maven</earcam.ramdisk.dir>
🐧
Supported Operating Systems
Really only aimed at Linux/UNIX.
Mac OSX users can create a ramdisk and then set this ram:// FS via the base path property (then further could be achieve global zero-conf with an always active profile in `~/.m2/settings.xml’)
Users of Windows could try with ubuntu-shell or consider something like ImDisk (from a reputable source), and then set the base path (see above).
🥩