www

My personal website(s)
Log | Files | Refs

2013-09-08-maven-tmpfs.html (9980B)


      1 <!DOCTYPE html>
      2 <html lang="en">
      3 <head>
      4 <!-- Sep 03, 2024 -->
      5 <meta charset="utf-8" />
      6 <meta name="viewport" content="width=device-width, initial-scale=1" />
      7 <title>Maven Tmpfs</title>
      8 <meta name="author" content="Vincent Demeester" />
      9 <meta name="generator" content="Org Mode" />
     10 <link rel='icon' type='image/x-icon' href='/images/favicon.ico'/>
     11 <meta name='viewport' content='width=device-width, initial-scale=1'>
     12 <link rel='stylesheet' href='/css/new.css' type='text/css'/>
     13 <link rel='stylesheet' href='/css/syntax.css' type='text/css'/>
     14 <link href='/index.xml' rel='alternate' type='application/rss+xml' title='Vincent Demeester' />
     15 </head>
     16 <body>
     17 <main id="content" class="content">
     18 <header>
     19 <h1 class="title">Maven Tmpfs</h1>
     20 </header><section id="outline-container-Introduction" class="outline-2">
     21 <h2 id="Introduction">Introduction</h2>
     22 <div class="outline-text-2" id="text-Introduction">
     23 <p>
     24 Je suis un utilisateur convaincu de <a href="http://maven.apache.org/">maven</a>, malgré ces défauts, le
     25 moto <b>&ldquo;Convention over configuration&rdquo;</b> me va vraiment bien. Que ce soit
     26 au boulot ou à la maison, j&rsquo;ai plus d&rsquo;ordinateurs équipés de ssd (ou de
     27 mémoire flash) que de disque traditionnel (mécanique ?). Pour augmenter
     28 un peu la durée de vie de ces disques SSD, j&rsquo;ai cherché à savoir comment
     29 <i>déporter</i> le <i>build</i> de maven (qui, pour rappel, se passe dans le
     30 dossier <code>target/</code>) hors du SSD ; ici ce sera dans le dossier <code>/tmp/</code> qui
     31 est monté en mémoire (merci <code>tmpfs</code>), mais on peut imaginer déporter ça
     32 sur un autre disque, etc.. Après quelques recherches j&rsquo;ai trouvés
     33 quelques inspirations.
     34 </p>
     35 
     36 <blockquote>
     37 <p>
     38 <b>Limitations</b>
     39 </p>
     40 
     41 <p>
     42 Dans la solution présentée ci-dessous les principales limitations sont
     43 les suivantes (que j&rsquo;essaierais de diminuer au fil du temp ;P) :
     44 </p>
     45 
     46 <ol class="org-ol">
     47 <li>Il est nécessaire de modifier le pom.xml du projet ; cela ne
     48 s&rsquo;appliquera donc pas à tous les projets maven sans modification du
     49 pom.xml.</li>
     50 <li>Cela ne fonctionne que sur une plateforme qui support les liens
     51 symboliques (Linux, Mac OS X, et autre UNIX).</li>
     52 <li>Cela ne fonctionne qu&rsquo;avec Java 7 ou plus.</li>
     53 <li>Si vous utilisez m2e, il va gentillement gueuler et c&rsquo;est moche ; pour résoudre le
     54 problème, il faut faire un tour vers <a href="http://wiki.eclipse.org/M2E_plugin_execution_not_covered">M2E plugin execution not covered</a>.</li>
     55 </ol>
     56 </blockquote>
     57 
     58 <p>
     59 Pour <a href="http://maven.apache.org/">maven</a>, le dossier <code>target/</code> vient de la propriété
     60 <code>project.build.directory</code>. Dans la théorie, il suffirait de modifier
     61 (dans <code>$HOME/.m2/settings.xml</code>) cette propriété et le tour serait jouer.
     62 Malheuresement ce n&rsquo;est pas possible, <code>project.build.directory</code> est une
     63 propriété interne et n&rsquo;est, à priori, pas modifiable.
     64 </p>
     65 
     66 <p>
     67 Notre souhait est le suivant :
     68 </p>
     69 
     70 <ol class="org-ol">
     71 <li>Le build doit se faire dans <code>/tmp/m2/</code>, ce qui pour un projet se
     72 traduit par <code>/tmp/m2/${groupId}:${artifactId}</code>.</li>
     73 <li>Le dossier <code>target/</code> dans les sources est un lien symbolique vers le
     74 dossier dans <code>/tmp/m2/</code></li>
     75 <li>On passe par un <b>profile</b> qui n&rsquo;est <b>pas actif</b> par défaut (pour ne
     76 pas faire chier le monde) mais <b>activable via une propriété</b> (maven
     77 nous permet de le faire et c&rsquo;est cool <code>^_^</code>). La propriété utilisée
     78 sera <code>external.build.root</code>.</li>
     79 </ol>
     80 
     81 <p>
     82 Le code ci-dessous est repris directement de mon inspiration<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>. Il
     83 s&rsquo;occupe de créer le dossier <code>${groupId}:${artifactId}</code> dans
     84 <code>external.build.root</code> et de faire le lien dans le dossier courant.
     85 </p>
     86 
     87 <div class="org-src-container">
     88 <pre class="src src-xml">&lt;project&gt;
     89     &lt;!-- […] --&gt;
     90     &lt;profiles&gt;
     91         &lt;profile&gt;
     92             &lt;id&gt;external-build-dir&lt;/id&gt;
     93             &lt;activation&gt;
     94                 &lt;activeByDefault&gt;false&lt;/activeByDefault&gt;
     95                 &lt;property&gt;
     96                     &lt;name&gt;external.build.root&lt;/name&gt;
     97                 &lt;/property&gt;
     98             &lt;/activation&gt;
     99             &lt;build&gt;
    100                 &lt;plugins&gt;
    101                     &lt;plugin&gt;
    102                         &lt;groupId&gt;com.alexecollins.maven.plugin&lt;/groupId&gt;
    103                         &lt;artifactId&gt;script-maven-plugin&lt;/artifactId&gt;
    104                         &lt;version&gt;1.0.0&lt;/version&gt;
    105                         &lt;executions&gt;
    106                             &lt;execution&gt;
    107                                 &lt;id&gt;prep-work-tree&lt;/id&gt;
    108                                 &lt;goals&gt;
    109                                     &lt;goal&gt;execute&lt;/goal&gt;
    110                                 &lt;/goals&gt;
    111                                 &lt;phase&gt;initialize&lt;/phase&gt;
    112                                 &lt;configuration&gt;
    113                                     &lt;script&gt;
    114                                         import java.nio.file.*
    115                                         def dir =
    116                                         "${external.build.root}/${project.groupId}:${project.artifactId}"
    117                                         println "using Maven dir ${dir}"
    118                                         def dirPath = Paths.get(dir)
    119                                         if (!Files.exists(dirPath)) {
    120                                         Files.createDirectories(dirPath)
    121                                         }
    122                                         def target = Paths.get("${project.build.directory}")
    123                                         if (!Files.exists(target)) {
    124                                         Files.createSymbolicLink(target, dirPath)
    125                                         }&lt;/script&gt;
    126                                 &lt;/configuration&gt;
    127                             &lt;/execution&gt;
    128                             &lt;execution&gt;
    129                                 &lt;id&gt;drop-symlink&lt;/id&gt;
    130                                 &lt;goals&gt;
    131                                     &lt;goal&gt;execute&lt;/goal&gt;
    132                                 &lt;/goals&gt;
    133                                 &lt;phase&gt;clean&lt;/phase&gt;
    134                                 &lt;configuration&gt;
    135                                     &lt;script&gt;
    136                                         import java.nio.file.*
    137                                         def target = Paths.get("${project.build.directory}")
    138                                         if (Files.isSymbolicLink(target)) {
    139                                         Files.delete(target)
    140                                         }
    141                                     &lt;/script&gt;
    142                                 &lt;/configuration&gt;
    143                             &lt;/execution&gt;
    144                         &lt;/executions&gt;
    145                         &lt;dependencies&gt;
    146                             &lt;dependency&gt;
    147                                 &lt;groupId&gt;org.codehaus.groovy&lt;/groupId&gt;
    148                                 &lt;artifactId&gt;groovy&lt;/artifactId&gt;
    149                                 &lt;version&gt;1.8.6&lt;/version&gt;
    150                             &lt;/dependency&gt;
    151                         &lt;/dependencies&gt;
    152                         &lt;configuration&gt;
    153                             &lt;language&gt;groovy&lt;/language&gt;
    154                         &lt;/configuration&gt;
    155                     &lt;/plugin&gt;
    156                 &lt;/plugins&gt;
    157             &lt;/build&gt;
    158         &lt;/profile&gt;
    159     &lt;/profiles&gt;
    160     &lt;!-- […] --&gt;
    161 &lt;/project&gt;
    162 </pre>
    163 </div>
    164 
    165 <p>
    166 Ainsi, il suffit ensuite d&rsquo;avoir quelques choses du genre dans son
    167 <code>$HOME/.m2/settings.xml</code> pour que les builds qui ont ce profil se
    168 <i>build</i> dans <code>/tmp/m2/</code>. On peut aussi ne rien avoir dans
    169 <code>$HOME/.m2/settings.xml</code> et utilise <code>-Dexternal.build.root=/tmp/m2/</code>
    170 avec la commande <code>mvn</code>.
    171 </p>
    172 
    173 <div class="org-src-container">
    174 <pre class="src src-xml">&lt;settings&gt;
    175     &lt;!-- […] --&gt;
    176     &lt;profiles&gt;
    177         &lt;profile&gt;
    178             &lt;id&gt;build-in-ramfs&lt;/id&gt;
    179             &lt;properties&gt;
    180                 &lt;external.build.root&gt;/tmp/m2/&lt;/external.build.root&gt;
    181             &lt;/properties&gt;
    182         &lt;/profile&gt;
    183     &lt;/profiles&gt;
    184     &lt;activeProfiles&gt;
    185         &lt;activeProfile&gt;build-in-ramfs&lt;/activeProfile&gt;
    186     &lt;/activeProfiles&gt;
    187     &lt;!-- […] --&gt;
    188 &lt;/settings&gt;
    189 </pre>
    190 </div>
    191 </div>
    192 </section>
    193 <div id="footnotes">
    194 <h2 class="footnotes">Footnotes: </h2>
    195 <div id="text-footnotes">
    196 
    197 <div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
    198 <a href="http://elehack.net/writings/programming/maven-target-in-tmpfs">PuttingMaven build directories out-of-tree</a> par <a href="http://elehack.net/">Michal Ekstrand</a>
    199 </p></div></div>
    200 
    201 
    202 </div>
    203 </div></main>
    204 <footer id="postamble" class="status">
    205 <footer>
    206      <small><a href="/" rel="history">Index</a> • <a href="/sitemap.html">Sitemap</a> • <a href="https://dl.sbr.pm/">Files</a></small><br/>
    207      <small class='questions'>Questions, comments ? Please use my <a href="https://lists.sr.ht/~vdemeester/public-inbox">public inbox</a> by sending a plain-text email to <a href="mailto:~vdemeester/public-inbox@lists.sr.ht">~vdemeester/public-inbox@lists.sr.ht</a>.</small><br/>
    208      <small class='copyright'>
    209       Content and design by Vincent Demeester
    210       (<a rel='licence' href='http://creativecommons.org/licenses/by-nc-sa/3.0/'>Some rights reserved</a>)
    211     </small><br />
    212 </footer>
    213 </footer>
    214 </body>
    215 </html>