main
  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>
 24Je suis un utilisateur convaincu de <a href="http://maven.apache.org/">maven</a>, malgré ces défauts, le
 25moto <b>&ldquo;Convention over configuration&rdquo;</b> me va vraiment bien. Que ce soit
 26au boulot ou à la maison, j&rsquo;ai plus d&rsquo;ordinateurs équipés de ssd (ou de
 27mémoire flash) que de disque traditionnel (mécanique ?). Pour augmenter
 28un 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
 30dossier <code>target/</code>) hors du SSD ; ici ce sera dans le dossier <code>/tmp/</code> qui
 31est monté en mémoire (merci <code>tmpfs</code>), mais on peut imaginer déporter ça
 32sur un autre disque, etc.. Après quelques recherches j&rsquo;ai trouvés
 33quelques inspirations.
 34</p>
 35
 36<blockquote>
 37<p>
 38<b>Limitations</b>
 39</p>
 40
 41<p>
 42Dans la solution présentée ci-dessous les principales limitations sont
 43les 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
 48s&rsquo;appliquera donc pas à tous les projets maven sans modification du
 49pom.xml.</li>
 50<li>Cela ne fonctionne que sur une plateforme qui support les liens
 51symboliques (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
 54problè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>
 59Pour <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.
 62Malheuresement ce n&rsquo;est pas possible, <code>project.build.directory</code> est une
 63propriété interne et n&rsquo;est, à priori, pas modifiable.
 64</p>
 65
 66<p>
 67Notre 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
 72traduit par <code>/tmp/m2/${groupId}:${artifactId}</code>.</li>
 73<li>Le dossier <code>target/</code> dans les sources est un lien symbolique vers le
 74dossier 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
 76pas faire chier le monde) mais <b>activable via une propriété</b> (maven
 77nous permet de le faire et c&rsquo;est cool <code>^_^</code>). La propriété utilisée
 78sera <code>external.build.root</code>.</li>
 79</ol>
 80
 81<p>
 82Le 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
 83s&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>
166Ainsi, 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>
170avec 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>