forked from vert-x/vert-x.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmods_manual.html
487 lines (472 loc) · 39.2 KB
/
mods_manual.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<link href='http://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css'>
<!-- <link rel="stylesheet/less" href="bootstrap/less/bootstrap.less">
<script src="bootstrap/less/less-1.3.3.min.js"></script>
-->
<link href="bootstrap/bootstrap.css" type="text/css" rel="stylesheet"/>
<link href="google-code-prettify/prettify.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="google-code-prettify/prettify.js"></script>
<link href="css/vertx.css" type="text/css" rel="stylesheet"/>
<link href="css/sunburst.css" type="text/css" rel="stylesheet"/>
<title>Vert.x</title>
<script>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-30144458-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body onload="prettyPrint()" class="hp">
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse"
data-target=".nav-collapse">
<span class="i-bar"></span>
<span class="i-bar"></span>
<span class="i-bar"></span>
</a>
<a class="brand" href="/">Vert.x</a>
<div class="nav-collapse">
<ul class="nav">
<li><a href="/">Home</a></li>
<li><a href="downloads.html">Download</a></li>
<li><a href="install.html">Install</a></li>
<li><a href="docs.html">Documentation</a></li>
<li><a href="examples.html">Examples</a></li>
<li><a href="community.html">Project Info</a></li>
<li><a href="https://github.com/vert-x/vert.x">Github</a></li>
<li><a href="http://modulereg.vertx.io/">Module Registry</a></li>
<li><a href="http://groups.google.com/group/vertx">Google Group</a></li>
<li><a href="http://vertxproject.wordpress.com/">Blog</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="span12">
<div class="well">
<h1>Modules Manual</h1>
</div>
</div>
</div>
<div class="row">
<div class="span12">
<div class="well">
<div>
<div class="toc">
<ul>
<li><a href="#what-is-a-vertx-module">What is a Vert.x module ?</a></li>
<li><a href="#runnable-modules">Runnable Modules</a></li>
<li><a href="#module-identifier">Module Identifier</a></li>
<li><a href="#the-structure-of-a-module">The structure of a module</a><ul>
<li><a href="#module-descriptor-file-modjson">Module descriptor file - mod.json</a><ul>
<li><a href="#main">main</a></li>
<li><a href="#lang-impl">lang-impl</a></li>
<li><a href="#worker">worker</a></li>
<li><a href="#multi-threaded">multi-threaded</a></li>
<li><a href="#includes">includes</a></li>
<li><a href="#preserve-cwd">preserve-cwd</a></li>
<li><a href="#auto-redeploy">auto-redeploy</a></li>
<li><a href="#resident">resident</a></li>
<li><a href="#system">system</a></li>
<li><a href="#deploys">deploys</a></li>
<li><a href="#description">description</a></li>
<li><a href="#licenses">licenses</a></li>
<li><a href="#author">author</a></li>
<li><a href="#keywords">keywords</a></li>
<li><a href="#developers">developers</a></li>
<li><a href="#homepage">homepage</a></li>
</ul>
</li>
<li><a href="#module-lib-directory">Module lib directory</a></li>
<li><a href="#examples">Examples</a></li>
</ul>
</li>
<li><a href="#module-classpath">Module classpath</a></li>
<li><a href="#module-classloaders">Module classloaders</a></li>
<li><a href="#including-the-resources-of-modules">Including the resources of modules</a></li>
<li><a href="#running-a-module-from-the-command-line">Running a module from the command line</a></li>
<li><a href="#running-a-module-programmatically">Running a module programmatically</a></li>
<li><a href="#how-vertx-locates-modules">How Vert.x locates modules</a><ul>
<li><a href="#mapping-a-module-identifier-to-maven-co-ordinates">Mapping a Module Identifier to Maven co-ordinates</a></li>
<li><a href="#mapping-a-module-identifier-to-bintray-co-ordinates">Mapping a Module Identifier to Bintray co-ordinates</a></li>
</ul>
</li>
<li><a href="#creating-fat-executable-jars">Creating fat executable jars</a></li>
<li><a href="#nested-modules-packaging-all-module-dependencies-in-the-module">Nested modules - Packaging all module dependencies in the module</a><ul>
<li><a href="#installing-modules-manually-from-the-repository">Installing modules manually from the repository</a></li>
</ul>
</li>
<li><a href="#uninstalling-modules">Uninstalling modules</a></li>
<li><a href="#how-to-publish-modules-to-remote-repositories">How to publish modules to remote repositories</a><ul>
<li><a href="#publishing-to-maven-repositories">Publishing to Maven repositories</a></li>
<li><a href="#publishing-to-bintray">Publishing to Bintray</a></li>
</ul>
</li>
<li><a href="#telling-the-world-about-your-module-introducing-the-vertx-module-registry">Telling the world about your module - Introducing the Vert.x Module Registry</a></li>
<li><a href="#module-configuration">Module configuration</a></li>
</ul>
</div>
<h1 id="what-is-a-vertx-module">What is a Vert.x module ?</h1><br/>
<p>Vert.x allows you to package up your applications or other re-usable functionality into modules which can then be deployed or used by other Vert.x code. </p>
<p>Creating your app as module(s) gives you the following benefits:</p>
<ul>
<li>Your classpath is encapsulated so modules are easier to run. You don't need to craft any long command lines.</li>
<li>Your dependencies are encapsulated in a single artifact (the module zip file)</li>
<li>Your module can be pushed to any Maven repository or <a href="http://bintray.com">Bintray</a>.</li>
<li>Your module can be catalogued in the Vert.x <a href="https://modulereg.vertx.io">module registry</a> so others can discover and use it</li>
<li>Vert.x can automatically download and install modules from any repository given just the module identifier.</li>
</ul>
<p>For these reasons it is highly recommend that you always assemble your applications as modules and you don't use raw verticles (i.e. using <code>vertx run</code> from the command line to run a verticle) for anything other than trivial prototyping and examples.</p>
<p><a id="runnable"> </a></p>
<h1 id="runnable-modules">Runnable Modules</h1><br/>
<p>Many types of modules are <em>runnable</em> - this means they have a <code>main</code> field specified in the <code>mod.json</code> descriptor. This means instances of the module can be deployed and run at the command line using <code>vertx runmod</code> or programmatically using <code>container.deployModule(...)</code>.</p>
<p>Modules don't have to be runnable. It is valid for a module not to specify a <code>main</code> - this means the module is <em>non-runnable</em>. Non runnable modules are useful when you want to <a href="#including">include</a> the resources of one module into another.</p>
<p><a id="mod-id"> </a></p>
<h1 id="module-identifier">Module Identifier</h1><br/>
<p>Each module has a unique identifier. The identifier is a string that is composed of three parts:</p>
<ul>
<li>Owner - represents the owner of the module. Often this will be a reverse domain name (like a Maven GroupID or Java package), but it doesn't have to be - it's just a string.</li>
<li>Name - the name of the module - again just a string</li>
<li>Version - the version of the module - also just a string - Vert.x doesn't enforce any particular version naming conventions.</li>
</ul>
<p>The three parts are separated by the tilda character '~' and concatenated together to form the module identifier string. Why do we use tilda? We experimented with other characters (e.g. <code>#</code>, <code>:</code>) but it's hard to find something that works on all operating systems (e.g. <code>:</code> is a reserved char in Windows filenames) and language implementations.</p>
<p>Examples of module identifiers:</p>
<p>Here are a couple of example of modules that are stored in Maven repositories:</p>
<pre class="prettyprint">io.vertx~mod-mongo-persistor~2.0.0-beta1
com.mycompany~toaster-mod~1.2.1-final
</pre>
<p>Here's an example that's stored in <a href="http://bintray.com">Bintray</a></p>
<pre class="prettyprint">purplefox~foomod~1.0
</pre>
<p>The <code>io.vertx</code> module owner is reserved for "official" modules created by the Vert.x project itself, so don't use this owner for your own modules.</p>
<h1 id="the-structure-of-a-module">The structure of a module</h1><br/>
<p>A Vert.x module is a <code>zip</code> file which contains the resources (<code>.class</code> files, <code>.java</code> files, script files, <code>jar</code> files and other resources) needed by your module.</p>
<p>In some ways it is similar to a <code>jar</code> file used in the Java world. We deliberately did not use <code>jar</code> files for Vert.x modules because Vert.x is a polyglot system and a particular module might, for instance, only contain python scripts, so using a Java archive for this would be somewhat strange!</p>
<h2 id="module-descriptor-file-modjson">Module descriptor file - mod.json</h2><br/>
<p>Every module must contain a file <code>mod.json</code> in the root of the module. This is the module descriptor file and contains various fields. It's a text file which contains some JSON. We relax the JSON specification a little bit and also allow you to add C-style comments in your <code>mod.json</code> so you can annotate your configuration. </p>
<p>Let's go through the fields in turn:</p>
<h3 id="main">main</h3><br/>
<p>If the module is <a href="#runnable">runnable</a> then a <code>main</code> must be specified. The main represents the verticle that will be run to start the module. The main can be the fully qualified class name of a compiled Java or Groovy verticle or it can be the name of a JavaScript, Groovy, Ruby or Python script verticle.</p>
<p>Here are some example:</p>
<pre class="prettyprint">"main": "org.mycompany.mymod.MyMain"
</pre>
<p>or</p>
<pre class="prettyprint">"main": "app.js"
</pre>
<p>or</p>
<pre class="prettyprint">"main": "somedir/starter.rb"
</pre>
<p>All language implementations in Vert.x are themselves implemented as modules. In order to determine which language implementation module to use to run the main, Vert.x usually looks at the file extension, and uses the mapping defined in the file <code>langs.properties</code> in the Vert.x installation <code>conf</code> directory to look up the language implementation.</p>
<p>In some cases there is ambiguity, for example given a FQCN should we assume the class is Java or Groovy? In these cases the main can be prefixed with the name of the language implementation to use, for example:</p>
<pre class="prettyprint">"main": "groovy:org.mycompany.mymod.MyCompiledGroovyClass"
</pre>
<p>You can also add the field <code>lang-impl</code> to mod.json to specify which language implementation module you want to run the module with. This overrides any settings in <code>langs.properties</code>.</p>
<h3 id="lang-impl">lang-impl</h3><br/>
<p>Normally Vert.x will infer which language module to use to run the module by either looking at the prefix of the file extension of the main. This behaviour can be overridden by specifying a field <code>lang-impl</code> where the value is as it would normally appear in <code>langs.properties</code>, e.g.:</p>
<pre class="prettyprint">"lang-impl": com.company~lang-cobol~1.0.0:com.mycompany.langmod.CobolVerticleFactory
</pre>
<p>Please see the <a href="language_support.html">language support guide</a> for more information on the format of this string.</p>
<p>Please note that this can only be used to change the language implementation to be used for that particular module, not any verticles it may spawn. To globally change the language implementation for Vert.x you can edit <code>langs.properties</code>.</p>
<h3 id="worker">worker</h3><br/>
<p>If the module is a worker this should be set to <code>true</code>. Worker modules run using a thread from the background pool and are allowed to perform blocking operations. Standard verticles run using an event loop thread and cannot block. Default is <code>false</code>.</p>
<pre class="prettyprint">"worker": true
</pre>
<h3 id="multi-threaded">multi-threaded</h3><br/>
<p>If the module is a worker then setting this to <code>true</code> makes the worker multi-threaded, i.e. the code in the module can be executed concurrently by different worker threads. This can be useful when writing modules that wrap things like JDBC connection pools. Use this with caution - this a power user feature not intended to be used in normal Vert.x development. Default is <code>false</code>.</p>
<p><a id="includes"> </a></p>
<h3 id="includes">includes</h3><br/>
<p>A module can <em>include</em> zero or more other modules. Including a module means the included modules classloaders are added as parents of the including module class loader. This means classes and resources from other modules can be accessed as if they were available in the including module. In some ways it's similar to importing packages in Java.</p>
<p>The <code>includes</code> is a comma separated string of module identifiers corresponding to the modules you want to include.</p>
<pre class="prettyprint">"includes": "io.vertx~some-module~1.1,org.aardvarks~foo-mod~3.21-beta1"
</pre>
<h3 id="preserve-cwd">preserve-cwd</h3><br/>
<p>When a module is executing if it uses Vert.x to access the filesystem it will, by default, see the module directory as the current directory. Let's say you have a web application that you wish to package as a module. This allows you to package up the resources of your web application inside the module and your module will see them.</p>
<p>For example, let's say we have a module with the following structure:</p>
<pre class="prettyprint">/mod.json
/server.js
/web/index.html
</pre>
<p>And <code>server.js</code> is a web server</p>
<pre class="prettyprint">var vertx = require('vertx')
vertx.createHttpServer().requestHandler(function(req) {
req.response.sendFile('./web/index.html'); // Always serve the index page
}).listen(8080, 'foo.com')
</pre>
<p>By default the server sees the module directory as '.' so it can access the file <code>web/index.html</code> which is included in the module.</p>
<p>In some cases you <em>don't want</em> the module to see its module directory as its cwd, in which case you can set <code>preserve-cwd</code> to <code>true</code>. The default is <code>false</code>.</p>
<pre class="prettyprint">"preserve-cwd": true
</pre>
<p>This preserves the current working directory of the caller.</p>
<p><a id="auto-redeploy"> </a></p>
<h3 id="auto-redeploy">auto-redeploy</h3><br/>
<p>Modules can be configured to auto-redeploy if Vert.x detects that any of the module resources have changed. This can be really useful during deployment. For more information see the documentation on <a href="dev_guide.html#auto-redeploy">auto redeploy</a>.</p>
<p>To enable auto-redeploy set <code>auto-redeploy</code> to <code>true</code>. Default is <code>false</code>.</p>
<pre class="prettyprint">"auto-redeploy": true
</pre>
<p>If <code>auto-redeploy</code> is set to <code>true</code> for a module which has been deployed by other modules, then Vert.x will reload the top-most module.</p>
<h3 id="resident">resident</h3><br/>
<p>Usually Vert.x will load a module into memory the first time it is referenced and unload it from memory once it is no longer referenced by any modules. This means that if modules are deployed and undeployed rapidly the referenced modules can end up being loaded and unloaded many times.</p>
<p>For most modules this is not an issue, but for some modules, in particular language implementation modules, the libraries (e.g. language engines) used in those modules may generate a lot of classes which live in the Java permanent generation (permgen), and loading and unloading the module frequently can result in the permgen filling up resulting in out of memory exceptions.</p>
<p>To avoid this, we allow modules to be marked as <code>resident</code> which means that Vert.x will load the module the first time it is referenced but will not unload it from memory until the Vert.x instance terminates.</p>
<p>This is an advanced feature and is not intended to be used unless you're writing a language implementation module. Default is <code>false</code>.</p>
<pre class="prettyprint">"resident": true
</pre>
<h3 id="system">system</h3><br/>
<p>When installing modules, unless the <code>VERTX_MODS</code> environment variable is set, Vert.x will install modules in a directory <code>mods</code> local to where <code>vertx</code> is invoked from. Some modules, in particular, language implementation modules tend to be shared by many different projects and it doesn't make sense to download them separately for each project that uses them.</p>
<p>By marking a module as <code>system</code> the module will be installed in the <code>sys-mods</code> directory which is in the Vert.x installation directory (if there is one), and will be shared by all applications.</p>
<p>This is an advanced feature and is not intended to be used in normal module development. Default is <code>false</code>.</p>
<pre class="prettyprint">"system": true
</pre>
<h3 id="deploys">deploys</h3><br/>
<p>Contains a comma separated list of the modules that this module deploys at runtime. It's optional and can be used when <a href="#nested-mods">creating nested modules</a>.</p>
<h3 id="description">description</h3><br/>
<p>Text description of the module. This field is mandatory if you want to register the module in the Vert.x <a href="http://modulereg.vertx.io">module registry</a></p>
<pre class="prettyprint">"description": "This module implements a highly scalable toaster. The toaster....."
</pre>
<h3 id="licenses">licenses</h3><br/>
<p>JSON array of strings containing the names of the license(s) used in the the module. This field is mandatory if you want to register the module in the Vert.x <a href="http://modulereg.vertx.io">module registry</a></p>
<pre class="prettyprint">"licenses": ["The Apache Software License Version 2.0", "Some other license"]
</pre>
<h3 id="author">author</h3><br/>
<p>The primary author of the module. This field is mandatory if you want to register the module in the <a href="">Vert.x module registry</a></p>
<pre class="prettyprint">"author": "Joe Bloggs"
</pre>
<h3 id="keywords">keywords</h3><br/>
<p>JSON array of strings representing keywords that describe the module. This field is highly recommended if you want to register the module in the Vert.x <a href="http://modulereg.vertx.io">module registry</a>, as it is used when searching for modules.</p>
<pre class="prettyprint">"keywords": ["bread", "toasting", "toasters", "nuclear"]
</pre>
<h3 id="developers">developers</h3><br/>
<p>JSON array of strings representing any other developers of the module. This field is optional.</p>
<pre class="prettyprint">"developers": ["A.N. Other", "Genghis Khan"]
</pre>
<h3 id="homepage">homepage</h3><br/>
<p>The homepage of your module project. This field is optional, but highly recommended.</p>
<pre class="prettyprint">"homepage": "https://github.com/jbloggs/toaster-mod"
</pre>
<p>Or</p>
<pre class="prettyprint">"homepage": "http://toastermod.org"
</pre>
<h2 id="module-lib-directory">Module lib directory</h2><br/>
<p>If your module directly uses other <code>jar</code> or <code>zip</code> files these should be placed in a <code>lib</code> directory which is in the root of the module. Any <code>jar</code> or <code>zip</code> files in the lib directory will be added to the module classpath.</p>
<p>If you have a particular <code>jar</code> which is used by several different modules, instead of adding it to the <code>lib</code> directory of each of the modules that uses it you can place it in its own module and <a href="#including">include</a> that module from the using module. This allows your modules to be smaller in size since they don't all contain the <code>jar</code>, and it also means the <code>jar</code> classes are only loaded into memory once, and not once for each module type that uses it.</p>
<h2 id="examples">Examples</h2><br/>
<p>Here's the structure of a simple module that just contains a single JS file:</p>
<pre class="prettyprint">/mod.json
/app.js
</pre>
<p>Where mod.json contains:</p>
<pre class="prettyprint">{
"main": "app.js"
}
</pre>
<p>Here's a simple module that contains java classes</p>
<pre class="prettyprint">/mod.json
/com/mycompany/mymod/App.class
/com/mycompany/mymod/SomeOtherClass.class
</pre>
<p>Where mod.json contains:</p>
<pre class="prettyprint">{
"main": "com.mycompany.mymod.App"
}
</pre>
<p>Another java module which also contains some jars:</p>
<pre class="prettyprint">/mod.json
/com/mycompany/myothermod/App.class
/com/mycompany/myothermod/SomeOtherClass.class
/lib/somelib.jar
/lib/someotherlib.jar
</pre>
<p>And you can put other resources in the module too, e.g.</p>
<pre class="prettyprint">/mod.json
/com/mycompany/myserver/Server.class
/foo.properties
/web/index.html
</pre>
<h1 id="module-classpath">Module classpath</h1><br/>
<p>Each module is given its own class loader by Vert.x. The root of the module and any <code>jar</code> or <code>zip</code> files in the <code>lib</code> directory (if any) comprise the module classpath. This means your code running in a module can reference any classes or other resources on this classpath.</p>
<h1 id="module-classloaders">Module classloaders</h1><br/>
<p>Each module is given its own class loader. For example, all deployed module instances of the module <code>com.mycompany~foo-mod~1.0</code> will share the same class loader, and all deployed module instances of the module <code>com.mycompany~bar-mod~2.1</code> will share another (different) class loader.</p>
<p>This means that different modules are isolated from each other. E.g. you cannot use globals or static members to share data between <code>com.mycompany~foo-mod~1.0</code> and <code>com.mycompany~bar-mod~2.1</code>. However you can use global and statics to share data between two instances of <code>com.mycompany~foo-mod~1.0</code>.</p>
<p>This means you can run multiple versions of the same module or have multiple versions of the same jar running in different modules in the same Vert.x instance at the same time.</p>
<p>Raw verticles that are run from the command line also run in their own class loader.</p>
<p>Any verticles deployed from a module will also have a their own class loader based on the main that is being deployed. For example all instances of <code>foo.js</code> deployed as verticles from inside <code>com.mycompany~foo-mod~1.0</code> will share a class loader, and all instances of (different) <code>foo.js</code> deployed as verticles from inside <code>com.mycompany~bar-mod~2.1</code> will share a different class loader.</p>
<p>Module class loaders are also arranged in a hierarchy. A particular module classloader can have zero or more parent class loaders. When loading classes or other resources a module class loader will first look on its <em>own</em> classpath for those resources, if it cannot find them it will ask each of its parents in turn, and they in turn will ask their parents. Note that this differs from the standard Java class loading protocol which usually asks its parents <em>first</em> before looking for resources itself.</p>
<p>If classes or resources cannot be found by any of the module class loaders in the hierarchy the platform class loader (i.e. the class loader that loaded the Vert.x platform itself) will be asked.</p>
<p>A raw verticle that is run directly on the command line will not have any parent module class loaders. A verticle that is deployed from inside a module will have the module class loader set as a parent of the class loader used to deploy the verticle.</p>
<p>If a module <a href="#includes">includes</a> any other modules than each of the modules that it includes will be set as a parent class loader of the module class loader. Doing this allows us to load the classes for any included module only once.</p>
<p><a id="including"> </a></p>
<h1 id="including-the-resources-of-modules">Including the resources of modules</h1><br/>
<p>Sometimes you might find that different modules are using the same or similar sets of resources, e.g. <code>.jar</code> files or scripts, or other resources.</p>
<p>Instead of copying the same resources into every module that needs them, you can put those resources in a module of their own, and then declare that other modules <code>includes</code> them.</p>
<p>Doing this adds the class loader of the included module as a parent to the class loader of the including module, in effect meaning you can reference the resources in the included module s if they were present in the including module.</p>
<p>This is done by specifying an <code>includes</code> field in the module descriptor.</p>
<p>Let's take an example. We have a jar <code>foo.jar</code> and a script <code>bar.js</code> which we want to be used by both <code>com.acme.module1-v1.0</code> and <code>com.acme.module2-v1.0</code>.</p>
<p>We create a module that contains <code>bar.js</code> and <code>foo.jar</code> (in the <code>lib</code> directory). Let's call that module <code>com.acme.common-stuff-v1.0</code>.</p>
<p>Then in the <code>mod.json</code> of <code>com.acme.module1-v1.0</code> and <code>com.acme.module2-v1.0</code> we add an <code>includes</code>, e.g.:</p>
<pre class="prettyprint">{
...
"includes":"com.acme.common-stuff-v1.0"
}
</pre>
<p>A module can include many other modules - <code>includes</code> is a comma-separated list of module names.</p>
<p>If a jar is include more than once from different modules, a warning will be issued. </p>
<p>Modules that <em>only</em> contain resources for re-use are called <em>non-runnable</em> modules and they don't require a <code>main</code> field in <code>mod.json</code>. It's also possible to include the resources of runnable modules into another module.</p>
<h1 id="running-a-module-from-the-command-line">Running a module from the command line</h1><br/>
<p>Modules can be run directly by using the command <code>vertx runmod</code>. Please see the <a href="manual.html#running-mods">main manual</a> for a full description of this.</p>
<p>E.g.</p>
<pre class="prettyprint">vertx runmod org.myorg~mymod~3.2
</pre>
<p>You can also run a module given just the module <code>zip</code> file. E.g.</p>
<pre class="prettyprint">vertx runzip my-mod-3.2.zip
</pre>
<p>The name of the module zip file must be <module_name>-<version>.zip</p>
<h1 id="running-a-module-programmatically">Running a module programmatically</h1><br/>
<p>You can also run a module programmatically similarly to how you run any verticle programmatically. Please see the core manual for the appropriate language for a full description on how to do this.</p>
<p>E.g. (JavaScript)</p>
<pre class="prettyprint">vertx.deployModule('org.myorg~mymod~3.2');
</pre>
<h1 id="how-vertx-locates-modules">How Vert.x locates modules</h1><br/>
<p>When you attempt to deploy or <a href="#includes">include</a> a module, Vert.x will first look to see if the module is already installed.</p>
<p>Vert.x looks in the following places:</p>
<ol>
<li>If the module is being deployed from another module it will look for a nested <code>mods</code> directory inside the current module. See the section on <a href="#nested-mods">nested modules</a>.</li>
<li>In the local <code>mods</code> directory on the filesystem, or in the directory specified by the <code>VERTX_MODS</code> environment variable, if set.</li>
<li>In the <code>sys-mods</code> directory of the Vert.x installation. </li>
</ol>
<p>If the module is not there then Vert.x will look in various repositories to locate the module. In the out of the box Vert.x configuration, Vert.x will look in Maven Central, Sonatype Nexus Snapshots, Bintray and your local Maven repository (if any).</p>
<p>The repositories it looks in are configured in the file <code>repos.txt</code> in the Vert.x installation <code>conf</code> directory. Here is the default <code>repos.txt</code>:</p>
<pre class="prettyprint"># Local Maven repo on filesystem
mavenLocal:~/.m2/repository
# Maven central
maven:http://repo2.maven.org/maven2
# Sonatype snapshots
maven:http://oss.sonatype.org/content/repositories/snapshots
# Bintray
bintray:http://dl.bintray.com
</pre>
<p>Vert.x can understand any Maven or Bintray repository, so if you want to configure your own repository simply add it to the file. For example, you might have your own company internal Nexus repository that you want to use.</p>
<p>Vert.x queries the repositories in the order they appear in the file, and will stop searching as soon as it finds the module in one of the repositories.</p>
<h2 id="mapping-a-module-identifier-to-maven-co-ordinates">Mapping a Module Identifier to Maven co-ordinates</h2><br/>
<p>When looking for a module in a Maven repository, Vert.x maps the module identifier to Maven co-ordinates as follows:</p>
<pre class="prettyprint">GroupID = Owner
ArtifactID = Name
Version = Version
</pre>
<p>E.g. for the module identifier <code>com.mycompany~my-mod~1.2-beta</code> the Maven co-ordinates would be </p>
<pre class="prettyprint">GroupID: com.mycompany
ArtifactID: my-mod
Version: 1.2-beta
</pre>
<p>The artifact type is always assumed to be a <code>zip</code> and to have a Maven classifier of <code>mod</code>.</p>
<h2 id="mapping-a-module-identifier-to-bintray-co-ordinates">Mapping a Module Identifier to Bintray co-ordinates</h2><br/>
<p>When looking in a Bintray repository, Vert.x maps the module identifier to Bintray co-ordinates as follows:</p>
<pre class="prettyprint">Bintray user name = Owner
Repository = vertx-mods
File path = Name
File name = Name-Version.zip
</pre>
<p>For example, the module <code>purplefox~foo-mod~2.2</code> in Bintray would map to:</p>
<pre class="prettyprint">Bintray username: purplefox
Repository: vertx-mods
File path = foo-mod
File name = foo-mod-2.2.zip
</pre>
<p>This gives a download url for the module:</p>
<pre class="prettyprint">http://dl.bintray.com/purplefox/vertx-mods/foo-mod/foo-mod-2.2.zip
</pre>
<h1 id="creating-fat-executable-jars">Creating fat executable jars</h1><br/>
<p>Vert.x also supports assembling 'fat jars'. These are executable jars which contain the Vert.x binaries along with your module so the module can be run by just executing the jar</p>
<pre class="prettyprint">java -jar mymodule-1.0-fat.jar
</pre>
<p>You can also provide the usual command line arguments that you would pass to <code>vertx runmod</code> when executing the jar, e.g.</p>
<pre class="prettyprint">java -jar mymodule-1.0-fat.jar -cluster -conf myconf.json
</pre>
<p>This means you don't have to have Vert.x pre-installed on the machine on which you execute the jar.</p>
<p>To create a fat jar you can run</p>
<pre class="prettyprint">vertx fatjar <module_name>
</pre>
<p>You can also provide an optional output directory name where to put the jar, e.g.</p>
<pre class="prettyprint">vertx fatjar <module_name> <output_directory>
</pre>
<p>Or you can use the Gradle task in the standard Gradle build or the Maven plugin to build them.</p>
<p><a id="nested-mods"> </a></p>
<h1 id="nested-modules-packaging-all-module-dependencies-in-the-module">Nested modules - Packaging all module dependencies in the module</h1><br/>
<p>The usual behaviour of Vert.x is to download and install module dependencies the first time they are referenced at runtime, if they're not already installed. For some production deployments this is not necessarily desirable - there may be a requirement that modules deployed on a production server must contain everything necessary to run then without calling out to download more artifacts at runtime.</p>
<p>For these situations Vert.x supports packaging a module, along with all the other modules that it references inside the same module to give a single self contained deployment unit.</p>
<p>For example, let's say you've created the module <code>com.mycompany~mod-toaster~1.0</code> and that module uses the following other modules <code>io.vertx~mod-mongo-persistor~2.0.0-beta1</code> and <code>org.foo~mod-nuclear~2.2</code>. Normally those modules would be downloaded and installed in the local <code>mods</code> directory on the file system the first time the module is run.</p>
<p>By adding the modules to the <code>deploys</code> field in the <code>mod.json</code> of our module we are telling Vert.x what the runtime module dependencies of the module are (these are not necessarily the same as the <em>build time</em> dependencies of the module!).</p>
<p>You can then run the following command against the installed module to tell Vert.x to pull in the dependencies mentioned in the <code>deploys</code> field and add them in a <em>nested</em> <code>mods</code> directory <em>inside</em> the module:</p>
<pre class="prettyprint">vertx pulldeps <module_name>
</pre>
<p>Before calling <code>vertx pulldeps</code> your module might have the structure on disk:</p>
<pre class="prettyprint">./mods/io.vertx~mod-mongo-persistor~2.0.0-beta1/mod.json
./mods/io.vertx~mod-mongo-persistor~2.0.0-beta1/app.js
</pre>
<p>After calling <code>vertx pulldeps</code> it would have the following structure</p>
<pre class="prettyprint">./mods/io.vertx~mod-mongo-persistor~2.0.0-beta1/mod.json
./mods/io.vertx~mod-mongo-persistor~2.0.0-beta1/app.js
./mods/io.vertx~mod-mongo-persistor~2.0.0-beta1/mods/io.vertx~mod-mongo-persistor~2.0.0-beta1/mod.json
./mods/io.vertx~mod-mongo-persistor~2.0.0-beta1/mods/io.vertx~mod-mongo-persistor~2.0.0-beta1/[...rest of the stuff in that module]
./mods/io.vertx~mod-mongo-persistor~2.0.0-beta1/mods/org.foo~mod-nuclear~2.2/mod.json
./mods/io.vertx~mod-mongo-persistor~2.0.0-beta1/mods/org.foo~mod-nuclear~2.2/[...rest of the stuff in that module]
</pre>
<p>The module directory <code>./mods/io.vertx~mod-mongo-persistor~2.0.0-beta1</code> can then be zipped and deployed as a self contained module and it won't have to download any dependencies at runtime since they will all be found <em>inside</em> the module already.</p>
<p><em>If you're using the standard Gradle template project or used the Vert.x Maven Archetype to create your project then this all happens automatically for you if you enable it in the <code>pom.xml</code> or <code>gradle.properties</code> file.</em></p>
<h2 id="installing-modules-manually-from-the-repository">Installing modules manually from the repository</h2><br/>
<p>In some cases, you do not want to wait until a module is first referenced by the application before it is installed, you want to install it <em>ahead of time</em>. This can be done using the command <code>vertx install</code></p>
<p>To install a module manually from a repository use <code>vertx install <module name></code>. For example:</p>
<pre class="prettyprint">vertx install io.vertx~mod-mongo-persistor~2.0.0-beta1
</pre>
<h1 id="uninstalling-modules">Uninstalling modules</h1><br/>
<p>To uninstall a module from your local <code>mods</code> directory (or <code>VERTX_MODS</code>) use the <code>vertx uninstall <module name></code> command. E.g.</p>
<pre class="prettyprint">vertx uninstall io.vertx~mod-mongo-persistor~2.0.0-beta1
</pre>
<h1 id="how-to-publish-modules-to-remote-repositories">How to publish modules to remote repositories</h1><br/>
<p>If you want to make your modules public (and this is highly recommended) you can publish them to any Maven or Bintray repository. Vert.x has been designed to work well with the repositories already used by most JVM developers (in most cases this is Maven) and we do now want to impose yet another repository format on users.</p>
<h2 id="publishing-to-maven-repositories">Publishing to Maven repositories</h2><br/>
<p>Many JVM developers will already be familiar with working with Nexus repositories and Maven Central. Vert.x modules can be effortlessly published there when using the <a href="gradle_dev.html">Gradle template project</a> or a project created by the Vert.x <a href="maven_dev.html">Maven Archetype</a>.</p>
<p>For Maven projects this is accomplished by executing <code>mvn deploy</code> as is normal for any Maven project.</p>
<p>For Gradle projects you just run <code>./gradlew uploadArchives</code> as normal for any Gradle project.</p>
<p>If you're not using Maven or Gradle you can can manually upload your module using the Nexus user interface.</p>
<p>If you're going to use Sonatype Nexus you will need to obtain an account with them.</p>
<h2 id="publishing-to-bintray">Publishing to Bintray</h2><br/>
<p><a href="http://bintray.com">Bintray</a> is a new binary repository site which is arguably is easier to get started with if you're not already used to dealing with publishing artifacts to Maven repositories. You simply need to register for an account on their website then you can immediately start uploading binaries either through their web UI or using command line tools.</p>
<h1 id="telling-the-world-about-your-module-introducing-the-vertx-module-registry">Telling the world about your module - Introducing the Vert.x Module Registry</h1><br/>
<p>So you've pushed your module to Maven Central, Bintray or perhaps some other public Maven repository. That's sufficient for any Vert.x user to use it, but how are you going to tell the Vert.x community about it?</p>
<p>Enter the <a href="http://modulereg.vertx.io">module registry</a>. The Vert.x module registry is a web application that keeps a directory of publicly available Vert.x modules. It allows you to list and search for modules that have been published by other Vert.x users and that might be of interest to you in your applications.</p>
<p>We want to encourage an ecosystem of modules for Vert.x, and the module registry is a key part of that.</p>
<p>The module registry doesn't actually store the modules itself, you store your module in any Maven or Bintray repository, it simply stores meta-data for the module so people can find it.</p>
<p>Once a user has found a module they like, you simply take note of the module identifier and use that in your application. Based on the module identifier Vert.x will download and install the module at build or run-time (depending on how your build is configured).</p>
<p>Anyone can register a module with the module registry by filling out a very simple form. Once a registration request has been submitted an email will be sent to a moderator who will approve the submission if all is ok.</p>
<p>Any modules that are to be registered in the module registry must have the following fields in <code>mod.json</code>:</p>
<ul>
<li><code>description</code></li>
<li><code>licenses</code></li>
<li><code>author</code></li>
</ul>
<p>It's also <em>highly recommended</em> that the following fields are added too:</p>
<ul>
<li><code>keywords</code> - useful when searching</li>
<li><code>homepage</code> - url to the project homepage.</li>
</ul>
<p><em>Piece of Trivia: The Vert.x module registry is itself a Vert.x module, and you can find it... it in the Vert.x module registry!</em></p>
<h1 id="module-configuration">Module configuration</h1><br/>
<p>Configuration for a module (if any) should be specified using a JSON configuration file when deploying from the command line using <code>vertx runmod</code> or passed in when deploying a module programmatically.</p>
<p>Applying configuration this way allows it to be easily and consistently configured irrespective of the language.</p></div>
</div>
</div>
</div>
</div>
</body>
</html>