Rework odl-parent developer guide
[docs.git] / docs / developer-guides / odl-parent-developer-guide.rst
1 .. _odl-parent-developer-guide:
2
3 ODL Parent Developer Guide
4 ==========================
5
6 Parent POMs
7 -----------
8
9 Overview
10 ~~~~~~~~
11
12 The ODL Parent component for OpenDaylight provides a number of Maven
13 parent POMs which allow Maven projects to be easily integrated in the
14 OpenDaylight ecosystem. Technically, the aim of projects in OpenDaylight
15 is to produce Karaf features, and these parent projects provide common
16 support for the different types of projects involved.
17
18 These parent projects are:
19
20 -  ``odlparent-lite`` — the basic parent POM for Maven modules which
21    don’t produce artifacts (*e.g.* aggregator POMs)
22
23 -  ``odlparent`` — the common parent POM for Maven modules containing
24    Java code
25
26 -  ``bundle-parent`` — the parent POM for Maven modules producing OSGi
27    bundles
28
29 The following parent projects are deprecated, but still used in Carbon:
30
31 -  ``feature-parent`` — the parent POM for Maven modules producing
32    Karaf 3 feature repositories
33
34 -  ``karaf-parent`` — the parent POM for Maven modules producing Karaf 3
35    distributions
36
37 The following parent projects are new in Carbon, for Karaf 4 support (which
38 won’t be complete until Nitrogen):
39
40 -  ``single-feature-parent`` — the parent POM for Maven modules producing
41    a single Karaf 4 feature
42
43 -  ``feature-repo-parent`` — the parent POM for Maven modules producing
44    Karaf 4 feature repositories
45
46 -  ``karaf4-parent`` — the parent POM for Maven modules producing Karaf 4
47    distributions
48
49 odlparent-lite
50 ~~~~~~~~~~~~~~
51
52 This is the base parent for all OpenDaylight Maven projects and
53 modules. It provides the following, notably to allow publishing
54 artifacts to Maven Central:
55
56 -  license information;
57
58 -  organization information;
59
60 -  issue management information (a link to our Bugzilla);
61
62 -  continuous integration information (a link to our Jenkins setup);
63
64 -  default Maven plugins (``maven-clean-plugin``,
65    ``maven-deploy-plugin``, ``maven-install-plugin``,
66    ``maven-javadoc-plugin`` with HelpMojo support,
67    ``maven-project-info-reports-plugin``, ``maven-site-plugin`` with
68    Asciidoc support, ``jdepend-maven-plugin``);
69
70 -  distribution management information.
71
72 It also defines two profiles which help during development:
73
74 -  ``q`` (``-Pq``), the quick profile, which disables tests, code
75    coverage, Javadoc generation, code analysis, etc. — anything which
76    is not necessary to build the bundles and features (see `this blog
77    post <http://blog2.vorburger.ch/2016/06/improve-maven-build-speed-with-q.html>`__
78    for details);
79
80 -  ``addInstallRepositoryPath``
81    (``-DaddInstallRepositoryPath=…/karaf/system``) which can be used to
82    drop a bundle in the appropriate Karaf location, to enable
83    hot-reloading of bundles during development (see `this blog
84    post <http://blog2.vorburger.ch/2016/06/maven-install-into-additional.html>`__
85    for details).
86
87 For modules which don’t produce any useful artifacts (*e.g.* aggregator
88 POMs), you should add the following to avoid processing artifacts:
89
90 ::
91
92     <build>
93         <plugins>
94             <plugin>
95                 <groupId>org.apache.maven.plugins</groupId>
96                 <artifactId>maven-deploy-plugin</artifactId>
97                 <configuration>
98                     <skip>true</skip>
99                 </configuration>
100             </plugin>
101             <plugin>
102                 <groupId>org.apache.maven.plugins</groupId>
103                 <artifactId>maven-install-plugin</artifactId>
104                 <configuration>
105                     <skip>true</skip>
106                 </configuration>
107             </plugin>
108         </plugins>
109     </build>
110
111 odlparent
112 ~~~~~~~~~
113
114 This inherits from ``odlparent-lite`` and mainly provides dependency and
115 plugin management for OpenDaylight projects.
116
117 If you use any of the following libraries, you should rely on
118 ``odlparent`` to provide the appropriate versions:
119
120 -  Akka (and Scala)
121
122 -  Apache Commons:
123
124    -  ``commons-codec``
125
126    -  ``commons-fileupload``
127
128    -  ``commons-io``
129
130    -  ``commons-lang``
131
132    -  ``commons-lang3``
133
134    -  ``commons-net``
135
136 -  Apache Shiro
137
138 -  Guava
139
140 -  JAX-RS with Jersey
141
142 -  JSON processing:
143
144    -  GSON
145
146    -  Jackson
147
148 -  Logging:
149
150    -  Logback
151
152    -  SLF4J
153
154 -  Netty
155
156 -  OSGi:
157
158    -  Apache Felix
159
160    -  core OSGi dependencies (``core``, ``compendium``\ …)
161
162 -  Testing:
163
164    -  Hamcrest
165
166    -  JSON assert
167
168    -  JUnit
169
170    -  Mockito
171
172    -  Pax Exam
173
174    -  PowerMock
175
176 -  XML/XSL:
177
178    -  Xerces
179
180    -  XML APIs
181
182 .. note::
183
184     This list is not exhaustive. It is also not cast in stone;if you
185     would like to add a new dependency (or migrate a dependency), please
186     contact `the mailing list <https://lists.opendaylight.org/g/kernel-dev>`__.
187
188 ``odlparent`` also enforces some Checkstyle verification rules. In
189 particular, it enforces the common license header used in all
190 OpenDaylight code:
191
192 ::
193
194     /*
195      * Copyright © ${year} ${holder} and others.  All rights reserved.
196      *
197      * This program and the accompanying materials are made available under the
198      * terms of the Eclipse Public License v1.0 which accompanies this distribution,
199      * and is available at http://www.eclipse.org/legal/epl-v10.html
200      */
201
202 where “\ ``${year}``\ ” is initially the first year of publication, then
203 (after a year has passed) the first and latest years of publication,
204 separated by commas (*e.g.* “2014, 2016”), and “\ ``${holder}``\ ” is
205 the initial copyright holder (typically, the first author’s employer).
206 “All rights reserved” is optional.
207
208 If you need to disable this license check, *e.g.* for files imported
209 under another license (EPL-compatible of course), you can override the
210 ``maven-checkstyle-plugin`` configuration. ``features-test`` does this
211 for its ``CustomBundleUrlStreamHandlerFactory`` class, which is
212 ASL-licensed:
213
214 ::
215
216     <plugin>
217         <artifactId>maven-checkstyle-plugin</artifactId>
218         <executions>
219             <execution>
220                 <id>check-license</id>
221                 <goals>
222                     <goal>check</goal>
223                 </goals>
224                 <phase>process-sources</phase>
225                 <configuration>
226                     <configLocation>check-license.xml</configLocation>
227                     <headerLocation>EPL-LICENSE.regexp.txt</headerLocation>
228                     <includeResources>false</includeResources>
229                     <includeTestResources>false</includeTestResources>
230                     <sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
231                     <excludes>
232                         <!-- Skip Apache Licensed files -->
233                         org/opendaylight/odlparent/featuretest/CustomBundleUrlStreamHandlerFactory.java
234                     </excludes>
235                     <failsOnError>false</failsOnError>
236                     <consoleOutput>true</consoleOutput>
237                 </configuration>
238             </execution>
239         </executions>
240     </plugin>
241
242 bundle-parent
243 ~~~~~~~~~~~~~
244
245 This inherits from ``odlparent`` and enables functionality useful for
246 OSGi bundles:
247
248 -  ``maven-javadoc-plugin`` is activated, to build the Javadoc JAR;
249
250 -  ``maven-source-plugin`` is activated, to build the source JAR;
251
252 -  ``maven-bundle-plugin`` is activated (including extensions), to build
253    OSGi bundles (using the “bundle” packaging).
254
255 In addition to this, JUnit is included as a default dependency in “test”
256 scope.
257
258 features-parent
259 ~~~~~~~~~~~~~~~
260
261 This inherits from ``odlparent`` and enables functionality useful for
262 Karaf features:
263
264 -  ``karaf-maven-plugin`` is activated, to build Karaf features — but
265    for OpenDaylight, projects need to use ``“jar”`` packaging (**not**
266    ``“feature”`` or ``“kar”``);
267
268 -  ``features.xml`` files are processed from templates stored in
269    ``src/main/features/features.xml``;
270
271 -  Karaf features are tested after build to ensure they can be activated
272    in a Karaf container.
273
274 The ``features.xml`` processing allows versions to be omitted from
275 certain feature dependencies, and replaced with “\ ``{{version}}``\ ”.
276 For example:
277
278 ::
279
280     <features name="odl-mdsal-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
281        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
282        xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
283
284         <repository>mvn:org.opendaylight.odlparent/features-odlparent/{{VERSION}}/xml/features</repository>
285
286         [...]
287         <feature name='odl-mdsal-broker-local' version='${project.version}' description="OpenDaylight :: MDSAL :: Broker">
288             <feature version='${yangtools.version}'>odl-yangtools-common</feature>
289             <feature version='${mdsal.version}'>odl-mdsal-binding-dom-adapter</feature>
290             <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
291             <feature version='${project.version}'>odl-mdsal-common</feature>
292             <feature version='${config.version}'>odl-config-startup</feature>
293             <feature version='${config.version}'>odl-config-netty</feature>
294             <feature version='[3.3.0,4.0.0)'>odl-lmax</feature>
295             [...]
296             <bundle>mvn:org.opendaylight.controller/sal-dom-broker-config/{{VERSION}}</bundle>
297             <bundle start-level="40">mvn:org.opendaylight.controller/blueprint/{{VERSION}}</bundle>
298             <configfile finalname="${config.configfile.directory}/${config.mdsal.configfile}">mvn:org.opendaylight.controller/md-sal-config/{{VERSION}}/xml/config</configfile>
299         </feature>
300
301 As illustrated, versions can be omitted in this way for repository
302 dependencies, bundle dependencies and configuration files. They must be
303 specified traditionally (either hard-coded, or using Maven properties)
304 for feature dependencies.
305
306 karaf-parent
307 ~~~~~~~~~~~~
308
309 This allows building a Karaf 3 distribution, typically for local testing
310 purposes. Any runtime-scoped feature dependencies will be included in the
311 distribution, and the ``karaf.localFeature`` property can be used to
312 specify the boot feature (in addition to ``standard``).
313
314 single-feature-parent
315 ~~~~~~~~~~~~~~~~~~~~~
316
317 This inherits from ``odlparent`` and enables functionality useful for
318 Karaf 4 features:
319
320 -  ``karaf-maven-plugin`` is activated, to build Karaf features, typically
321    with ``"feature"`` packaging (``"kar"`` is also supported);
322
323 -  ``feature.xml`` files are generated based on the compile-scope dependencies
324    defined in the POM, optionally initialized from a stub in
325    ``src/main/feature/feature.xml``.
326
327 -  Karaf features are tested after build to ensure they can be activated
328    in a Karaf container.
329
330 The ``feature.xml`` processing adds transitive dependencies by default, which
331 allows features to be defined using only the most significant dependencies
332 (those that define the feature); other requirements are determined
333 automatically as long as they exist as Maven dependencies.
334
335 ``configfiles`` need to be defined both as Maven dependencies (with the
336 appropriate type and classifier) and as ``<configfile>`` elements in the
337 ``feature.xml`` stub.
338
339 Other features which a feature depends on need to be defined as Maven
340 dependencies with type “xml” and classifier “features” (note the plural here).
341
342 ``feature-repo-parent``
343 ~~~~~~~~~~~~~~~~~~~~~~~
344
345 This inherits from ``odlparent`` and enables functionality useful for
346 Karaf 4 feature repositories. It follows the same principles as
347 ``single-feature-parent``, but is designed specifically for repositories
348 and should be used only for this type of artifacts.
349
350 It builds a feature repository referencing all the (feature) dependencies
351 listed in the POM.
352
353 karaf4-parent
354 ~~~~~~~~~~~~~
355
356 This allows building a Karaf 4 distribution, typically for local testing
357 purposes. Any runtime-scoped feature dependencies will be included in the
358 distribution, and the ``karaf.localFeature`` property can be used to
359 specify the boot feature (in addition to ``standard``).
360
361 Features (for Karaf 3)
362 ----------------------
363
364 The ODL Parent component for OpenDaylight provides a number of Karaf 3
365 features which can be used by other Karaf 3 features to use certain
366 third-party upstream dependencies.
367
368 These features are:
369
370 -  Akka features (in the ``features-akka`` repository):
371
372    -  ``odl-akka-all`` — all Akka bundles;
373
374    -  ``odl-akka-scala-2.11`` — Scala runtime for OpenDaylight;
375
376    -  ``odl-akka-system-2.4`` — Akka actor framework bundles;
377
378    -  ``odl-akka-clustering-2.4`` — Akka clustering bundles and
379       dependencies;
380
381    -  ``odl-akka-leveldb-0.7`` — LevelDB;
382
383    -  ``odl-akka-persistence-2.4`` — Akka persistence;
384
385 -  general third-party features (in the ``features-odlparent``
386    repository):
387
388    -  ``odl-netty-4`` — all Netty bundles;
389
390    -  ``odl-guava-18`` — Guava 18;
391
392    -  ``odl-guava-21`` — Guava 21 (not intended for use in Carbon);
393
394    -  ``odl-lmax-3`` — LMAX Disruptor;
395
396    -  ``odl-triemap-0.2`` — Concurrent Hash-Trie Map.
397
398 To use these, you need to declare a dependency on the appropriate
399 repository in your ``features.xml`` file:
400
401 ::
402
403     <repository>mvn:org.opendaylight.odlparent/features-odlparent/{{VERSION}}/xml/features</repository>
404
405 and then include the feature, *e.g.*:
406
407 ::
408
409     <feature name='odl-mdsal-broker-local' version='${project.version}' description="OpenDaylight :: MDSAL :: Broker">
410         [...]
411         <feature version='[3.3.0,4.0.0)'>odl-lmax</feature>
412         [...]
413     </feature>
414
415 You also need to depend on the features repository in your POM:
416
417 ::
418
419     <dependency>
420         <groupId>org.opendaylight.odlparent</groupId>
421         <artifactId>features-odlparent</artifactId>
422         <classifier>features</classifier>
423         <type>xml</type>
424     </dependency>
425
426 assuming the appropriate dependency management:
427
428 ::
429
430     <dependencyManagement>
431         <dependencies>
432             <dependency>
433                 <groupId>org.opendaylight.odlparent</groupId>
434                 <artifactId>odlparent-artifacts</artifactId>
435                 <version>1.8.0-SNAPSHOT</version>
436                 <scope>import</scope>
437                 <type>pom</type>
438             </dependency>
439         </dependencies>
440     </dependencyManagement>
441
442 (the version number there is appropriate for Carbon). For the time being
443 you also need to depend separately on the individual JARs as
444 compile-time dependencies to build your dependent code; the relevant
445 dependencies are managed in ``odlparent``'s dependency management.
446
447 | The suggested version ranges are as follows:
448
449 -  ``odl-netty``: ``[4.0.37,4.1.0)`` or ``[4.0.37,5.0.0)``;
450
451 -  ``odl-guava``: ``[18,19)`` (if your code is ready for it, ``[19,20)``
452    is also available, but the current default version of Guava in
453    OpenDaylight is 18);
454
455 -  ``odl-lmax``: ``[3.3.4,4.0.0)``
456
457 Features (for Karaf 4)
458 ----------------------
459
460 There are equivalent features to all the Karaf 3 features, for Karaf 4.
461 The repositories use “features4” instead of “features”, and the features
462 use ``odl4`` instead of ``odl``.
463
464 The following new features are specific to Karaf 4:
465
466 -  Karaf wrapper features (also in the ``features4-odlparent``
467    repository) — these can be used to pull in a Karaf feature
468    using a Maven dependency in a POM:
469
470    -  ``odl-karaf-feat-feature`` — the Karaf ``feature`` feature;
471
472    -  ``odl-karaf-feat-jdbc`` — the Karaf ``jdbc`` feature;
473
474    -  ``odl-karaf-feat-jetty`` — the Karaf ``jetty`` feature;
475
476    -  ``odl-karaf-feat-war`` — the Karaf ``war`` feature.
477
478 To use these, all you need to do now is add the appropriate dependency
479 in your feature POM; for example:
480
481 ::
482
483     <dependency>
484         <groupId>org.opendaylight.odlparent</groupId>
485         <artifactId>odl4-guava-18</artifactId>
486         <classifier>features</classifier>
487         <type>xml</type>
488     </dependency>
489
490 assuming the appropriate dependency management:
491
492 ::
493
494     <dependencyManagement>
495         <dependencies>
496             <dependency>
497                 <groupId>org.opendaylight.odlparent</groupId>
498                 <artifactId>odlparent-artifacts</artifactId>
499                 <version>1.8.0-SNAPSHOT</version>
500                 <scope>import</scope>
501                 <type>pom</type>
502             </dependency>
503         </dependencies>
504     </dependencyManagement>
505
506 (the version number there is appropriate for Carbon). We no longer use version
507 ranges, the feature dependencies all use the ``odlparent`` version (but you
508 should rely on the artifacts POM).