Declaring Optional Import Package Requirements

When developing modules, you can declare optional dependencies. An optional dependency is one your module can use if available, but can still function without it.

If you decide that your module requires an optional dependency, follow these steps to add it:

  1. In your module’s bnd.bnd file, declare the package your module optionally depends on:


    Note that you can use either an optional or dynamic import. The differences are explained here.

  2. Create a component to use the optional package:

    import; // A class from the optional package
        enabled = false // instruct declarative services to ignore this component by default
    public class OptionalPackageConsumer implements Foo {...}
  3. Create a second component to be a controller for the first. The second component checks the class loader for the optional class on the classpath. If it’s not there, this means you must catch any ClassNotFoundException. For example:

    public class OptionalPackageConsumerStarter {
        void activate(ComponentContext componentContext) {
            try {
            catch (Throwable t) {
                _log.warn("Could not find {}", t.getMessage()); // Could use instead

If the class loader check in the controller component is successful, the client component is enabled. This check is automatically performed whenever there are any wiring changes to the module containing these components (Declarative Services components are always restarted when there are wiring changes).

If you install the module when the optional dependency is missing from Liferay DXP’s OSGi runtime, your controller component catches a ClassNotFoundException and logs a warning or info message (or takes whatever other action you implement to handle this case). If you install the optional dependency, refreshing your module triggers the OSGi bundle lifecycle events that trigger your controller’s activate method and the check for the optional dependency. Since the dependency exists, your client component uses it.

Note that you can refresh a bundle from Gogo shell with this command:

equinox:refresh [bundle ID] 

Configuring Dependencies

« Implementing LoggingResolving Bundle Requirements »