Skip to content
CMO & CTO
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

  • Digital Experience
    • Experience Strategy
    • Experience-Driven Commerce
    • Multi-Channel Experience
    • Personalization & Targeting
    • SEO & Performance
    • User Journey & Behavior
  • Marketing Technologies
    • Analytics & Measurement
    • Content Management Systems
    • Customer Data Platforms
    • Digital Asset Management
    • Marketing Automation
    • MarTech Stack & Strategy
    • Technology Buying & ROI
  • Software Engineering
    • Software Engineering
    • Software Architecture
    • General Software
    • Development Practices
    • Productivity & Workflow
    • Code
    • Engineering Management
    • Business of Software
    • Code
    • Digital Transformation
    • Systems Thinking
    • Technical Implementation
  • About
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

OSGi for Modular Systems: Why and How

Posted on October 21, 2012 By Luis Fernandez
\n

Context

\n\n\n\n

Modular apps are back in the spotlight. We keep shipping giant wars, we fight classpath hell, we restart servers for the tiniest tweak, and we swear we will fix it next sprint. The Java module project from the JDK team is still somewhere on the horizon, while the OSGi standard keeps showing up in places that quietly run most of our day to day work. Eclipse is OSGi at its core. Adobe CQ runs on OSGi with Apache Sling. Atlassian plugins rely on OSGi to load and isolate features. Apache folks keep shipping goodies like Felix, Karaf, and Sling, and the OSGi Alliance pushed Release 5 earlier this year with a smarter resolver and cleaner metadata. If you want real modular systems on the JVM today, OSGi is not just a buzzword. It is a toolset you can use right now.

\n\n\n\n

Definitions

\n\n\n\n

Let us strip the buzz off and get to the point. OSGi is a set of specs that define how to build modules called bundles for the JVM. A bundle is just a jar with extra metadata that says what it gives and what it needs. The runtime provides a module layer and a service registry so bundles can find each other safely, versioned, and at runtime.

\n\n\n\n

Key pieces you meet on day one:

\n\n\n\n
  • Bundle: a jar with a manifest that declares name, version, what packages it exports, what packages it imports, and lifecycle actions.
  • Class loader isolation: each bundle gets its own class loader so you can keep multiple versions of the same library in the same VM without tears.
  • Import Package and Export Package: headers in the manifest that list the contracts a bundle needs and offers. Version ranges keep you honest.
  • Service registry: a lightweight registry where bundles publish and consume services by interface. You get decoupling with less wiring pain.
  • Lifecycle: install, start, stop, update, uninstall. You can change a running system without a full restart if you design for it.
  • Declarative Services and Blueprint: two friendly ways to wire services so you do not write lifecycle code by hand. DS is annotation friendly. Blueprint uses XML and plays nice with Spring habits.
  • Runtimes and tools: Apache Felix and Equinox are the common runtimes. Karaf is a sweet container on top with features, logging, and a shell. bnd and the maven bundle plugin generate your manifest correctly. Pax Exam helps with tests inside a container.
\n\n\n\n

New in the latest spec drop, the capabilities and requirements model brings a smarter resolver. Think of it as Import Package grown up into a general way to express what a bundle needs and what it provides. This leads to better resolution of graphs and cleaner installs.

\n\n\n\n

Examples

\n\n\n\n

Here are patterns I have used that paid off.

\n\n\n\n
  • Plugin friendly platforms: If your product needs an extension story, OSGi gives you the structure. Expose a set of stable interfaces in an API bundle, publish services, and let third parties contribute their own bundles. You can keep the platform stable while plugins evolve on their own schedule. See what Eclipse and Atlassian do here. It works.
  • Long lived servers: With Karaf, you can install and update features without a full bounce. I have upgraded a logging bundle and a single connector while keeping sessions going. Not every change can be hot reloaded, but the number of times you avoid a full restart is not small.
  • Library conflicts contained: Ever had two libraries that require different versions of the same dependency. In a plain web app you pick one and pray. In OSGi you can run both. Each bundle imports a specific version range, and the runtime wires them without leaking into your neighbor.
  • Clear API and impl split: You publish a clean package from an API bundle, keep the implementation in a separate bundle, and wire through the service registry. That split makes upgrades and refactors less scary because consumers depend on the interface and version numbers keep everyone honest.
  • Team scale: Teams own bundles. They ship their piece with its life cycle and version. A release is a set of bundle versions. You stop arguing about mysterious classpath order and instead talk about contracts and ranges.
\n\n\n\n

Real world stacks that ride this today: Adobe CQ with Apache Sling on Felix, Eclipse Equinox, Apache ServiceMix and Karaf for integration work, GlassFish 3 with OSGi support, and JBoss OSGi for folks in that camp. If you build for any of these, you are already in OSGi land whether you know it or not.

\n\n\n\n

Counterexamples

\n\n\n\n

There are also cases where OSGi adds more moving parts than you need.

\n\n\n\n
  • Single module web apps: If your app is a small CRUD in Tomcat with one team, your pain is probably not modularity. You can get far with a simple war, Spring, and Maven. OSGi will not magically make that code better.
  • Short lived processes: Command line tools or batch jobs that spin up, do work, and exit do not benefit much from a dynamic module runtime.
  • Libraries that fight class loaders: Some libraries assume one class loader and global static state. They can be tamed, but the time you spend can exceed the benefit. Old logging toolkits, old XML parsers, and bytecode tricks can be annoying.
  • Teams without time for basics: If your team is under pressure to ship next week and nobody has touched OSGi before, it is easy to shoot your foot with split packages, wrong imports, or version ranges. The learning curve is not steep forever but the first month needs attention.
\n\n\n\n

There are also anti patterns to avoid inside OSGi:

\n\n\n\n
  • Require Bundle everywhere: It couples you to a specific bundle rather than a package or a service. Prefer Import Package and service contracts. Keep it loose.
  • Split packages: Spreading the same package across bundles is a trap. Pick a bundle to own a package and stick to that.
  • All bundles start at boot: Let the runtime activate only what is needed. DS and Blueprint help you get lazy activation right.
\n\n\n\n

Decision rubric

\n\n\n\n

If you are trying to decide whether to go with OSGi for a new system or to introduce it into an existing one, use this checklist. If you hit yes on most items in a group, you know where you stand.

\n\n\n\n

Pick OSGi now if

\n\n\n\n
  • You need a plugin model with third party extensions and safe isolation.
  • You must run multiple versions of the same library or component in one JVM.
  • You aim for long uptime and want to update parts without a full restart.
  • You have several teams and want a clear API first approach with versioned contracts.
  • Your target platform already uses OSGi such as Equinox, Karaf, Adobe CQ, or ServiceMix.
  • You want strong module boundaries beyond what Maven scopes give you at build time.
\n\n\n\n

Stay simple for now if

\n\n\n\n
  • Your app is small or short lived and a single deployable is enough.
  • Your deps are stable and you do not need runtime updates.
  • Your team is new to modular design and you cannot spare time to learn the basics this quarter.
\n\n\n\n

If you choose OSGi, do it this way

\n\n\n\n
  • Start with Karaf or Felix for a friendly runtime. Karaf features make life easy.
  • Use bnd or the maven bundle plugin to generate manifests. Do not hand craft headers.
  • Prefer Declarative Services for wiring. It is lean, annotation friendly, and fast to start.
  • Publish clear APIs in their own bundles and keep impl separate.
  • Adopt semantic versioning for packages and bundles. Major means breakage.
  • Test in container with Pax Exam so you catch wiring and lifecycle issues early.
\n\n\n\n

Lessons learned

\n\n\n\n

After shipping a few OSGi based products, here are the bits I keep repeating to teams.

\n\n\n\n
  • Design around services: Think in terms of interfaces and small service contracts. Keep the number of exported packages small. More contracts does not mean better design.
  • Keep bundles cohesive: One bundle should have a single story. Not too tiny, not kitchen sink. Feature sized is a good rule.
  • Package versioning is the real deal: You version packages because that is what consumers import. Bumping bundle version without touching package versions is just bookkeeping.
  • Import by package with ranges: Import Package gives you a clean contract. Use ranges that reflect your tolerance. Be strict on breaking changes, flexible on minor updates.
  • Avoid static singletons: In OSGi they turn into hidden globals that cross module boundaries. Use the service registry, it is what it is there for.
  • Watch logging and class loaders: Choose a logging stack that plays nice with multiple class loaders. slf4j with an OSGi aware binding keeps things sane.
  • Kill split packages on sight: They lead to resolution surprises and brittle builds. Refactor so one bundle owns one package.
  • Blueprint vs DS: Blueprint is a gentle path if your team is very Spring minded. For new greenfield, DS is lighter and usually faster to start.
  • Do not hot reload everything: Plan for hot updates for the parts that benefit. Database schema changes and deep framework wiring often still require a bounce. That is fine.
  • Automate resolution: Let the resolver and bnd do the heavy lifting. Manual classpath style thinking does not translate to OSGi.
  • Document the contracts: Your API bundle is your product to other teams. Write javadoc, state version policy, and include examples of the service lifecycle.
\n\n\n\n

Where does this leave us. For teams shipping server side Java today, OSGi gives modular systems that work now. The spec has been around a long time, the tooling is solid, and the platforms that matter run it in production. We are still waiting for the JDK to bring a module story out of the box. Until then, OSGi is the practical way to get strong boundaries, versioned contracts, and dynamic services without reinventing the wheel.

\n\n\n\n

If you are sitting on a monolith and dreading the next upgrade, carve out a small feature, turn it into a bundle, wire it through the service registry, and run it in Karaf. Feel what controlled modularity looks like on a real system. You will either confirm you do not need it, or you will not want to go back.

\n
Software Architecture Software Engineering

Post navigation

Previous post
Next post
  • Digital Experience (94)
    • Experience Strategy (19)
    • Experience-Driven Commerce (5)
    • Multi-Channel Experience (9)
    • Personalization & Targeting (21)
    • SEO & Performance (10)
  • Marketing Technologies (92)
    • Analytics & Measurement (14)
    • Content Management Systems (45)
    • Customer Data Platforms (4)
    • Digital Asset Management (8)
    • Marketing Automation (6)
    • MarTech Stack & Strategy (10)
    • Technology Buying & ROI (3)
  • Software Engineering (310)
    • Business of Software (20)
    • Code (30)
    • Development Practices (52)
    • Digital Transformation (21)
    • Engineering Management (25)
    • General Software (82)
    • Productivity & Workflow (30)
    • Software Architecture (85)
    • Technical Implementation (23)
  • 2025 (12)
  • 2024 (8)
  • 2023 (18)
  • 2022 (13)
  • 2021 (3)
  • 2020 (8)
  • 2019 (8)
  • 2018 (23)
  • 2017 (17)
  • 2016 (40)
  • 2015 (37)
  • 2014 (25)
  • 2013 (28)
  • 2012 (24)
  • 2011 (30)
  • 2010 (42)
  • 2009 (25)
  • 2008 (13)
  • 2007 (33)
  • 2006 (26)

Ab Testing Adobe Adobe Analytics Adobe Target AEM agile-methodologies Analytics architecture-patterns CDP CMS coding-practices content-marketing Content Supply Chain Conversion Optimization Core Web Vitals customer-education Customer Data Platform Customer Experience Customer Journey DAM Data Layer Data Unification documentation DXP Individualization java Martech metrics mobile-development Mobile First Multichannel Omnichannel Personalization product-strategy project-management Responsive Design Search Engine Optimization Segmentation seo spring Targeting Tracking user-experience User Journey web-development

©2025 CMO & CTO | WordPress Theme by SuperbThemes