OSGi package dependencies and exports

  Written by The Jahia Team
 
Developers
   Estimated reading time:

Before going any further, it is very important to understand what OSGi package dependencies are, how they work and how to use them properly.

The OSGi framework will only let you access a Java package located in another OSGi bundle if:

  • It is exported by an OSGi bundle
  • It is imported by your own bundle

OSGi imports and exports must be declared in the META-INF/MANIFEST.MF file, with the Import-Package and Export-Package headers. If an import or export is missing, or if versions of packages don’t match, no access to the package will be allowed by the bundle’s class loader. Management of the package imports and exports is the main learning curve involved in learning to use OSGi. Fortunately, Jahia offers tooling such as the Jahia Maven Plugin that helps generate dependencies for common module projects. There are also other OSGi plugins available on the Internet but usually the Felix Maven Bundle Plugin and the Jahia Maven plugin should be sufficient for most projects.

If your module is based on jahia-modules, the plugins are preconfigured to detect the required imports. You can manually add or modify packages by setting the  jahia.modules.importPackage property in your pom.xml file. It is also possible to completely override the default configuration by setting the import-package property. If you need to expose a package to other modules, you must declare it explicitly by setting the export-package property :

    <properties>
        <jahia.modules.importPackage>org.jahia.defaults.config.spring,org.jahia.modules.external</jahia.modules.importPackage>
        <export-package>org.jahia.modules.external.users</export-package>
    </properties>

Import and exports can also specify versions and options. More documentation can be found here and here.

Module dependecy with Jahia-depends

When developing modules with dependencies outside of core functionality, developers can specify Jahia-depends configuration in the pom.xml to explicitly declare its module dependencies. This allows the module to perform checks within the OSGI lifecycle and ensure dependencies are met prior to resolving and starting the module within the OSGI runtime. This is declared in the module pom.xml as following, where dependency-module is the artifact ID that this module depends on:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <configuration>
                <instructions>
                    <Jahia-Depends>dependency-module</Jahia-Depends>
                </instructions>
            </configuration>
        </plugin>
    </plugins>
</build>

This configuration is implemented through the use and declaration of OSGI Requirements and Capabilities constraint model within the generated module manifest file.

Version Restriction

With the 8.0.3 release, Jahia added support for specifying additional versions' requirement of the dependency specified. This is helpful in cases, for example, where the current module depends on certain features that is only available in certain versions of the dependency. The version restriction clause of module dependency is specified with =  followed by either a lower bound version restriction e.g. dependency-module=<version> or by a specific version range restriction e.g. dependency-module=[<version-lower-bound>, <version-upper-bound>] . The version range clause follows OSGI version syntax and supports use of inclusive range ( [  or ] ) and exclusive range ( (  or ) ) for lower-bound or higher-bound restrictions, or both. The version number parameter itself supports and matches major, minor and micro level granularity that conforms to OSGI version number syntax. The Jahia-depends configuration also supports mixed usage of dependencies with version restriction clause as optional.

As an example, the following Jahia-depends configuration can be added in the pom.xml file:

<Jahia-Depends>dep-module1=4.1,dep-module2,dep-module3=[0, 3)</Jahia-Depends> 

This means that the module requires:

  • dep-module1 that is greater than or equal to 4.1.x version
  • dep-module2 (any version available)
  • dep-module3 that is less than but not equal to any 3.x.x version

The module itself also needs to require at least 8.0.3 as parent version to use the version restriction clause:

<parent>
    <artifactId>jahia-modules</artifactId>
    <groupId>org.jahia.modules</groupId>
    <version>8.0.3.0</version>
</parent>

Module Administration

When a module has a dependency requirement and is deployed, OSGI framework will try to resolve those dependencies and start the module as necessary. If a dependency is resolved successfully, then the module itself should be started within the framework. This can be verified within the Jahia Module Administration (v2.2.1) page (Settings > Modules and Extensions > Modules). If one or more dependencies are not resolved (either dependency does not exist at all or version restriction is not satisfied) then the module will get an error message within the Module Administration page like the following:

jahia-depends1.png

In this example, the jahia-starter-template module has a declared dependency page-builder-components=[2,4] where it requires page-builder-components module to be installed with version between 2.x.x and 4.x.x inclusive. In this example, page-builder-components module installed has a 1.0.0 version and is out of range of the specified version restriction. Notice that the jahia-starter-template module also has an Inactive status and cannot be started until the conflict is resolved.