Skip to content

Add native OSGi bundle metadata to published jars - #498

Merged
trask merged 6 commits into
open-telemetry:mainfrom
royteeuwen:osgi-support
Aug 3, 2026
Merged

Add native OSGi bundle metadata to published jars#498
trask merged 6 commits into
open-telemetry:mainfrom
royteeuwen:osgi-support

Conversation

@royteeuwen

@royteeuwen royteeuwen commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Description

Closes #494

Publishes the semconv and semconv-incubating jars with OSGi bundle metadata so they can be consumed directly in OSGi containers, without external re-wrapping (e.g. hand-maintained wrapper bundles).

This mirrors the OSGi support recently added to opentelemetry-java: the bnd Gradle plugin (biz.aQute.bnd.builder) is wired into the shared otel.java-conventions plugin. Since the semconv modules have no SPI / ServiceLoader needs, the configuration is a trimmed-down version of the upstream one (no ServiceLoader mediator capabilities). Both published modules want OSGi metadata, so the bundle config is applied unconditionally rather than behind a flag.

Changes

  • buildSrc/build.gradle.kts — add the biz.aQute.bnd:biz.aQute.bnd.gradle plugin dependency.
  • otel.java-conventions.gradle.kts — apply biz.aQute.bnd.builder, make archives reproducible, and configure the main jar task's bundle with -exportcontents: io.opentelemetry.*. Import-Package is left to bnd's auto-detection, except io.opentelemetry.api.* which is pinned to [1.33,2) (bnd can't infer a range there because the pinned compileOnly opentelemetry-api 1.33.0 isn't itself a bnd bundle; 1.33 is the baseline :dependencyManagement already requires). Both modules (and any future module) are bundled automatically; the -sources/-javadoc jars are left plain.
  • osgi-test/ — new :osgi-test module (not published) that validates the bundles in a real OSGi runtime (see Testing).

Generated manifest (excerpt)

opentelemetry-semconv:

Bundle-SymbolicName: opentelemetry-semconv
Export-Package: io.opentelemetry.semconv;version="1.43.0";uses:="io.opentelemetry.api.common"
Import-Package: io.opentelemetry.api.common;version="[1.33,2)",java.lang,...
Automatic-Module-Name: io.opentelemetry.semconv

opentelemetry-semconv-incubating:

Bundle-SymbolicName: opentelemetry-semconv-incubating
Export-Package: io.opentelemetry.semconv.incubating;version="1.43.0";uses:="io.opentelemetry.api.common,io.opentelemetry.semconv"
Import-Package: io.opentelemetry.api.common;version="[1.33,2)",io.opentelemetry.semconv;version="[1.43,2)",...

Testing

  • New :osgi-test module boots the semconv + semconv-incubating jars inside a real Apache Felix container and runs JUnit 5 inside it, via bnd's BundleResolveTestOSGi task chain (modeled on opentelemetry-java's integration-tests/osgi). If either bundle's generated OSGi metadata is wrong (bad exports / unsatisfiable imports) the bundle won't resolve and the tests won't run — and the task fails explicitly in that case, since bnd otherwise reports success on zero tests. It's wired into test/check, so it runs as part of the normal ./gradlew build.
  • ./gradlew build passes (unit tests, checkstyle, japicmp, animal-sniffer, and the OSGi resolve test).
  • Verified the main jars carry the OSGi headers and the -sources/-javadoc jars remain plain.

@royteeuwen
royteeuwen requested review from a team as code owners June 14, 2026 17:46
@royteeuwen

Copy link
Copy Markdown
Contributor Author

@trask anything I can do to get this mergeable?

Copilot AI review requested due to automatic review settings July 14, 2026 19:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds native OSGi bundle metadata to the published semconv and semconv-incubating JARs by wiring the Bnd Gradle plugin into the shared otel.java-conventions build logic, enabling direct consumption in OSGi containers without wrapper bundles.

Changes:

  • Adds the biz.aQute.bnd.builder plugin to the shared otel.java-conventions precompiled script plugin and configures the main jar task to emit OSGi headers (exporting io.opentelemetry.* and auto-detecting imports).
  • Introduces osgiEnabled (default true) and osgiOptionalPackages extension knobs to control/augment OSGi import behavior.
  • Adds the Bnd Gradle plugin dependency to buildSrc and enables reproducible archive settings for JAR outputs.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts Applies/configures Bnd for OSGi metadata on the main jar and enables reproducible archive output.
buildSrc/src/main/kotlin/io/opentelemetry/gradle/OtelJavaExtension.kt Adds extension properties to control enabling OSGi metadata and optional import packages.
buildSrc/build.gradle.kts Adds the Bnd Gradle plugin dependency to the build logic classpath.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@trask trask left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a test?

or, related to open-telemetry/opentelemetry-java-instrumentation#18995, is there maybe another way / tool we could validate a jar for osgi compliance?

Wire the bnd Gradle plugin into the shared otel.java-conventions plugin
so the semconv and semconv-incubating jars are published with OSGi
manifest headers (Bundle-SymbolicName, Export-Package, Import-Package).
This lets the artifacts be consumed directly in OSGi containers without
external re-wrapping.

Fixes open-telemetry#494
@royteeuwen

Copy link
Copy Markdown
Contributor Author

@trask added a test. I went with the same approach as opentelemetry-java's integration-tests/osgi: a new :osgi-test module that boots the semconv + semconv-incubating jars inside a real Apache Felix container and runs JUnit 5 inside it via bnd's BundleResolveTestOSGi chain. If either bundle's generated OSGi metadata is wrong (bad exports / unsatisfiable imports) the bundle won't resolve and the tests won't run — and the task fails explicitly in that case, since bnd otherwise reports success on zero tests.

Two things surfaced while getting it to resolve, both scoped to the test module:

  • The semconv bundles Import-Package: io.opentelemetry.api.common, so resolution needs an opentelemetry-api that is itself an OSGi bundle. Since OSGi metadata was only added to core in Finish adding OSGi support opentelemetry-java#8417 (well after the 1.33.0 compileOnly baseline this repo pins), the test forces a recent opentelemetry-api on its own classpath.
  • opentelemetry-common (pulled in transitively) declares Require-Capability: osgi.serviceloader.processor, so the container needs Aries SPI Fly to resolve even though semconv has no ServiceLoader providers of its own.

Both are documented in comments in osgi-test/build.gradle.kts. It's wired into test/check, so it runs as part of the normal ./gradlew build.

Comment thread buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts Outdated
Comment thread buildSrc/src/main/kotlin/otel.java-conventions.gradle.kts Outdated
Comment thread settings.gradle.kts
@trask
trask merged commit 608b9f0 into open-telemetry:main Aug 3, 2026
17 checks passed
@royteeuwen
royteeuwen deleted the osgi-support branch August 4, 2026 06:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OSGi support

3 participants