Bundle anatomy and manifest metadata
The manifest is the bundle's machine-readable contract.
Identity and content
Bundle-ManifestVersion: 2
Bundle-SymbolicName: com.acme.billing.api
Bundle-Version: 2.3.1
Export-Package: com.acme.billing.api;version="2.3.0"
Import-Package: org.osgi.framework;version="[1.10,2)"
Bundle-SymbolicName identifies the bundle.
Bundle-Version versions the artifact. Exported packages
have their own API versions. Package versions—not Maven artifact
versions—drive package resolution.
Import-Package
An import range describes compatible providers. [1.2,2)
means at least 1.2 and below 2.0. An unbounded or overly wide import can
wire to a binary- incompatible provider. A range locked to one micro
version blocks safe patches.
Export-Package
Export only intentional API packages. Keep implementation packages
private. Use @ProviderType for interfaces consumers
implement rarely and @ConsumerType for interfaces consumers
are expected to implement; bnd uses these roles during baselining.
Require-Bundle
Require-Bundle exposes a provider bundle's exported
packages as a unit and couples to bundle identity. Prefer package
imports for normal libraries. Require-Bundle remains
relevant in ecosystems such as parts of Eclipse where bundle-level
relationships are deliberate.
Resources and native code
Bundles can contain configuration, DS descriptors, localization, and native libraries. Class-relative resource lookup and bundle APIs have different visibility semantics. Native code clauses require careful OS, processor, and lifecycle handling.
Let bnd calculate metadata
Handwritten manifests drift. bnd analyzes bytecode to calculate imports, generates DS descriptors from annotations, and warns about split or unused relationships. Keep instructions intentional; inspect the generated manifest.
Feynman check
The Maven dependency says what was available while compiling. The OSGi import says what must be wired while resolving. Explain why shipping the first does not prove the second.