docs/ExtensionInterfaceRules.md
This page defines the rules for authoring BTrace extension APIs (interfaces), the build-time checks enforced by the Gradle plugin, and how optional services use shims or throwing stubs at runtime.
src/api/java. Implementations live under src/impl/java and are shaded/packaged into the implementation JAR.@Injected(optional = true) and select the fallback mode:
SHIM (production): a no‑op object that implements the interface and returns defaults.THROW (development): an object that throws on any method call with a clear error.@Injected(mode = SHIM|THROW), or globally with -Dbtrace.extension.shimMode=shim|throw (default: throw).java.io, java.net, java.nio.channels, or java.lang.reflect types in signatures.throws clauses.public static final constants are allowed on interfaces.javax.annotation.{Nullable, Nonnull}, org.jspecify.annotations.{Nullable, NonNull}, org.jetbrains.annotations.{Nullable, NotNull}, jakarta.annotation.{Nullable, Nonnull}.@Nullable to ensure the no‑op shim can safely return null.void methods do nothing.@ServiceDescriptor(permissions = { ... }), or rely on plugin scanning.The org.openjdk.btrace.extension Gradle plugin runs validation on the API services you declare in btraceExtension.services. It fails the build with clear error IDs.
Enforced checks (subset shown):
BTRACE-EXT-001: Service must be a public, top‑level interface.BTRACE-EXT-002: Default/private interface methods not allowed (Java 8/shim compatibility).BTRACE-EXT-003: Interface declares non‑constant fields.BTRACE-EXT-010: Method declares checked exceptions.BTRACE-EXT-013: Method uses forbidden signature type (io/net/channels/reflect).BTRACE-EXT-020: Missing nullability on method return.BTRACE-EXT-021: Missing nullability on a parameter.BTRACE-EXT-022: Method returns an interface but is not annotated @Nullable (shimability).BTRACE-EXT-040: API signature references an implementation class (API purity).BTRACE-EXT-032: API annotates required permissions but plugin configuration does not provide them and permission scanning is disabled (enable scanning or declare explicitly).Apply the plugin in your extension project and declare services:
plugins {
id 'org.openjdk.btrace.extension'
id 'com.github.johnrengelman.shadow'
}
btraceExtension {
id = 'btrace-metrics'
name = 'BTrace Metrics (HDR)'
description = 'HDR Histogram based metrics'
services = ['org.openjdk.btrace.metrics.MetricsService']
// Optional: configure nullability annotations if you use different ones
nullableAnnotations = ['com.acme.NonRequired']
nonnullAnnotations = ['com.acme.Required']
}
Build tasks wired by the plugin:
validateServiceApis runs during check and fails on violations.generateServiceShims and generateShimIndex produce shim classes and an index bundled into the API JAR.packageExtension produces *-extension.zip including API and implementation JARs.During the API JAR build, the plugin logs the permissions written to the manifest:
[BTRACE-EXT] permissions: scanned=[THREADS, REFLECTION] merged=[THREADS, REFLECTION]
@Injected(optional = true).@Injected(optional = true, mode = SHIM) or THROW.-Dbtrace.extension.shimMode=shim|throw (default: throw).optional = false) never fall back and fail fast if unavailable.Compliant interface:
package org.openjdk.btrace.metrics;
import org.openjdk.btrace.core.extensions.Permission;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ServiceDescriptor(permissions = { Permission.THREADS })
public interface MetricsService {
void inc(@Nonnull String name);
@Nullable Meter meter(@Nonnull String name);
}
Violations (examples):
java.io.File (BTRACE-EXT-013)impl.InternalMeter (BTRACE-EXT-040)For deeper background on extension loading, permission enforcement, and injection, see: docs/BTraceExtensionDevelopmentGuide.md and docs/architecture/ExtensionInvokeDynamicBridge.md.
This section maps validation errors to concrete fixes you can apply.
scanPermissions = true in the plugin or add the missing permissions to requiredPermissions.@ServiceDescriptor.permissions and package-level @ExtensionDescriptor.permissions.src/impl/java from API signatures and annotations.src/api/java and list it in btraceExtension.services.--stacktrace. If reproducible, file an issue with the API source and the generated class.