Skip to content

Conversation

@jbachorik
Copy link
Collaborator

@jbachorik jbachorik commented Jan 1, 2026

🚀 Modernize Extensions: Descriptor‑based permissions, strict API lint, builder‑based metrics, and CI stability

This PR finishes the extensions overhaul by standardizing on descriptor‑based permissions and safe, policy‑aware runtime linking. It removes legacy probe/extension permission annotations, tightens verifier semantics, introduces service‑provided builders (no new in probes), adds convenience APIs for common cases, and stabilizes CI.


🧭 Summary

  • 🔐 Descriptor‑based permissions and metadata
    • @ServiceDescriptor(permissions = { ... }) on service interfaces (API JAR).
    • Package‑level @ExtensionDescriptor(permissions = { ... }) in package-info.java (optional; API JAR).
    • Plugin auto‑detects services and validates/merges permissions into the API JAR manifest.
  • ✂️ Remove legacy permission annotations
    • Probe‑level @RequestPermission(s) and extension‑level @RequiresPermission(s) are removed.
    • Verifier + runtime enforce from the manifest and agent grants.
  • 🧱 Verifier and runtime linking remain strict and safe
    • No object construction in probes (no new).
    • Calls are allowed only on BTraceUtils, injected services, and service‑returned objects.
    • Clearer error messages suggest using service builders/factories.
  • 🧰 Gradle plugin validation (strict by default)
    • Lints public API classes with public constructors (apiCtorSeverity = 'error' by default).
    • Cross‑checks descriptor‑declared permissions vs manifest.
    • Enforces at most one package‑level @ExtensionDescriptor in the project.
  • 📈 Metrics refactor (API + Impl)
    • HistogramConfig is now an API interface;
    • HistogramConfigBuilder (API) produced by the service; HistogramConfigImpl lives in impl.
    • Convenience creators: histogramMicros(name[, key]), histogramMillis(name[, key]) (replace prior constants like MICROS, MILLIS).
  • 🧪 CI stability fixes for integration tests
    • compileTestProbes depends on :btrace-instr:jar and :btrace-compiler:jar to avoid race‑condition “zip END header not found” errors.

🧩 Architecture

  • Injection: @Injected fields always link via invokedynamicExtensionIndy → policy‑aware ExtensionBridge → implementation (or SHIM fallback); APIs are on bootstrap, impls are loaded on demand.
  • Permissions: Declared in descriptors → written to manifest by the plugin → enforced by verifier/runtime against agent grants (--grant=...).
  • SHIMs: Supported via META-INF/btrace/shims.index (noop/throw) when implementations are blocked or missing.

🧪 Tests

  • Integration tests: compile step now serializes jar builds; examples updated to use convenience creators.
  • Extension/runtime tests: policy behaviors, ServiceLoader precedence, SHIM index parsing.

📚 Docs

  • Updated Tutorial and Getting Started:
  • Extension Development Guide:

⚙️ Operator/author impact (TL;DR)

  • Extension authors annotate services via @ServiceDescriptor and (optionally) package metadata via @ExtensionDescriptor; avoid public constructors in API.
  • Probe authors inject services, avoid new, and rely on service builders or convenience creators; grant permissions via --grant.

Thanks for reviewing! Feedback on the builder ergonomics, lint defaults, and any docs gaps is welcome. 🙏

@jbachorik jbachorik force-pushed the jb/extensions_1 branch 7 times, most recently from 29bded4 to 4add98d Compare January 6, 2026 18:22
…nstrumentation/tests

Removes legacy permission annotations and extension permission markers.

Adjusts core extension metadata, messages, and dtrace integration.

Updates instrumentation pipeline and verifiers; refreshes related tests and test data.

Touches client/agent entrypoints and messaging; polishes samples and README.

Build tweaks across modules and CI workflow.
Rewrites the guide to use the BTrace Gradle Extension Plugin with a single module and dual source sets (api, impl).

Covers plugin DSL (id/services/shadedPackages/permissions), auto-generated manifest/properties, and shaded impl artifacts.

Removes obsolete two-module setup, manual manifest edits, and ad-hoc shadow config in favor of plugin defaults.

Adds distribution/installation notes for the generated API/Impl artifacts and ZIP.
@jbachorik jbachorik requested a review from Copilot January 7, 2026 10:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request completes the BTrace extensions overhaul by moving from legacy annotation-based permissions to descriptor-based permissions declared in manifests, introducing invokedynamic-based service injection, and providing builder patterns for metrics APIs. It removes legacy service APIs (btrace-services, btrace-services-api, btrace-statsd), tightens verifier constraints (no object construction in probes), and stabilizes CI with proper task dependencies.

Key Changes

  • Descriptor-based permissions: Extensions declare permissions via @ServiceDescriptor on service interfaces and optional @ExtensionDescriptor in package-info.java; the Gradle plugin validates and writes merged permissions to the API JAR manifest.
  • Invokedynamic injection: @Injected fields are linked via invokedynamicExtensionIndyExtensionBridge, enabling on-demand extension loading without polluting the bootstrap classpath.
  • Builder-based metrics API: HistogramConfig is now an interface with HistogramConfigBuilder provided by the service; convenience creators like histogramMicros(name) replace prior constants.

Reviewed changes

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

Show a summary per file
File Description
docs/architecture/extension-storage-design.md New design document outlining extension storage, discovery, and loading mechanisms with directory structure and metadata format.
docs/architecture/extension-manifest-format.md Defines MANIFEST.MF attributes for extension metadata, replacing btrace-extension.properties.
docs/architecture/extension-invokedynamic-bridge.md Comprehensive architecture documentation for the invokedynamic-based extension bridge with classloader hierarchy and execution flow.
docs/architecture/extension-configuration.md Documents extension configuration file format, priority order, and properties for controlling extension loading behavior.
docs/README.md Updates documentation index with new extension architecture references and quick-start links.
docs/QuickReference.md Adds @Injected annotation reference and CLI commands for extensions policy management.
docs/PermissionPolicy.md New document describing simplified per-extension permission policy using allow/deny lists.
docs/GettingStarted.md Adds quick-start guide for using the histogram metrics extension with example probe code.
docs/FAQ.md Adds FAQ entry on extension service injection using @Injected without parameters.
docs/ExtensionInterfaceRules.md New document defining strict rules for extension API interfaces with build-time enforcement and runtime fallback behavior.
docs/BTraceTutorial.md Updates tutorial to reflect descriptor-based permissions, builder patterns, and adds comprehensive histogram metrics extension example.
common.gradle Updates getToolsJar to prefer JDK 8 for better compatibility and enhances javadoc task to include tools.jar when available.
buildSrc/build.gradle Minimal buildSrc configuration file added.
btrace-ui/build.gradle Adds explicit imports for SimpleDateFormat and Date to avoid potential conflicts.
btrace-statsd/src/main/resources/META-INF/services/org.openjdk.btrace.core.extensions.Extension Removes legacy SPI file as statsd extension is removed from main distribution.
btrace-statsd/src/main/java/org/openjdk/btrace/statsd/StatsdExtension.java Removes entire StatsdExtension class (489 lines) as part of legacy services API removal.
btrace-statsd/src/main/java/org/openjdk/btrace/statsd/Statsd.java Removes Statsd service implementation (470 lines) as part of legacy services API removal.
btrace-statsd/src/main/java/org/openjdk/btrace/statsd/QManager.java Removes QManager helper class (122 lines) as part of statsd removal.
btrace-statsd/build.gradle Removes entire build configuration (7 lines) for btrace-statsd module.
btrace-services/src/main/resources/META-INF/services/org.openjdk.btrace.core.extensions.Extension Removes legacy PrinterExtension SPI file.
btrace-services/src/main/java/org/openjdk/btrace/services/impl/PrinterExtension.java Removes PrinterExtension implementation (89 lines).
btrace-services/src/main/java/org/openjdk/btrace/services/impl/Printer.java Removes legacy Printer service (62 lines).
btrace-services/build.gradle Removes btrace-services build configuration (4 lines).
btrace-services-api/src/main/java/org/openjdk/btrace/services/spi/SimpleService.java Removes SimpleService base class (30 lines).
btrace-services-api/src/main/java/org/openjdk/btrace/services/spi/RuntimeService.java Removes RuntimeService base class (38 lines).
btrace-services-api/src/main/java/org/openjdk/btrace/services/api/Service.java Removes Service factory class (74 lines).
btrace-services-api/src/main/java/org/openjdk/btrace/services/api/RuntimeContext.java Removes RuntimeContext interface (9 lines).
btrace-services-api/build.gradle Removes btrace-services-api build configuration (3 lines).
btrace-runtime/src/test/resources/META-INF/btrace/shims.index Adds shim index for test services mapping to noop and throw implementations.
btrace-runtime/src/test/java/test/shim/ShimServiceThrow.java Adds throwing shim implementation for testing optional service fallback.
btrace-runtime/src/test/java/test/shim/ShimServiceNoop.java Adds no-op shim implementation for testing optional service fallback.
btrace-runtime/src/test/java/test/shim/ShimService.java Adds test service interface for shim testing.
btrace-runtime/src/test/java/org/openjdk/btrace/runtime/ExtensionRegistryTest.java Removes ExtensionRegistry test (91 lines) as registry is replaced by manifest-based bridge.
btrace-runtime/src/test/java/org/openjdk/btrace/runtime/ExtensionIndyShimIndexTest.java Adds tests for shim resolution from index in SHIM and THROW modes.
btrace-runtime/src/main/java15/org/openjdk/btrace/runtime/Indy.java Reorders imports for consistency.
btrace-runtime/src/main/java11/org/openjdk/btrace/runtime/BTraceRuntimeImpl_11.java Adds JFR availability check, defensive module export/open operations, and reflective Perf access for JDK 25+ compatibility.
btrace-runtime/src/main/java/org/openjdk/btrace/runtime/ExtensionRegistry.java Removes ExtensionRegistry class (243 lines) replaced by manifest-based loading.
btrace-runtime/src/main/java/org/openjdk/btrace/runtime/ExtensionIndy.java Adds complete invokedynamic bootstrap implementation (311 lines) for extension service field access with shim fallback support.
btrace-runtime/src/main/java/org/openjdk/btrace/runtime/BTraceRuntimeImplBase.java Removes ExtensionRegistry usage, updates imports, adds try-catch for timer initialization, removes getExtension method.
btrace-runtime/src/main/java/org/openjdk/btrace/runtime/BTraceRuntimeAccess.java Removes RuntimeContext interface implementation, adds currentContext() method for invokedynamic bridge, updates method signatures.
btrace-runtime/build.gradle Replaces btrace-services-api and btrace-services dependencies with btrace-extension for all Java version source sets.
btrace-instr/src/test/resources/instrumentorTestData/static/onmethod/leveled/* Updates bytecode golden files with additional frame directives and label adjustments from ASM changes.
btrace-instr/src/test/resources/instrumentorTestData/static/onmethod/* Updates bytecode golden files with frame and label changes.
btrace-instr/src/test/resources/instrumentorTestData/static/issues/* Updates bytecode golden files for issue test cases.
btrace-instr/src/test/resources/instrumentorTestData/static/ServicesTest Replaces legacy service instantiation with invokedynamic-based injection; removes testSimpleService, testRuntimeService, testSingletonService handlers.
btrace-instr/src/test/resources/instrumentorTestData/dynamic/onmethod/leveled/* Updates dynamic instrumentation golden files with frame and label changes.
btrace-instr/src/test/resources/instrumentorTestData/dynamic/onmethod/* Updates dynamic instrumentation golden files.

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.

2 participants