Repository navigation
Conversation
This comment has been minimized.
This comment has been minimized.
🟢 Java Benchmark SLOs — All performance SLOs passed
PR vs. master results
Commit: Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
Existing R2DBC teardown overrides bypass the new checks and leak logging hooks. Spring Boot logging resets also remove the Logback filter, allowing later stack overflows to pass undetected.
🤖 Bits Code Review · Commit 26cceef
| loggedStackOverflow.check(); | ||
| } finally { | ||
| if (loggedStackOverflow != null) { | ||
| loggedStackOverflow.close(); |
There was a problem hiding this comment.
Guarantee logging-hook cleanup when subclasses override tearDown
Existing R2DBC subclasses override tearDown() without calling super, so JUnit skips this base cleanup while inherited init() still installs the logging hooks. Those tests never check captured stack overflows and retain another handler/filter after each invocation. Put hook checking and detachment in dedicated lifecycle callbacks that cannot be bypassed by these overrides, or update all affected subclasses.
React: 👍 useful · 👎 wrong · 😕 unclear · 👀 right, but not acting on it
What each reaction means
- 👍 Useful: correct, and you're fixing it or will.
- 👎 Wrong: the finding is incorrect, for example the bug can't happen or the code was misread.
- 😕 Unclear: you can't tell what it means or why it matters.
- 👀 Right, not acting: correct, but intended, out of scope for this PR, a known risk, or too minor.
🤖 Bits Code Review · Open Bits AI session
| ch.qos.logback.classic.LoggerContext context = (ch.qos.logback.classic.LoggerContext) factory; | ||
| LogbackCapture filter = new LogbackCapture(check); | ||
| filter.start(); | ||
| context.addTurboFilter(filter); |
There was a problem hiding this comment.
Preserve Logback capture across context resets
SpringBootApplicationTest starts Spring applications inside its feature methods, after the harness installs this filter. Spring Boot logging initialization resets LoggerContext, which clears its turbo filters. Subsequent Logback stack overflows therefore escape detection and can still pass cleanup. Add reset-resistant listener handling that reinstalls and restarts the filter, and remove both listener and filter during close.
React: 👍 useful · 👎 wrong · 😕 unclear · 👀 right, but not acting on it
What each reaction means
- 👍 Useful: correct, and you're fixing it or will.
- 👎 Wrong: the finding is incorrect, for example the bug can't happen or the code was misread.
- 😕 Unclear: you can't tell what it means or why it matters.
- 👀 Right, not acting: correct, but intended, out of scope for this PR, a known risk, or too minor.
🤖 Bits Code Review · Open Bits AI session
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 26cceef1d1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ch.qos.logback.classic.LoggerContext context = (ch.qos.logback.classic.LoggerContext) factory; | ||
| LogbackCapture filter = new LogbackCapture(check); | ||
| filter.start(); | ||
| context.addTurboFilter(filter); |
There was a problem hiding this comment.
Preserve capture across Logback context resets
When a test initializes or reconfigures Logback after the base setup() has run, LoggerContext.reset() clears the turbo-filter list, so the filter installed here silently disappears for the remainder of the test. This occurs in instrumentation suites that start an application from inside a feature—for example, SpringBootApplicationTest calls SpringApplication.run(...) after InstrumentationSpecification.setup()—and a subsequently logged StackOverflowError can still pass unnoticed. Make the capture reset-resistant or reinstall it when the context resets.
Useful? React with 👍 / 👎.
|
|
||
| configureLoggingLevels() | ||
|
|
||
| loggedStackOverflow = new LoggedStackOverflowCheck() |
There was a problem hiding this comment.
Start capture before suite fixtures run
Because the capture is created only in per-iteration setup() and closed after every cleanup, setupSpec() and cleanupSpec() execute with no logging hook. Many instrumentation specifications start and stop asynchronous servers, clients, or containers in those suite fixtures; if a framework catches and logs a StackOverflowError from that work without propagating it, the entire suite can still pass. Keep a suite-level capture active across the fixture windows and report any retained error as a suite failure.
Useful? React with 👍 / 👎.
| String format, | ||
| Object[] params, | ||
| Throwable throwable) { | ||
| check.capture(throwable); |
There was a problem hiding this comment.
Ignore Logback events disabled by the effective level
When code passes a StackOverflowError to a disabled Logback call, such as logger.debug("caught", error) while the logger is configured at WARN, this filter still records it and fails the test even though no event is logged. Logback invokes turbo filters before applying the logger's effective-level check, and this filter captures unconditionally before returning NEUTRAL; only capture events that would remain enabled after the neutral decision.
Useful? React with 👍 / 👎.
| firstError.compareAndSet(null, (StackOverflowError) error); | ||
| return; | ||
| } | ||
| error = error.getCause(); |
There was a problem hiding this comment.
Inspect suppressed exceptions for stack overflows
When a framework aggregates failures by attaching the original StackOverflowError as a suppressed exception, the logged wrapper renders that stack overflow but this traversal follows only getCause(), so cleanup does not fail. This is common for multi-failure and resource-cleanup wrappers; traverse a bounded, cycle-safe throwable graph that includes getSuppressed() rather than only the cause chain.
Useful? React with 👍 / 👎.
What Does This Do
Fail Spock and JUnit instrumentation tests when JUL or Logback logs a
StackOverflowErrorduring a test. Report the failure during cleanup with the original error as its cause.Motivation
The Vert.x regression introduced by #13067 logged background stack overflows (fixed in #13128) while its response and trace assertions still passed. Both PR and merge-queue checks accepted those runs.
Make these errors visible as test failures instead of relying on them to cause missing traces or task timeouts.
Additional Notes
As expected, the build fails now. The fix works, though, and now detects the overlooked issue:
Contributor Checklist
type:and (comp:orinst:) labels in addition to any other useful labelsclose,fix, or any linking keywords when referencing an issueUse
solvesinstead, and assign the PR milestone to the issueJira ticket: [PROJ-IDENT]