main
  1<!DOCTYPE html>
  2
  3<html lang="fr">
  4  
  5  <head>
  6    <meta charset="utf-8">
  7    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  8
  9    <link rel="start" href="https://vincent.demeester.fr" />
 10
 11    <title>Vincent Demeester</title>
 12    <link rel="canonical" href="https://vincent.demeester.fr/posts/2013-09-08-maven-tmpfs/">
 13    <link href="https://vincent.demeester.fr/index.xml" rel="alternate" type="application/rss+xml" title="Vincent Demeester" />
 14
 15    <link rel="openid.server" href="https://indieauth.com/openid" />
 16    <link rel="openid.delegate" href="http://vincent.demeester.fr/" />
 17    <link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
 18
 19    <link rel="stylesheet" href="/css/screen.css" type="text/css" />
 20    <link rel="stylesheet" href="/css/sbrain.css" type="text/css" />
 21    <link rel="stylesheet" href="/css/syntax.css" type="text/css" />
 22
 23  </head>
 24  
 25  <body lang="fr"/>
 26  
 27
 28
 29
 30
 31
 32<div id="main-container">
 33  <div id="page">
 34    <article class="post">
 35      <header>
 36        <h1 class="emphnext">Maven Tmpfs</h1><a href='https://vincent.demeester.fr/posts/2013-09-08-maven-tmpfs/'></a>
 37        <address class="signature">
 38          <span class="date">Sun, 8 September, 2013</span>
 39          <span class="words">(600 Words)</span>
 40        </address>
 41	<ul class="tag_box inline">
 42	  
 43	  <li class="category"><a href="/categories/#developement">developement</a></li>
 44	  
 45	  
 46	  
 47	  
 48	  
 49	  <li class="tag tag-maven"><a href="/tags/#maven">maven<span>2</span></a></li>
 50	  
 51	  
 52	  <li class="tag tag-tmpfs"><a href="/tags/#tmpfs">tmpfs<span>1</span></a></li>
 53	  
 54	  
 55	  <li class="tag tag-ssd"><a href="/tags/#ssd">ssd<span>1</span></a></li>
 56	  
 57	  <br/>
 58	  
 59	</ul>
 60      </header>
 61      
 62      
 63      
 64      <p>Je suis un utilisateur convaincu de [maven](), malgré ces défauts, le moto
 65<strong>&ldquo;Convention over configuration&rdquo;</strong> me va vraiment bien. Que ce soit au boulot ou
 66à la maison, j&rsquo;ai plus d&rsquo;ordinateurs équipés de ssd (ou de mémoire flash) que de
 67disque traditionnel (mécanique ?). Pour augmenter un peu la durée de vie de
 68ces disques SSD, j&rsquo;ai cherché à savoir comment <em>déporter</em> le <em>build</em> de maven
 69(qui, pour rappel, se passe dans le dossier <code>target/</code>) hors du SSD ; ici ce
 70sera dans le dossier <code>/tmp/</code> qui est monté en mémoire (merci <code>tmpfs</code>),
 71mais on peut imaginer déporter ça sur un autre disque, etc.. Après quelques
 72recherches j&rsquo;ai trouvés quelques inspirations.</p>
 73
 74<blockquote>
 75<p><strong>Limitations</strong></p>
 76
 77<p>Dans la solution présentée ci-dessous les principales limitations sont
 78les suivantes (que j&rsquo;essaierais de diminuer au fil du temp ;P) :</p>
 79
 80<ol>
 81<li>Il est nécessaire de modifier le pom.xml du projet ; cela ne s&rsquo;appliquera
 82donc pas à tous les projets maven sans modification du pom.xml.</li>
 83<li>Cela ne fonctionne que sur une plateforme qui support les liens
 84symboliques (Linux, Mac OS X, et autre UNIX).</li>
 85<li>Cela ne fonctionne qu&rsquo;avec Java 7 ou plus.</li>
 86<li>Si vous utilisez m2e, il va gentillement gueuler et c&rsquo;est moche ; pour
 87résoudre le problème, il faut faire un tour vers <a href="http://wiki.eclipse.org/M2E_plugin_execution_not_covered">M2E plugin execution
 88not covered</a>.</li>
 89</ol>
 90</blockquote>
 91
 92<p>Pour [maven](), le dossier <code>target/</code> vient de la propriété
 93<code>project.build.directory</code>. Dans la théorie, il suffirait de modifier (dans
 94<code>$HOME/.m2/settings.xml</code>) cette propriété et le tour serait jouer.
 95Malheuresement ce n&rsquo;est pas possible, <code>project.build.directory</code> est une
 96propriété interne et n&rsquo;est, à priori, pas modifiable.</p>
 97
 98<p>Notre souhait est le suivant :</p>
 99
100<ol>
101<li>Le build doit se faire dans <code>/tmp/m2/</code>, ce qui pour un projet se traduit
102par <code>/tmp/m2/${groupId}:${artifactId}</code>.</li>
103<li>Le dossier <code>target/</code> dans les sources est un lien symbolique vers le
104dossier dans <code>/tmp/m2/</code></li>
105<li>On passe par un <strong>profile</strong> qui n&rsquo;est <strong>pas actif</strong> par défaut (pour ne pas
106faire chier le monde) mais <strong>activable via une propriété</strong> (maven nous permet
107de le faire et c&rsquo;est cool <code>^_^</code>). La propriété utilisée sera
108<code>external.build.root</code>.</li>
109</ol>
110
111<p>Le code ci-dessous est repris directement de mon inspiration<sup class="footnote-ref" id="fnref:inspiration"><a href="#fn:inspiration">1</a></sup>. Il
112s&rsquo;occupe de créer le dossier <code>${groupId}:${artifactId}</code> dans
113<code>external.build.root</code> et de faire le lien dans le dossier courant.</p>
114
115<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;project&gt;</span>
116    <span class="c">&lt;!-- […] --&gt;</span>
117    <span class="nt">&lt;profiles&gt;</span>
118        <span class="nt">&lt;profile&gt;</span>
119            <span class="nt">&lt;id&gt;</span>external-build-dir<span class="nt">&lt;/id&gt;</span>
120            <span class="nt">&lt;activation&gt;</span>
121                <span class="nt">&lt;activeByDefault&gt;</span>false<span class="nt">&lt;/activeByDefault&gt;</span>
122                <span class="nt">&lt;property&gt;</span>
123                    <span class="nt">&lt;name&gt;</span>external.build.root<span class="nt">&lt;/name&gt;</span>
124                <span class="nt">&lt;/property&gt;</span>
125            <span class="nt">&lt;/activation&gt;</span>
126            <span class="nt">&lt;build&gt;</span>
127                <span class="nt">&lt;plugins&gt;</span>
128                    <span class="nt">&lt;plugin&gt;</span>
129                        <span class="nt">&lt;groupId&gt;</span>com.alexecollins.maven.plugin<span class="nt">&lt;/groupId&gt;</span>
130                        <span class="nt">&lt;artifactId&gt;</span>script-maven-plugin<span class="nt">&lt;/artifactId&gt;</span>
131                        <span class="nt">&lt;version&gt;</span>1.0.0<span class="nt">&lt;/version&gt;</span>
132                        <span class="nt">&lt;executions&gt;</span>
133                            <span class="nt">&lt;execution&gt;</span>
134                                <span class="nt">&lt;id&gt;</span>prep-work-tree<span class="nt">&lt;/id&gt;</span>
135                                <span class="nt">&lt;goals&gt;</span>
136                                    <span class="nt">&lt;goal&gt;</span>execute<span class="nt">&lt;/goal&gt;</span>
137                                <span class="nt">&lt;/goals&gt;</span>
138                                <span class="nt">&lt;phase&gt;</span>initialize<span class="nt">&lt;/phase&gt;</span>
139                                <span class="nt">&lt;configuration&gt;</span>
140                                    <span class="nt">&lt;script&gt;</span>
141                                        import java.nio.file.*
142                                        def dir =
143                                        &#34;${external.build.root}/${project.groupId}:${project.artifactId}&#34;
144                                        println &#34;using Maven dir ${dir}&#34;
145                                        def dirPath = Paths.get(dir)
146                                        if (!Files.exists(dirPath)) {
147                                        Files.createDirectories(dirPath)
148                                        }
149                                        def target = Paths.get(&#34;${project.build.directory}&#34;)
150                                        if (!Files.exists(target)) {
151                                        Files.createSymbolicLink(target, dirPath)
152                                        }<span class="nt">&lt;/script&gt;</span>
153                                <span class="nt">&lt;/configuration&gt;</span>
154                            <span class="nt">&lt;/execution&gt;</span>
155                            <span class="nt">&lt;execution&gt;</span>
156                                <span class="nt">&lt;id&gt;</span>drop-symlink<span class="nt">&lt;/id&gt;</span>
157                                <span class="nt">&lt;goals&gt;</span>
158                                    <span class="nt">&lt;goal&gt;</span>execute<span class="nt">&lt;/goal&gt;</span>
159                                <span class="nt">&lt;/goals&gt;</span>
160                                <span class="nt">&lt;phase&gt;</span>clean<span class="nt">&lt;/phase&gt;</span>
161                                <span class="nt">&lt;configuration&gt;</span>
162                                    <span class="nt">&lt;script&gt;</span>
163                                        import java.nio.file.*
164                                        def target = Paths.get(&#34;${project.build.directory}&#34;)
165                                        if (Files.isSymbolicLink(target)) {
166                                        Files.delete(target)
167                                        }
168                                    <span class="nt">&lt;/script&gt;</span>
169                                <span class="nt">&lt;/configuration&gt;</span>
170                            <span class="nt">&lt;/execution&gt;</span>
171                        <span class="nt">&lt;/executions&gt;</span>
172                        <span class="nt">&lt;dependencies&gt;</span>
173                            <span class="nt">&lt;dependency&gt;</span>
174                                <span class="nt">&lt;groupId&gt;</span>org.codehaus.groovy<span class="nt">&lt;/groupId&gt;</span>
175                                <span class="nt">&lt;artifactId&gt;</span>groovy<span class="nt">&lt;/artifactId&gt;</span>
176                                <span class="nt">&lt;version&gt;</span>1.8.6<span class="nt">&lt;/version&gt;</span>
177                            <span class="nt">&lt;/dependency&gt;</span>
178                        <span class="nt">&lt;/dependencies&gt;</span>
179                        <span class="nt">&lt;configuration&gt;</span>
180                            <span class="nt">&lt;language&gt;</span>groovy<span class="nt">&lt;/language&gt;</span>
181                        <span class="nt">&lt;/configuration&gt;</span>
182                    <span class="nt">&lt;/plugin&gt;</span>
183                <span class="nt">&lt;/plugins&gt;</span>
184            <span class="nt">&lt;/build&gt;</span>
185        <span class="nt">&lt;/profile&gt;</span>
186    <span class="nt">&lt;/profiles&gt;</span>
187    <span class="c">&lt;!-- […] --&gt;</span>
188<span class="nt">&lt;/project&gt;</span></code></pre></div>
189
190<p>Ainsi, il suffit ensuite d&rsquo;avoir quelques choses du genre dans son
191<code>$HOME/.m2/settings.xml</code> pour que les builds qui ont ce profil se <em>build</em>
192dans <code>/tmp/m2/</code>. On peut aussi ne rien avoir dans <code>$HOME/.m2/settings.xml</code>
193et utilise <code>-Dexternal.build.root=/tmp/m2/</code> avec la commande <code>mvn</code>.</p>
194
195<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;settings&gt;</span>
196    <span class="c">&lt;!-- […] --&gt;</span>
197    <span class="nt">&lt;profiles&gt;</span>
198        <span class="nt">&lt;profile&gt;</span>
199            <span class="nt">&lt;id&gt;</span>build-in-ramfs<span class="nt">&lt;/id&gt;</span>
200            <span class="nt">&lt;properties&gt;</span>
201                <span class="nt">&lt;external.build.root&gt;</span>/tmp/m2/<span class="nt">&lt;/external.build.root&gt;</span>
202            <span class="nt">&lt;/properties&gt;</span>
203        <span class="nt">&lt;/profile&gt;</span>
204    <span class="nt">&lt;/profiles&gt;</span>
205    <span class="nt">&lt;activeProfiles&gt;</span>
206        <span class="nt">&lt;activeProfile&gt;</span>build-in-ramfs<span class="nt">&lt;/activeProfile&gt;</span>
207    <span class="nt">&lt;/activeProfiles&gt;</span>
208    <span class="c">&lt;!-- […] --&gt;</span>
209<span class="nt">&lt;/settings&gt;</span></code></pre></div>
210<div class="footnotes">
211
212<hr />
213
214<ol>
215<li id="fn:inspiration"><a href="http://elehack.net/writings/programming/maven-target-in-tmpfs">Putting Maven build directories out-of-tree</a> par <a href="http://elehack.net/">Michal Ekstrand</a>
216 <a class="footnote-return" href="#fnref:inspiration"><sup>[return]</sup></a></li>
217</ol>
218</div>
219
220      
221    </article>
222    <hr />
223    <div class="prev-next">
224      
225      <a class="paging-link prev" href="/posts/2013-10-12-podcasts/" title="Podcasts">← Previous post</a>
226      
227
228      
229      <a class="paging-link next" href="/posts/2012-12-16-gollum-comme-wiki-personnel/" title="Gollum Comme Wiki Personnel">Next post →</a>
230      
231    </div>
232
233  </div>
234</div>
235
236<footer>
237  <nav>
238    
239    <a href="/">home</a>
240    <span class="text-muted"> | </span>
241    
242    <a href="/about">about</a>
243    <span class="text-muted"> | </span>
244    
245    <a href="/archive">archive</a>
246    <span class="text-muted"> | </span>
247    
248    <a href="/categories">categories</a>
249    <span class="text-muted"> | </span>
250    
251    <a href="/tags">tags</a>
252    <span class="text-muted"> | </span>
253    
254    <a href="https://twitter.com/vdemeest">twitter</a>
255    <span class="text-muted"> | </span>
256    
257    <a href="https://github.com/vdemeester">github</a>
258    <span class="text-muted"> | </span>
259    
260    <a href="https://vincent.demeester.fr/index.xml">rss</a>
261  </nav>
262  <br/>
263  <address>
264    <span class="copyright">
265      Content and design by Vincent Demeester
266      (<a rel="licence" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Some rights reserved</a>)
267    </span><br />
268    <span class="engine">
269      Powered by <a href="https://gohugo.io/">Hugo</a> and <a href="https://github.com/kaushalmodi/ox-hugo/">ox-hugo</a>
270    </span>
271  </address>
272</footer>
273</body>
274