Chapter 7. Designing Modular Applications

This chapter will present some common techniques and design patterns that are used to implement modular applications with OSGi. It starts by introducing the concept of semantic versioning, which is a key part of how bundles and packages are versioned, followed by how baselining can be used to enable automatic version incrementing. This is then followed by an overview of some of the design patterns common in OSGi applications, including the benefits they present, and finally finishes with a list of best practices in OSGi.

Semantic versioning

A key aspect of OSGi bundles and packages is that they are versioned using semantic versioning. This encodes compatibility into the version number so that clients can select an appropriately versioned component to build against or bind to.

Semantic versioning breaks down a number such as 1.2.3.RELEASE into the following four parts:

  • Major version: This is a number that indicates the major release (1)
  • Minor version: This is a number that indicates the minor release (2)
  • Micro (or patch) version: This is a number that indicates the micro (patch) release (3)
  • Qualifier: This is a textual string that indicates the patch (RELEASE)

This version numbering scheme is used by every Java JAR in Maven Central and can be used to determine whether or not upgrading to a later version will be compatible. Numbers default to 0 if they are not specified, and the qualifier defaults to an empty string. In OSGi, numbers are sorted numerically and the qualifier is sorted alphabetically.

Changes in major version numbers are deemed to be incompatible changes. Thus, a client that depends on commons-collections-1.0 might not be able to upgrade directly to 2.0. In a major change, it is expected that there will be backward compatibility problems, such as renaming entire packages or removing methods or classes that used to exist.

Changes in the minor version are expected to be backward compatible, but with new functionality. For example, clients that are built and tested against commons-collections-2.0 might expect to be able to upgrade to commons-collections-2.1 without recompilation. Changes that are backward compatible include adding new classes or new packages, or for interfaces or classes that are not designed to be implemented or subclassed, adding new methods. In Java 8, adding new default methods is considered a backward compatible change.

Changes in the micro version are deemed to be backward compatible without any change in the API. These are incremented when bug fixes are performed. Note that a bug fix by definition includes user visible behavior (the bug existed before, but not afterwards), but this does not usually mean a change in the API or the contract. If the contract or API is changed to accommodate a bug fix, then the appropriate version numbers should be incremented.

Finally, the qualifier is used to encode optional metadata, such as the state or quality of the release (for example, M1, RC2, or RELEASE) or a date or timestamp (such as 201408171400).

Semantic versioning also suggests that initial development starts with a major version of 0 and that until the major version reaches 1, the content is in flux. Although not strictly recognized by OSGi, it is a common convention that others tend to use.

Tip

M1 stands for Milestone 1 and RC2 stands for Release Candidate 2. These can be compared lexicographically along with Release, since Mx < RCx < RELEASE.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset