AEM in 40 Days
CalendarPhase 1 · Foundations

Day 5 of 40

OSGi

Bundles, services, components, and the Felix console

~35 min read1 video1 source page

By the end of today you should be able to

  1. Explain what an OSGi bundle is and how it differs from a plain JAR
  2. Describe the bundle lifecycle and what 'resolved' vs 'active' means
  3. Explain services, components and Declarative Services annotations
  4. Use the Felix web console to diagnose a bundle or component that will not start

Why AEM has a module system at all

AEM is a large Java application that must let you deploy, update and remove your code without restarting the server. That is what OSGi provides: a dynamic module system for the JVM. AEM's OSGi container is Apache Felix, and everything in AEM — including Adobe's own code — ships as OSGi bundles.

Bundles

A bundle is a JAR with extra manifest headers that declare its boundaries:

  • Bundle-SymbolicName and Bundle-Version — its identity.
  • Export-Package — the packages it makes visible to other bundles.
  • Import-Package — the packages it needs from elsewhere, with version ranges.

Unlike a plain classpath, nothing is visible unless it is explicitly exported and imported. This strict boundary is the source of the most common OSGi frustration: a class that exists in the JVM but that your bundle cannot see because nobody exported it. Your core module's bnd/maven-bundle-plugin configuration generates these headers for you.

The lifecycle

A bundle moves through states, and knowing them turns a mysterious failure into a two-minute diagnosis:

  • Installed — present, but its dependencies have not been satisfied.
  • Resolved — every Import-Package was matched. It can start.
  • Active — started and running. This is where you want to be.
Stuck in "Installed"

A bundle sitting at Installed rather than Active almost always has an unsatisfied import. Open /system/console/bundles, click it, and read the imports — the unsatisfied one is flagged. Usually it is a version range mismatch or a dependency you forgot to make available.

Services and components

Inside a bundle, an OSGi component is a class managed by the container. If it publishes itself under an interface, it is also a service that other code can consume. AEM uses Declarative Services (DS) annotations, so you write plain annotated classes:

@Component(service = GreetingService.class)
public class GreetingServiceImpl implements GreetingService {

    @Reference
    private SlingSettingsService settings;

    @Activate
    protected void activate(Config config) { /* ... */ }

    @Deactivate
    protected void deactivate() { /* ... */ }
}
  • @Component — register this class with the container; service= names the interface(s) it publishes.
  • @Reference — inject another service. By default this is mandatory: if it cannot be satisfied, your component stays unsatisfied and never activates.
  • @Activate / @Deactivate — lifecycle hooks, called when the component starts and stops.

Components are dynamic. A service can come and go at runtime, and the container rewires dependents accordingly. That is why you never cache a service reference in a static field.

The web console

At /system/console (locally: http://localhost:4502/system/console) you get the diagnostic tools you will use constantly:

  • /system/console/bundles — every bundle and its state. Your first stop after a deploy.
  • /system/console/components — every DS component, and crucially why an unsatisfied one is unsatisfied.
  • /system/console/configMgr — OSGi configuration (day 30).
  • /system/console/slingmodels — registered Sling Models and their adapters.
On Cloud Service

You do not get the Felix console on production. You get the Developer Console and downloadable logs instead. Locally the full console is available, which is exactly why reproducing problems on your local SDK matters.

Today's takeaway

Bundles are JARs with enforced boundaries; components are managed classes; services are components published under an interface. When something does not work after a deploy, check bundle state first, component state second.

Watch

Adobe's own videos for this topic. They load only when you press play.

Introduction to OSGi

Read on Experience League

The primary sources these notes are drawn from.

Your notes

Saved automatically to this browser.

Check yourself

11 questions on today's material. 80% to pass.

Take the quiz