This post revisits a system we built years ago: a CORBA-based distributed component assembly platform.
It is easy to label it as “legacy tech,” but that misses the point. The core problems we solved then are still with us today; only the implementation style has changed.

Project Snapshot: A Heterogeneous Component Assembly System

The system had four core components:

  • A bus component
  • A UI component
  • A database component
  • A server component

These components were implemented in different languages (C++ and Java) and interoperated through CORBA middleware.
We also built four Eclipse plugins for distributed application assembly, configuration, and deployment.
A naming/registry-like service handled service registration and discovery.

In short, this was a true heterogeneous distributed system: heterogeneous languages, heterogeneous components, and heterogeneous runtime environments, unified through architecture.

Why the CORBA Stack Looked Heavy

People often summarize CORBA with a list of “heavy” concepts:

  • IDL
  • Stub/Skeleton
  • ORB
  • Naming Service
  • Object Lifecycle
  • Distributed Transaction

That stack was not heavy for its own sake. It made key distributed concerns explicit:

  • How interfaces are defined and evolved (IDL)
  • How cross-language invocation is generated and enforced (Stub/Skeleton)
  • How remote objects are located and routed (ORB/Naming)
  • How component/object lifecycle is managed (Lifecycle)
  • How consistency is handled across boundaries (Transaction)

None of these concerns disappeared in modern systems. They were redistributed across different layers.

The Turning Point: Remote Is Not Local

Early distributed object design often pursued this ideal: remote invocation should feel like local invocation.
Reality kept pushing back:

  • Networks fail
  • Latency is unpredictable
  • Timeouts and retries are non-trivial
  • Version compatibility gets hard at scale

The industry eventually aligned on a practical truth: RPC is not a local function call.
That is why REST, gRPC, and event-driven systems emphasize explicit boundaries, failure semantics, idempotency, and observability.

Then vs Now: Different Tools, Same Abstractions

A simplified mapping makes the continuity obvious:

  • IDL -> OpenAPI / Protobuf / AsyncAPI
  • Naming Service -> Consul / Eureka / Kubernetes DNS
  • ORB routing semantics -> API Gateway / Service Mesh
  • Message bus -> Kafka / NATS / Pulsar
  • Lifecycle governance -> Kubernetes Controller / Operator
  • Distributed transaction -> Saga / Outbox / Eventual Consistency

If you focus on product names, it looks like replacement.
If you focus on architectural abstractions, it is evolution and recomposition.

Eclipse Plugins and Today’s Platform Engineering

Our four Eclipse plugins effectively implemented platform engineering patterns before the term became mainstream:

  • Extension points (plugin model)
  • Component assembly orchestration
  • Standardized deployment workflow
  • Lifecycle and dependency governance

This aligns directly with modern IDE ecosystems, internal developer platforms, developer portals, and composable tooling pipelines.

Under the Hood of Eclipse Plugins: What OSGi Actually Solves

The Eclipse plugin runtime is built on OSGi.
In practical terms, OSGi is a modular runtime that supports dynamic loading, dependency isolation, and service registration.

Its core mechanics include:

  • Bundle modularization: each plugin is a bundle with explicit metadata and dependencies
  • Lifecycle control: install/start/stop/update/uninstall
  • Service registry: bundles publish and consume services at runtime
  • Classloader isolation: each bundle has controlled visibility, reducing classpath conflicts
  • Version governance: import/export package constraints and version ranges

This is why Eclipse plugin systems scale beyond “drop jars into a folder”: OSGi provides runtime governance, not just packaging.

OSGi also comes with trade-offs:

  • Steeper learning curve (especially classloading and versioning)
  • Higher debugging complexity than standard monolith setups
  • Stronger need for engineering discipline across teams

OSGi vs Current Extension Approaches

Today, teams more commonly use:

  • IDE extension ecosystems: VS Code extensions, JetBrains plugins
  • Web extensibility models: micro-frontends, module federation, plugin-like web shells
  • Platform/backend extensibility: sidecars, operators, hooks, workflow plugin nodes
  • Low-code or workflow tools with scripted extension points

Compared with OSGi:

  • OSGi strengths: strict module boundaries, strong dependency control, runtime dynamism
  • OSGi weaknesses: heavier mental model, higher implementation overhead, lower mainstream adoption
  • Modern strengths: faster developer onboarding, richer ecosystem momentum, better cloud-native alignment
  • Modern weaknesses: many solve extension points, but not OSGi-level runtime governance

A practical rule of thumb:
if you need long-lived enterprise modularity with strict isolation and version governance, OSGi principles remain highly relevant;
if speed of delivery and broad ecosystem leverage are the priority, modern extension stacks usually win.

EJB, CORBA, and Modern Microservices

EJB is no longer common in greenfield systems, and CORBA is no longer the default integration path.
But the capabilities they packaged did not vanish. They were decomposed:

  • Communication: REST / gRPC
  • Discovery: Service registry / Kubernetes-native discovery
  • Governance: Gateway / Mesh / Observability stacks
  • Consistency: Strong consistency in narrow scopes, eventual consistency in broader workflows

From an architecture-history perspective, this is less “replacement” and more “decomposition of monolithic middleware into composable infrastructure.”

Does This Legacy Still Matter?

Yes, strongly.

Many teams can use modern frameworks but still lack depth in:

  • Service discovery fundamentals
  • IDL/contract-first design
  • Cross-language protocol boundaries
  • Message bus decoupling patterns
  • Component lifecycle and plugin-oriented architecture

Those fundamentals are exactly what heterogeneous distributed systems force teams to learn.

Final Takeaway

What we built with CORBA was not just a legacy implementation; it was full-spectrum distributed systems engineering.
Today’s stack has shifted from CORBA/EJB to REST/gRPC/Kubernetes, but the foundational questions are still the same:

  • How to define stable contracts
  • How to govern discovery and routing
  • How to control cross-language complexity
  • How to manage lifecycle and evolution cost
  • How to build reliability on unreliable networks

Technology evolves. Core systems thinking persists.
The durable advantage is not a specific framework, but your ability to reason about these constraints across generations of tooling.