github pinpoint-apm/pinpoint v3.1.1
3.1.1 release

latest release: latest
4 hours ago

Pinpoint 3.1.1 is a maintenance release of the 3.1.x line. It focuses on agent stability and overhead on reactive and coroutine workloads (Reactor / WebFlux / reactor-netty / Kotlin coroutines), Spring Framework 7 compatibility, and security hardening of the Web and Batch modules. There are no schema changes; collector and web can be upgraded in place from 3.1.0.

Highlights

Agent — Reactor megamorphic-dispatch remediation (JDK 21/25)

Backport of the master track that remediates the JIT megamorphic invokeinterface dispatch observed on reactive applications running on recent JDKs (C2 profile pollution across the generic reactor CoreSubscriber instrumentation).

  • The reactor AsyncContext carrier is unified into a single injected field, so the hot interceptors no longer go through polymorphic accessor lookups.
  • Each interceptor class now gets a generated monomorphic exception-guard wrapper instead of sharing one reflective guard. The code generation is enabled by default:
    # pinpoint.config (local / release profiles)
    profiler.interceptor.exception.guard.codegen=true   # set false to fall back to the 3.1.0 guard
  • The generic reactor CoreSubscriber instrumentation can be switched off for a lightweight mode (profiler.reactor.subscriber.instrument=false, default true). Publisher-seam wrapping and scheduler-task tracing stay behind config gates that are off by default (profiler.reactor.trace.scheduler.task, profiler.reactor.trace.scheduler.task.periodic).
  • DefaultAsyncTraceContext / DefaultRecorderFactory no longer call the Guice Provider.get() chain on every trace request; the singleton factories are injected or memoized (#14210).

Agent — "Corrupted call stack" storms fixed and throttled

Three layers address the Corrupted call stack found ... call stack is empty log floods (and the CPU spikes that came with them) reported on reactor-netty / WebFlux services:

  • DefaultCallStack.peek() returns the disabled instance while overflowed frames are outstanding, instead of null, so a transaction that exceeds profiler.callstack.max.sequence no longer logs a stack dump per span event (#14310).
  • OnErrorSubscriberInterceptor (onErrorResume / onErrorReturn / onErrorMap / onErrorComplete) carries its TraceBlock from before() to after() instead of looking the AsyncContext up twice, which closed a frame nobody opened on every failing WebClient response (#14319).
  • The corrupted-call-stack WARN and stack dump are throttled to one per 3 s per trace type; suppressed dumps are counted and reported on the next emitted one, and skip the exception construction entirely.

Agent — Kotlin coroutines

ResumeWithInterceptor keeps the span event opened in before() and closes exactly that one in after(), so a nested Reactor callback swapping the current trace during BaseContinuationImpl.resumeWith(...) no longer leaves unbalanced blocks (previously surfacing as corrupted call stacks on the parent ChildTrace).

Agent — Spring Framework 7 compatibility

  • WebFlux and RestTemplate header adaptors no longer throw NoSuchMethodError on Spring Framework 7, where HttpHeaders stopped implementing MultiValueMap (#14278).
  • The RestTemplate plugin matches the new RestTemplate(Iterable<HttpMessageConverter<?>>) constructor, so RestTemplates built by Spring Boot 4 / Framework 7 are traced again.

Agent — Plugin fixes

  • Redisson: reactive command tracing works on Redisson 3.17+ and 3.19+ (ReactiveProxyBuilder callback signature changes); it had been silently inactive on modern versions.
  • reactor-netty / netty HTTP client: HttpClientRequestWrapper.toRemoteHost() and HttpClientHandlerRequestWithBodyInterceptor no longer cast a non-inet remote address (e.g. Unix domain sockets) to InetSocketAddress, which threw ClassCastException inside the interceptor.
  • Duplicate accessor member injection is skipped in ASMClass (#13962).
  • StringUtils.abbreviate no longer splits UTF-16 surrogate pairs (#14021).
  • Empty PAnnotationValue is returned for NullAnnotation instead of an NPE (#14154).
  • ExceptionChainSampler no longer fails on a non-positive throughput setting.
  • Removed the unused interceptor registry setting and bootstrap-interceptor jar references (#14008).

Web / Batch — Security hardening

  • Webhook SSRF validation (#13857): webhook URLs are resolved and validated before sending; URLs that resolve to loopback, link-local, multicast, or private ranges (10/8, 172.16/12, 192.168/16, 100.64/10, ...) are rejected. The webhook payload no longer includes the user group. See Upgrade notes.
  • Basic login (#13858, #14103): the JWT cookie is HttpOnly with configurable Secure / SameSite, the authentication recursion is fixed, and the JWT secret key is now required when basic login is enabled. See Upgrade notes.
  • NUL bytes are rejected in null-terminated buffer values (collector-side decoding).
  • gRPC mappers no longer cache protobuf builders in interface fields (shared across mapper instances and threads).

Upgrade notes

Agent

  • Default pinpoint.modules.uid.version is now v3 (254-character ApplicationName support, #13715). This matches the 3.1.0 collector/web. If the agent reports to a collector older than 3.1.0, set it back explicitly:
    pinpoint.modules.uid.version=v1
  • profiler.interceptor.exception.guard.codegen=true is the new default. Set it to false to restore the 3.1.0 behavior (a JVM restart is required).
  • profiler.interceptorregistry.size has been removed from pinpoint-root.config (no longer used).

Web

  • If pinpoint.modules.web.login=basicLogin, the web fails to start unless the JWT secret is configured:
    web.security.auth.jwt.secretkey=<generate-a-random-secret>
    # optional cookie attributes (defaults shown)
    #web.security.auth.jwt.cookie.http-only=true
    #web.security.auth.jwt.cookie.secure=false
    #web.security.auth.jwt.cookie.same-site=Lax
  • Webhooks targeting private network addresses are rejected in this version. If your alarm webhooks resolve into 10/8, 172.16/12 or 192.168/16, keep them on 3.1.0 or route them through a publicly resolvable host; a configurable host allowlist is available on master and planned for a later release.

Build

  • Minimum required Maven version is 3.7 (the bundled mvnw is unaffected).

Compatibility

Component Minimum Notes
Agent JDK 8+ verified on 8 / 11 / 17 / 21 / 25
Collector / Web / Batch JDK 17+
Collector for agent 3.1.1 3.1.0+ with the default uid.version=v3; see Upgrade notes for older collectors
HBase schema unchanged from 3.1.0

Downloads

Binaries are attached to this release:

What's Changed

  • [#13693] Prepare 3.1.1-SNAPSHOT by @intr3p1d in #13711
  • [#13715] Backport : Change default NameVersion to v3 by @emeroad in #13718
  • [#noissue] Move maven-compiler-plugin version to pluginManagement by @emeroad in #13725
  • [#noissue] Bump minimum required Maven version to 3.7 by @emeroad in #13731
  • [#noissue] Move maven-surefire-plugin version to pluginManagement by @emeroad in #13730
  • [#noissue] Move maven-resources/javadoc-plugin versions to pluginManagement by @emeroad in #13733
  • [#noissue] Update CI workflow triggers to 3.1.x branch by @emeroad in #13732
  • [#noissue] Update README.md by @intr3p1d in #13741
  • [#noissue] Remove unused maven-surefire-plugin configuration by @emeroad in #13802
  • [#noissue] Backport: Reject NUL bytes in null-terminated buffer values by @donghun-cho in #13859
  • [#13857] Backport: Add SSRF validation and update webhook payload structure by @ga-ram in #13889
  • [#13858] Backport: Secure basic login JWT cookie and fix authentication recursion by @ga-ram in #13890
  • [#13858] Backport: Disable basic login secure cookie by default by @ga-ram in #13892
  • [#13962] Backport: Skip duplicate accessor member injection in ASMClass by @jaehong-kim in #13963
  • [#14008] Backport: Remove interceptor registry settings and bootstrap-interceptor jar references by @jaehong-kim in #14010
  • [#14021] Backport: Keep StringUtils.abbreviate from splitting surrogate pairs by @jaehong-kim in #14022
  • [#noissue] Backport: Reactor megamorphic-dispatch remediation track from master by @jaehong-kim in #14148
  • [#noissue] Backport: Fix ExceptionChainSampler failing on non-positive throughput by @donghun-cho in #14149
  • [#noissue] 3.1.1-alpha1 release by @jaehong-kim in #14153
  • [#noissue] Ignore git mergetool temp files by @emeroad in #14156
  • [#noissue] Prepare 3.1.1-SNAPSHOT by @jaehong-kim in #14155
  • [#14154] Backport : Return empty PAnnotationValue for NullAnnotation to prevent NPE by @emeroad in #14157
  • [#14103] Backport: Require jwt secret key for basic login by @ga-ram in #14161
  • [#noissue] Remove cached protobuf builders from grpc mappers by @emeroad in #14160
  • [#14278] Backport: Fix NoSuchMethodError in the WebFlux and RestTemplate header adaptors on Spring Framework 7 by @jaehong-kim in #14279
  • [#14310] Backport: Return the disabled instance from DefaultCallStack.peek() while overflowed frames are outstanding by @jaehong-kim in #14312
  • [#14319] Backport: Carry the TraceBlock through OnErrorSubscriberInterceptor instead of looking the AsyncContext up twice by @jaehong-kim in #14321
  • [#noissue] Backport: Throttle the corrupted call stack dumps of DefaultTrace and ChildTrace by @jaehong-kim in #14337
  • [#noissue] Backport: Keep coroutine resume trace blocks balanced by @jaehong-kim in #14339
  • [#noissue] Backport: Support the Iterable-based RestTemplate constructor of Spring Framework 7 by @jaehong-kim in #14342
  • [#noissue] Backport: Fix redisson reactive command tracing for redisson 3.17+ by @jaehong-kim in #14343
  • [#noissue] Backport: Avoid casting non-inet remote addresses in HttpClientHandlerRequestWithBodyInterceptor by @jaehong-kim in #14344
  • [#noissue] Backport: Avoid casting non-inet remote addresses in HttpClientRequestWrapper by @jaehong-kim in #14347
  • [#14210] Backport: Cache the singletons behind the Guice Providers on the trace request path by @jaehong-kim in #14378
  • [#14381] 3.1.1 release by @jaehong-kim in #14382

Full Changelog: v3.1.0...v3.1.1

Don't miss a new pinpoint release

NewReleases is sending notifications on new releases.