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