|
| 1 | +--- |
| 2 | +alwaysApply: false |
| 3 | +description: Public API surface, binary compatibility, and common classes to modify |
| 4 | +--- |
| 5 | +# Java SDK Public API |
| 6 | + |
| 7 | +## API Compatibility |
| 8 | + |
| 9 | +Public API is tracked via `.api` files generated by the [Binary Compatibility Validator](https://github.com/Kotlin/binary-compatibility-validator) Gradle plugin. Each module has its own file at `<module>/api/<module>.api`. |
| 10 | + |
| 11 | +- **Never edit `.api` files manually.** Run `./gradlew apiDump` to regenerate them. |
| 12 | +- `./gradlew check` validates current code against `.api` files and fails on unintended changes. |
| 13 | +- `@ApiStatus.Internal` marks classes/methods as internal — they still appear in `.api` files but are not part of the public contract. |
| 14 | +- `@ApiStatus.Experimental` marks API that may change in future versions. |
| 15 | + |
| 16 | +## Key Public API Classes |
| 17 | + |
| 18 | +### Entry Point |
| 19 | + |
| 20 | +`Sentry` (`sentry` module) is the static entry point. Most public API methods on `Sentry` delegate to `getCurrentScopes()`. When adding a new method to `Sentry`, it typically calls through to `IScopes`. |
| 21 | + |
| 22 | +### Interfaces |
| 23 | + |
| 24 | +| Interface | Description | |
| 25 | +|-----------|-------------| |
| 26 | +| `IScope` | Single scope — holds data (tags, extras, breadcrumbs, attributes, user, contexts, etc.) | |
| 27 | +| `IScopes` | Multi-scope container — manages global, isolation, and current scope; delegates capture calls to `SentryClient` | |
| 28 | +| `ISpan` | Performance span — timing, tags, data, measurements | |
| 29 | +| `ITransaction` | Top-level transaction — extends `ISpan` | |
| 30 | + |
| 31 | +### Configuration |
| 32 | + |
| 33 | +`SentryOptions` is the base configuration class. Platform-specific subclasses: |
| 34 | +- `SentryAndroidOptions` — Android-specific options |
| 35 | +- Integration modules may add their own (e.g. `SentrySpringProperties`) |
| 36 | + |
| 37 | +New features must be **opt-in by default** — add a getter/setter pair to the appropriate options class. |
| 38 | + |
| 39 | +### Internal Classes (Not Public API) |
| 40 | + |
| 41 | +| Class | Description | |
| 42 | +|-------|-------------| |
| 43 | +| `SentryClient` | Sends events/envelopes to Sentry — receives captured data from `Scopes` | |
| 44 | +| `SentryEnvelope` / `SentryEnvelopeItem` | Low-level envelope serialization | |
| 45 | +| `Scope` | Concrete implementation of `IScope` | |
| 46 | +| `Scopes` | Concrete implementation of `IScopes` | |
| 47 | + |
| 48 | +## Adding New Public API |
| 49 | + |
| 50 | +When adding a new method that users can call (e.g. a new scope operation), these classes typically need changes: |
| 51 | + |
| 52 | +### Interfaces and Static API |
| 53 | +1. `IScope` — add the method signature |
| 54 | +2. `IScopes` — add the method signature (usually delegates to a scope) |
| 55 | +3. `Sentry` — add static method that calls `getCurrentScopes()` |
| 56 | + |
| 57 | +### Implementations |
| 58 | +4. `Scope` — actual implementation with data storage |
| 59 | +5. `Scopes` — delegates to the appropriate scope (global, isolation, or current based on `defaultScopeType`) |
| 60 | +6. `CombinedScopeView` — defines how the three scope types combine for reads (merge, first-wins, or specific scope) |
| 61 | + |
| 62 | +### No-Op and Adapter Classes |
| 63 | +7. `NoOpScope` — no-op stub for `IScope` |
| 64 | +8. `NoOpScopes` — no-op stub for `IScopes` |
| 65 | +9. `ScopesAdapter` — delegates to `Sentry` static API |
| 66 | +10. `HubAdapter` — deprecated bridge from old `IHub` API |
| 67 | +11. `HubScopesWrapper` — wraps `IScopes` as `IHub` |
| 68 | + |
| 69 | +### Serialization (if the data is sent to Sentry) |
| 70 | +12. Add serialization/deserialization in the relevant data class or create a new one implementing `JsonSerializable` and `JsonDeserializer` |
| 71 | + |
| 72 | +### Tests |
| 73 | +13. Write tests for all implementations, especially `Scope`, `Scopes`, `SentryTest`, and any new data classes |
| 74 | +14. No-op classes typically don't need separate tests unless they have non-trivial logic |
| 75 | + |
| 76 | +## Protocol / Data Model Classes |
| 77 | + |
| 78 | +Classes in the `io.sentry.protocol` package represent the Sentry event protocol. They implement `JsonSerializable` for serialization and have a companion `Deserializer` class implementing `JsonDeserializer`. When adding new fields to protocol classes, update both serialization and deserialization. |
| 79 | + |
| 80 | +## Namespaced APIs |
| 81 | + |
| 82 | +Newer features are namespaced under `Sentry.<feature>()` rather than added directly to `Sentry`. Each namespaced API has an interface, implementation, and no-op. Examples: |
| 83 | + |
| 84 | +- `Sentry.logger()` → `ILoggerApi` / `LoggerApi` / `NoOpLoggerApi` (structured logging, `io.sentry.logger` package) |
| 85 | +- `Sentry.metrics()` → `IMetricsApi` / `MetricsApi` / `NoOpMetricsApi` (metrics) |
| 86 | + |
| 87 | +Options for namespaced features are similarly nested under `SentryOptions`, e.g. `SentryOptions.getMetrics()`, `SentryOptions.getLogs()`. |
| 88 | + |
| 89 | +These APIs may share infrastructure like the type system (`SentryAttributeType.inferFrom()`) — changes to shared components (e.g. attribute types) may require updates across multiple namespaced APIs. |
0 commit comments