Skip to content

Put build directory of Maven into RAM

Updated: at 08:15 AM

I’ve recently bought an Intel 520 SSD, so my top priority for my laptop is to reduce the disk write during daily use. In the Java world, Maven is one of the most common build tool out there. My most used Maven command is:

mvn clean package

This command will do a fresh build of the project, then copy all the compiled classes/resources to the build directory of Maven (which is the folder ‘target’, next to your source directory). If you have a large Maven project at hand, this command will perform thousands disk write (clean compiled classes and resources, then compile Java classes and assemble the resources into WAR/JAR file). By changing the build directory of Maven to /tmp (which is a tmpfs mountpoint (residing on RAM on my ArchLinux)), I can now rebuild my project as many times as I like without the write amplication concern. Here is now I do it in Maven:

<properties>
    <target.directory>/tmp/maven/${project.groupId}-${project.artifactId}/target</target.directory>
</properties>

With the above configuration, maven will do all the build in /tmp, my SSD will thanks me for this :), but we have a small problem! Eclipse does not allow the build directory to be located outside the project directory, but I have a workaround for that. By defining a linked resource, Eclipse will happily with our setup! Here is the complete sample pom.xml file:

<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>
 <groupId>com.abc</groupId>
 <artifactId>abc</artifactId>
 <packaging>war</packaging>
 <version>1.0</version>
 <name>Sampe Webapp</name>
 <url>http://www.abc.com</url>
 <properties>
  <target.directory>target</target.directory>
 </properties>
 <dependencies>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>3.8.1</version>
   <scope>test</scope>
  </dependency>
 </dependencies>
 <build>
  <finalName>abc</finalName>
  <directory>${target.directory}</directory>
 </build>
 <plugins>
   <plugin>
     <artifactId>maven-eclipse-plugin</artifactId>
       <version>2.8</version>
       <configuration>
         <downloadSources>true</downloadSources>
         <downloadJavadocs>true</downloadJavadocs>
         <buildOutputDirectory>target</buildOutputDirectory>
         <linkedResources>
           <linkedResource>
             <name>target</name>
             <type>2</type>
             <location>${project.build.outputDirectory}</location>
           </linkedResource>
         </linkedResources>
       </configuration>
   </plugin>
 </plugins>
</project>

And the sample settings.xml file:

<?xml version="1.0"?>
<settings>
  <profiles>
    <profile>
      <id>development</id>
      <properties>
        <target.directory>/tmp/maven/${project.groupId}-${project.artifactId}/target</target.directory>
      </properties>
    </profile>
    <profile>
      <id>public-snapshots</id>
  </profiles>
  <activeProfiles>
    <activeProfile>development</activeProfile>
  </activeProfiles>
</settings>

Happy coding!