fix(extensions): report the manifest's service list and drop the unread descriptor reader#923
Open
jbachorik wants to merge 1 commit into
Open
fix(extensions): report the manifest's service list and drop the unread descriptor reader#923jbachorik wants to merge 1 commit into
jbachorik wants to merge 1 commit into
Conversation
…ad descriptor reader `btracex inspect` reported every shipped extension's services as `org.slf4j.spi.SLF4JServiceProvider,javax.annotation.processing.Processor`. `ExtensionInspector.readServices` listed the *filenames* under `META-INF/services/` in the impl JAR, which are the SPI files that shading leaves behind from dependencies, not the extension's own services. All seven bundled extensions were affected. The service list now comes from the API JAR's `BTrace-Extension-Services` manifest attribute -- the same source `ExtensionMetadata` reads when the runtime loads and permission-checks an extension, so inspection cannot disagree with what the runtime enforces. `ExtensionMeta` was a third reader of extension identity that nothing reached: its only caller discovered extension classes through a `META-INF/services/io.btrace.core.extensions.Extension` entry that no packaged extension contains, so it always returned an empty list. Its four identity getters had no callers at all. Removing it leaves two live descriptor sources: the manifest, which is authoritative, and package-level `@ExtensionDescriptor`, whose `permissions` the Gradle plugin still asserts against the manifest at build time. The TUI carried a verbatim copy of the same service reader feeding a field nothing displayed; it is gone. Its hand-maintained list of privileged permission names now defers to `Permission.isPrivileged()`, and uppercases with `Locale.ROOT` so a Turkish locale cannot turn `reflection` into a name `valueOf` rejects. Inspection output is otherwise unchanged: `Version`, `Privileged` and `Required` are byte-identical across all seven extensions before and after. Tutorials 04 and 07 already documented the correct service list; tutorial 06 explained the defect as intended behaviour and is rewritten. Three documents also carried a stale `Required : [THREADS]` for btrace-metrics, which reports `[CLASSLOADER,REFLECTION,THREADS]`. Fixes #919
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
btracex inspectreported the wrong service list for every one of the seven bundledextensions:
ExtensionInspector.readServiceslisted the filenames underMETA-INF/services/in theimpl JAR. Those files come from shaded dependencies, not from the extension. The service list
now comes from the API JAR's
BTrace-Extension-Servicesattribute — the same sourceExtensionMetadatareads when the runtime loads and permission-checks an extension.This reaches users through
btracex inspect <path>,btracex install, and the repo browser.docs/tutorials/04and07already documented the correct output, which is what confirms thiswas a regression rather than intent.
docs/tutorials/06documented the defect as expectedbehaviour and is rewritten.
Removing the third descriptor reader
ExtensionMetawas a third reader of extension identity that nothing reached. Its only callerdiscovered extension classes through a
META-INF/services/io.btrace.core.extensions.Extensionentry that no packaged extension contains, so it always returned an empty list; four of its six
getters had no callers at all. It cannot be revived as-is either:
BTrace-Extension-Servicesnames the API interface, while the
Extensionsubclass lives only in the impl JAR, so nothingyields the
Class<? extends Extension>its factory requires.This is what #919 asked for — "decide the single source of truth". Two formats are live and stay:
the manifest, which is authoritative, and package-level
@ExtensionDescriptor, whosepermissionsthe Gradle plugin still asserts against the manifest at build time. The third isgone.
ExtensionMetaispublicand ships unmasked inio.btrace:btrace, so it would be compilableAPI — but no 3.0.0 has been released (latest tag
v2.2.6, and theio.btrace.*namespace isitself new in 3.0; 2.x used
org.openjdk.btrace). Removing it now is free; after 3.0.0 it wouldnot be. There is no CHANGELOG in this repo, so this note is the record of the removal.
The TUI carried a verbatim copy of the same reader feeding a field nothing displayed — deleted.
Its hand-maintained list of privileged permission names now defers to
Permission.isPrivileged().Evidence
Before/after, driving the real CLI over the staged distribution. Only the
Servicesline moved—
Version,PrivilegedandRequiredare byte-identical for all seven:Services :afterio.btrace.contracts.ContractServiceio.btrace.gpu.GpuBridgeServiceio.btrace.llm.LlmTraceServiceio.btrace.metrics.MetricsServiceio.btrace.rag.RagQualityServiceio.btrace.statsd.Statsdio.btrace.utils.PrinterServiceVerified the new tests fail against
develop's sources and pass with the fix: 5 of 11ExtensionInspectorTestcases andBTraceJarPackagingTest.inspectionReportsWhatTheManifestDeclaresgo red before, green after.
:btrace-dist:build,:btrace-core:test,:btrace-client:testandspotlessCheckall pass.Tests
BTraceJarPackagingTest.inspectionReportsWhatTheManifestDeclaresdrives the realbtracex inspectentry point and asserts reported id, version, services and permissions match themanifest, for every allow-listed extension. This is [3.0] Reconcile the three coexisting extension descriptor formats #919's last checklist item.
BTraceJarPackagingTest.extensionManifestsAreSelfConsistentpins the manifest invariants(
-Id= directory name,-Version= distribution version,-Implresolves, declared serviceclasses present in the API JAR).
ExtensionInspectorTestgains the services-from-manifest cases, plus coverage for the@ServiceDescriptorpermission merge — which this change leaves as the only annotation-basedcontributor to the reported permission set, and which had no test at all.
inspectExtensionWithPermissionswas previously vacuous: its fixture wroteMETA-INF/btrace/permissions.propertieswhile the reader looks forMETA-INF/btrace-extension.properties, so theprivilegedflag never reached the inspector.The fixture now emits the manifest attribute, making privileged detection genuinely tested.
Deliberately not fixed
ExtensionMetadata.scanServicesDirectoryreads services-file contents (implementationFQCNs) rather than names, so the runtime's service list for
examples/btrace-hadoopincludes animpl class. Pre-existing, already recorded at
internal/analysis/2026-07-04-core-runtime-analysis.md:383, and out of scope here.META-INF/services/io.btrace.core.extensions.Extensionin an impl module loses the@ExtensionDescriptorpermission merge in inspection output. No supported build path emits thatfile — the Gradle plugin never writes it.
Incidental
Three documents carried a stale
Required : [THREADS]forbtrace-metrics, which reports[CLASSLOADER,REFLECTION,THREADS](ExtensionReport.toStringsorts). Wrong ondeveloptoday,independent of this change; corrected while editing the same lines.
Fixes #919
This change is