Skip to content

feat(spring-jakarta): [Cache Tracing 9] Port cache tracing to Spring Boot 3 + samples#5190

Draft
adinauer wants to merge 2 commits intofeat/cache-tracing-retrievefrom
feat/cache-tracing-spring-boot-3
Draft

feat(spring-jakarta): [Cache Tracing 9] Port cache tracing to Spring Boot 3 + samples#5190
adinauer wants to merge 2 commits intofeat/cache-tracing-retrievefrom
feat/cache-tracing-spring-boot-3

Conversation

@adinauer
Copy link
Member

@adinauer adinauer commented Mar 13, 2026

PR Stack (Cache Tracing)

  • #5172 — Add SentryCacheWrapper and SentryCacheManagerWrapper
  • #5173 — Add enableCacheTracing option
  • #5174 — Add BeanPostProcessor and auto-configuration
  • #5175 — Add cache tracing e2e sample
  • #5179 — Add SentryJCacheWrapper for JCache (JSR-107)
  • #5182 — Add JCache console sample
  • #5183 — Add cache tracing to all Spring Boot 4 samples
  • #5184 — Add retrieve() overrides for reactive/async cache support
  • #5190 — Port cache tracing to Spring Boot 3 Jakarta + samples
  • #5191 — Port cache tracing to Spring Boot 2 + samples

📜 Description

Port cache tracing classes from sentry-spring-7 to sentry-spring-jakarta (Spring Boot 3 / Spring Framework 6), including:

  • SentryCacheWrapper, SentryCacheManagerWrapper, SentryCacheBeanPostProcessor in io.sentry.spring.jakarta.cache
  • Auto-configuration wiring in sentry-spring-boot-jakarta's SentryAutoConfiguration
  • Both retrieve() overrides for reactive/async cache operations (safe on Spring 6.0 as dead code)
  • Full unit test coverage

Also adds cache tracing samples and e2e tests to all 4 Spring Boot 3 sample modules:

  • sentry-samples-spring-boot-jakarta
  • sentry-samples-spring-boot-jakarta-opentelemetry
  • sentry-samples-spring-boot-jakarta-opentelemetry-noagent
  • sentry-samples-spring-boot-webflux-jakarta

Each sample includes CacheController, TodoService with @Cacheable/@CachePut/@CacheEvict, Caffeine config, and CacheSystemTest.

💡 Motivation and Context

Spring Boot 3 is still the majority of production users. Without this port, cache tracing would only be available on Spring Boot 4.

💚 How did you test it?

  • Unit tests pass: ./gradlew :sentry-spring-jakarta:test --tests="io.sentry.spring.jakarta.cache.*"
  • All 4 samples compile successfully
  • Code formatted with spotlessApply, API dump regenerated

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

None — this completes the Spring Boot 3 port for cache tracing.

⚠️ Merge this PR using a merge commit (not squash). Only the collection branch is squash-merged into main.

#skip-changelog

adinauer and others added 2 commits March 13, 2026 07:03
Port cache tracing classes from sentry-spring-7 to sentry-spring-jakarta,
covering Spring Boot 3 (Spring Framework 6.x) users. Includes
SentryCacheWrapper, SentryCacheManagerWrapper, SentryCacheBeanPostProcessor,
and auto-configuration in sentry-spring-boot-jakarta.

The retrieve() overrides for CompletableFuture/reactive cache operations
are included and safe on Spring 6.0 (where retrieve() doesn't exist on
the Cache interface) — they're simply dead code, never called by the
framework until Spring 6.1+.

Co-Authored-By: Claude <noreply@anthropic.com>
Add CacheController, TodoService with @Cacheable/@CachePut/@CacheEvict,
Caffeine cache config, and CacheSystemTest e2e tests to all four Jakarta
sample modules:
- sentry-samples-spring-boot-jakarta
- sentry-samples-spring-boot-jakarta-opentelemetry
- sentry-samples-spring-boot-jakarta-opentelemetry-noagent
- sentry-samples-spring-boot-webflux-jakarta

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 13, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


This PR will not appear in the changelog.


🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 13, 2026

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 658e082

@sentry
Copy link

sentry bot commented Mar 13, 2026

Sentry Build Distribution

App Name App ID Version Configuration Install Page
SDK Size io.sentry.tests.size 8.34.1 (1) release Install Build

@github-actions
Copy link
Contributor

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 312.89 ms 370.83 ms 57.94 ms
Size 0 B 0 B 0 B

Baseline results on branch: feat/cache-tracing-retrieve

Startup times

Revision Plain With Sentry Diff
73fac85 366.36 ms 466.94 ms 100.58 ms

App size

Revision Plain With Sentry Diff
73fac85 0 B 0 B 0 B

@adinauer
Copy link
Member Author

@sentry review

@adinauer
Copy link
Member Author

cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Comment on lines +166 to +167
return result.whenComplete(
(value, throwable) -> {
Copy link

Choose a reason for hiding this comment

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

Bug: The retrieve(key, valueLoader) method in SentryCacheWrapper does not handle null returns from the delegate, leading to a NullPointerException when .whenComplete() is called.
Severity: HIGH

Suggested Fix

Add a null check for the result variable after the call to delegate.retrieve(key, valueLoader). If result is null, it should be handled gracefully, similar to how the retrieve(Object key) overload handles nulls, to prevent the NullPointerException.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location:
sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/cache/SentryCacheWrapper.java#L166-L167

Potential issue: In `SentryCacheWrapper`, the `retrieve(Object key,
Supplier<CompletableFuture<T>> valueLoader)` method calls `delegate.retrieve(key,
valueLoader)` but does not check if the result is `null` before calling
`.whenComplete()` on it. According to Spring Cache documentation, the `retrieve` method
can return `null` to signal an immediate cache miss. In such cases, the current
implementation will throw a `NullPointerException`, causing a runtime crash and
potentially leaving a Sentry span unfinished. This affects applications using reactive
`@Cacheable` methods with a cache implementation that can return `null` from this
method.

Did we get this right? 👍 / 👎 to inform future reviews.

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.

1 participant