1 .. _odl-parent-developer-guide:
3 Developing with ODL Parent
4 ==========================
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.
18 These parent projects are:
20 - ``odlparent-lite`` — the basic parent POM for Maven modules which
21 don’t produce artifacts (*e.g.* aggregator POMs)
23 - ``odlparent`` — the common parent POM for Maven modules containing
26 - ``bundle-parent`` — the parent POM for Maven modules producing OSGi
29 - ``single-feature-parent`` — the parent POM for Maven modules producing
30 a single Karaf 4 feature
32 - ``feature-repo-parent`` — the parent POM for Maven modules producing
33 Karaf 4 feature repositories
35 - ``karaf4-parent`` — the parent POM for Maven modules producing Karaf 4
38 - ``karaf-dist-static`` - the parent POM for Maven modules producing Karaf 4
44 This is the base parent for all OpenDaylight Maven projects and
45 modules. It provides the following, notably to allow publishing
46 artifacts to Maven Central:
48 - license information;
50 - organization information;
52 - issue management information (a link to our Bugzilla);
54 - continuous integration information (a link to our Jenkins setup);
56 - default Maven plugins (``maven-clean-plugin``,
57 ``maven-deploy-plugin``, ``maven-install-plugin``,
58 ``maven-javadoc-plugin`` with HelpMojo support,
59 ``maven-project-info-reports-plugin``, ``maven-site-plugin`` with
60 Asciidoc support, ``jdepend-maven-plugin``);
62 - distribution management information.
64 It also defines two profiles which help during development:
66 - ``q`` (``-Pq``), the quick profile, which disables tests, code
67 coverage, Javadoc generation, code analysis, etc. — anything which
68 isn’t necessary to build the bundles and features (see `this blog
69 post <http://blog2.vorburger.ch/2016/06/improve-maven-build-speed-with-q.html>`__
72 - ``addInstallRepositoryPath``
73 (``-DaddInstallRepositoryPath=…/karaf/system``) which can be used to
74 drop a bundle in the appropriate Karaf location, to enable
75 hot-reloading of bundles during development (see `this blog
76 post <http://blog2.vorburger.ch/2016/06/maven-install-into-additional.html>`__
79 For modules which don’t produce any useful artifacts (*e.g.* aggregator
80 POMs), you should add the following to avoid processing artifacts:
87 <groupId>org.apache.maven.plugins</groupId>
88 <artifactId>maven-deploy-plugin</artifactId>
94 <groupId>org.apache.maven.plugins</groupId>
95 <artifactId>maven-install-plugin</artifactId>
106 This inherits from ``odlparent-lite`` and mainly provides dependency and
107 plugin management for OpenDaylight projects.
109 If you use any of the following libraries, you should rely on
110 ``odlparent`` to provide the appropriate versions:
118 - ``commons-fileupload``
152 - core OSGi dependencies (``core``, ``compendium``\ …)
176 This list isn’t exhaustive. It’s also not cast in stone; if you’d
177 like to add a new dependency (or migrate a dependency), please
179 list <https://lists.opendaylight.org/mailman/listinfo/odlparent-dev>`__.
181 ``odlparent`` also enforces some Checkstyle verification rules. In
182 particular, it enforces the common license header used in all
188 * Copyright © ${year} ${holder} and others. All rights reserved.
190 * This program and the accompanying materials are made available under the
191 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
192 * and is available at http://www.eclipse.org/legal/epl-v10.html
195 where “\ ``${year}``\ ” is initially the first year of publication, then
196 (after a year has passed) the first and latest years of publication,
197 separated by commas (*e.g.* “2014, 2016”), and “\ ``${holder}``\ ” is
198 the initial copyright holder (typically, the first author’s employer).
199 “All rights reserved” is optional.
201 If you need to disable this license check, *e.g.* for files imported
202 under another license (EPL-compatible of course), you can override the
203 ``maven-checkstyle-plugin`` configuration. ``features-test`` does this
204 for its ``CustomBundleUrlStreamHandlerFactory`` class, which is
210 <artifactId>maven-checkstyle-plugin</artifactId>
213 <id>check-license</id>
217 <phase>process-sources</phase>
219 <configLocation>check-license.xml</configLocation>
220 <headerLocation>EPL-LICENSE.regexp.txt</headerLocation>
221 <includeResources>false</includeResources>
222 <includeTestResources>false</includeTestResources>
223 <sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
225 <!-- Skip Apache Licensed files -->
226 org/opendaylight/odlparent/featuretest/CustomBundleUrlStreamHandlerFactory.java
228 <failsOnError>false</failsOnError>
229 <consoleOutput>true</consoleOutput>
238 This inherits from ``odlparent`` and enables functionality useful for
241 - ``maven-javadoc-plugin`` is activated, to build the Javadoc JAR;
243 - ``maven-source-plugin`` is activated, to build the source JAR;
245 - ``maven-bundle-plugin`` is activated (including extensions), to build
246 OSGi bundles (using the “bundle” packaging).
248 In addition to this, JUnit is included as a default dependency in “test”
254 This inherits from ``odlparent`` and enables functionality useful for
257 - ``karaf-maven-plugin`` is activated, to build Karaf features — but
258 for OpenDaylight, projects need to use “jar” packaging (**not**
261 - ``features.xml`` files are processed from templates stored in
262 ``src/main/features/features.xml``;
264 - Karaf features are tested after build to ensure they can be activated
265 in a Karaf container.
267 The ``features.xml`` processing allows versions to be ommitted from
268 certain feature dependencies, and replaced with “\ ``{{version}}``\ ”.
273 <features name="odl-mdsal-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
274 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
275 xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
277 <repository>mvn:org.opendaylight.odlparent/features-odlparent/{{VERSION}}/xml/features</repository>
280 <feature name='odl-mdsal-broker-local' version='${project.version}' description="OpenDaylight :: MDSAL :: Broker">
281 <feature version='${yangtools.version}'>odl-yangtools-common</feature>
282 <feature version='${mdsal.version}'>odl-mdsal-binding-dom-adapter</feature>
283 <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
284 <feature version='${project.version}'>odl-mdsal-common</feature>
285 <feature version='${config.version}'>odl-config-startup</feature>
286 <feature version='${config.version}'>odl-config-netty</feature>
287 <feature version='[3.3.0,4.0.0)'>odl-lmax</feature>
289 <bundle>mvn:org.opendaylight.controller/sal-dom-broker-config/{{VERSION}}</bundle>
290 <bundle start-level="40">mvn:org.opendaylight.controller/blueprint/{{VERSION}}</bundle>
291 <configfile finalname="${config.configfile.directory}/${config.mdsal.configfile}">mvn:org.opendaylight.controller/md-sal-config/{{VERSION}}/xml/config</configfile>
294 As illustrated, versions can be ommitted in this way for repository
295 dependencies, bundle dependencies and configuration files. They must be
296 specified traditionally (either hard-coded, or using Maven properties)
297 for feature dependencies.
302 This allows building a Karaf 3 distribution, typically for local testing
303 purposes. Any runtime-scoped feature dependencies will be included in the
304 distribution, and the ``karaf.localFeature`` property can be used to
305 specify the boot feature (in addition to ``standard``).
307 single-feature-parent
308 ~~~~~~~~~~~~~~~~~~~~~
310 This inherits from ``odlparent`` and enables functionality useful for
313 - ``karaf-maven-plugin`` is activated, to build Karaf features, typically
314 with “feature” packaging (“kar” is also supported);
316 - ``feature.xml`` files are generated based on the compile-scope dependencies
317 defined in the POM, optionally initialised from a stub in
318 ``src/main/feature/feature.xml``.
320 - Karaf features are tested after build to ensure they can be activated
321 in a Karaf container.
323 The ``feature.xml`` processing adds transitive dependencies by default, which
324 allows features to be defined using only the most significant dependencies
325 (those that define the feature); other requirements are determined
326 automatically as long as they exist as Maven dependencies.
328 “configfiles” need to be defined both as Maven dependencies (with the
329 appropriate type and classifier) and as ``<configfile>`` elements in the
330 ``feature.xml`` stub.
332 Other features which a feature depends on need to be defined as Maven
333 dependencies with type “xml” and classifier “features” (note the plural here).
338 This inherits from ``odlparent`` and enables functionality useful for
339 Karaf 4 feature repositories. It follows the same principles as
340 ``single-feature-parent``, but is designed specifically for repositories
341 and should be used only for this type of artifacts.
343 It builds a feature repository referencing all the (feature) dependencies
349 This allows building a Karaf 4 distribution, typically for local testing
350 purposes. Any runtime-scoped feature dependencies will be included in the
351 distribution, and the ``karaf.localFeature`` property can be used to
352 specify the boot feature (in addition to ``standard``).
357 This allows building a kind of immutable static distribution by adding
358 this as a parent to your project's pom.xml. This pom file defines the static
359 karaf framework alongside common OpenDaylight's components(branding,
360 bouncycastle items, etc). The major difference to the dynamic distribution is
361 that validation of features dependencies happens during the build phase and
362 all of the dependencies are installed as *"reference:file:url"* into the
363 *"etc/startup.properties"*. Static distribution might be the right choice when
364 you need to to produce a lightweight and immutable package for your deployment.
365 You can find a ``test-static`` project that inherits from ``karaf-dist-static``
366 and demonstrates how this parent can be used.
368 Generally speaking, to build a static distribution with selected for your
369 purposes features, you have to follow the next two steps:
371 1. Add features you want to be included in distribution under the
378 <groupId>org.opendaylight.odlparent</groupId>
379 <artifactId>odl-dropwizard-metrics</artifactId>
380 <version>${project.version}</version>
382 <classifier>features</classifier>
385 <groupId>org.opendaylight.odlparent</groupId>
386 <artifactId>odl-gson</artifactId>
387 <version>${project.version}</version>
389 <classifier>features</classifier>
393 2. Put additional configuration for the karaf-maven-plugin about these features:
398 <groupId>org.apache.karaf.tooling</groupId>
399 <artifactId>karaf-maven-plugin</artifactId>
400 <extensions>true</extensions>
402 <startupFeatures combine.children="append">
403 <feature>shell</feature>
405 <bootFeatures combine.children="append">
406 <feature>odl-dropwizard-metrics</feature>
407 <feature>odl-gson</feature>
412 .. note:: If you need to add something from the default karaf features
413 (like ``shell`` feature in our example), you should use
414 **<startupFeatures>** block, and not forget about
415 **combine.children="append"** attribute. Everything else can
416 be added to the bootFeatures block.
421 * An issue with FeatureDeploymentListener.bundleChanged and NPE records in
422 log files. More details available here:
423 https://issues.apache.org/jira/browse/KARAF-6612
425 * Some of the features might try to update configuration files, but that's
426 not supported by static distribution, so StaticConfigurationImpl.update
427 will throw UnsupportedOperationException.
429 Features (for Karaf 3)
430 ----------------------
432 The ODL Parent component for OpenDaylight provides a number of Karaf 3
433 features which can be used by other Karaf 3 features to use certain
434 third-party upstream dependencies.
438 - Akka features (in the ``features-akka`` repository):
440 - ``odl-akka-all`` — all Akka bundles;
442 - ``odl-akka-scala-2.11`` — Scala runtime for OpenDaylight;
444 - ``odl-akka-system-2.4`` — Akka actor framework bundles;
446 - ``odl-akka-clustering-2.4`` — Akka clustering bundles and
449 - ``odl-akka-leveldb-0.7`` — LevelDB;
451 - ``odl-akka-persistence-2.4`` — Akka persistence;
453 - general third-party features (in the ``features-odlparent``
456 - ``odl-netty-4`` — all Netty bundles;
458 - ``odl-guava-18`` — Guava 18;
460 - ``odl-guava-21`` — Guava 21 (not indended for use in Carbon);
462 - ``odl-lmax-3`` — LMAX Disruptor;
464 - ``odl-triemap-0.2`` — Concurrent Trie HashMap.
466 To use these, you need to declare a dependency on the appropriate
467 repository in your ``features.xml`` file:
471 <repository>mvn:org.opendaylight.odlparent/features-odlparent/{{VERSION}}/xml/features</repository>
473 and then include the feature, *e.g.*:
477 <feature name='odl-mdsal-broker-local' version='${project.version}' description="OpenDaylight :: MDSAL :: Broker">
479 <feature version='[3.3.0,4.0.0)'>odl-lmax</feature>
483 You also need to depend on the features repository in your POM:
488 <groupId>org.opendaylight.odlparent</groupId>
489 <artifactId>features-odlparent</artifactId>
490 <classifier>features</classifier>
494 assuming the appropriate dependency management:
498 <dependencyManagement>
501 <groupId>org.opendaylight.odlparent</groupId>
502 <artifactId>odlparent-artifacts</artifactId>
503 <version>1.8.0-SNAPSHOT</version>
504 <scope>import</scope>
508 </dependencyManagement>
510 (the version number there is appropriate for Carbon). For the time being
511 you also need to depend separately on the individual JARs as
512 compile-time dependencies to build your dependent code; the relevant
513 dependencies are managed in ``odlparent``'s dependency management.
515 | The suggested version ranges are as follows:
517 - ``odl-netty``: ``[4.0.37,4.1.0)`` or ``[4.0.37,5.0.0)``;
519 - ``odl-guava``: ``[18,19)`` (if your code is ready for it, ``[19,20)``
520 is also available, but the current default version of Guava in
523 - ``odl-lmax``: ``[3.3.4,4.0.0)``
525 Features (for Karaf 4)
526 ----------------------
528 There are equivalent features to all the Karaf 3 features, for Karaf 4.
529 The repositories use “features4” instead of “features”, and the features
530 use “odl4” instead of “odl”.
532 The following new features are specific to Karaf 4:
534 - Karaf wrapper features (also in the ``features4-odlparent``
535 repository) — these can be used to pull in a Karaf feature
536 using a Maven dependency in a POM:
538 - ``odl-karaf-feat-feature`` — the Karaf ``feature`` feature;
540 - ``odl-karaf-feat-jdbc`` — the Karaf ``jdbc`` feature;
542 - ``odl-karaf-feat-jetty`` — the Karaf ``jetty`` feature;
544 - ``odl-karaf-feat-war`` — the Karaf ``war`` feature.
546 To use these, all you need to do now is add the appropriate dependency
547 in your feature POM; for example:
552 <groupId>org.opendaylight.odlparent</groupId>
553 <artifactId>odl4-guava-18</artifactId>
554 <classifier>features</classifier>
558 assuming the appropriate dependency management:
562 <dependencyManagement>
565 <groupId>org.opendaylight.odlparent</groupId>
566 <artifactId>odlparent-artifacts</artifactId>
567 <version>1.8.0-SNAPSHOT</version>
568 <scope>import</scope>
572 </dependencyManagement>
574 (the version number there is appropriate for Carbon). We no longer use version
575 ranges, the feature dependencies all use the ``odlparent`` version (but you
576 should rely on the artifacts POM).