Skip to content

perf: Replace java.net.URI with custom string parsing in Dsn#5448

Open
runningcode wants to merge 6 commits into
mainfrom
no/custom-dsn-parser
Open

perf: Replace java.net.URI with custom string parsing in Dsn#5448
runningcode wants to merge 6 commits into
mainfrom
no/custom-dsn-parser

Conversation

@runningcode
Copy link
Copy Markdown
Contributor

@runningcode runningcode commented May 19, 2026

Summary

Replaces java.net.URI parsing in the Dsn constructor with lightweight manual
string parsing, and hardens and tests the parser. This is a critical startup path performance improvement.

Here are perfetto traces of the retrieveParsedDsn() method as measured on a Pixel 3. I've repeated the measurement several times and I always get an order of magnitude difference.

This is on master:
image
This is on this branch:
image

What changed

  • Parsing: Replace new URI(dsnString).normalize() with manual
    indexOf/substring parsing, avoiding the java.net.URI string parser.
    retrieveParsedDsn() runs on the main thread during Sentry.init(), so this
    keeps a known-slow API off the init path. The only remaining URI use is
    constructing the endpoint from already-parsed components
    (new URI(scheme, null, host, port, path, null, null)), which does not
    re-parse a string.
  • Correctness: Strip URI fragments (#…) alongside query strings so they no
    longer leak into the project id, and support bracketed IPv6 literal hosts
    (e.g. https://key@[::1]:9000/1) — both behaviors the old URI parser handled.

JAVA-532

Relates to: https://linear.app/getsentry/issue/JAVA-532
Also relates to: https://linear.app/getsentry/issue/JAVA-516/move-dsn-parsing-off-the-main-thread-during-init

🤖 Generated with Claude Code

@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 19, 2026

JAVA-516

JAVA-532

@sentry
Copy link
Copy Markdown

sentry Bot commented May 19, 2026

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.43.1 (1) release

⚙️ sentry-android Build Distribution Settings

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 287.89 ms 353.78 ms 65.89 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
62b579c 312.88 ms 361.57 ms 48.70 ms
d501a7e 307.33 ms 341.94 ms 34.61 ms
2195398 345.88 ms 411.71 ms 65.82 ms
cf708bd 434.73 ms 502.96 ms 68.22 ms
27d7cf8 397.90 ms 498.65 ms 100.75 ms
85d7417 347.21 ms 394.35 ms 47.15 ms
5dee26b 315.44 ms 367.25 ms 51.81 ms
4c04bb8 307.93 ms 362.34 ms 54.41 ms
5b1a06b 310.56 ms 362.79 ms 52.22 ms
f634d01 359.58 ms 433.88 ms 74.30 ms

App size

Revision Plain With Sentry Diff
62b579c 0 B 0 B 0 B
d501a7e 0 B 0 B 0 B
2195398 0 B 0 B 0 B
cf708bd 1.58 MiB 2.11 MiB 539.71 KiB
27d7cf8 1.58 MiB 2.12 MiB 549.42 KiB
85d7417 1.58 MiB 2.10 MiB 533.44 KiB
5dee26b 0 B 0 B 0 B
4c04bb8 0 B 0 B 0 B
5b1a06b 0 B 0 B 0 B
f634d01 1.58 MiB 2.10 MiB 533.40 KiB

Previous results on branch: no/custom-dsn-parser

Startup times

Revision Plain With Sentry Diff
85d9e31 323.66 ms 391.76 ms 68.10 ms
51a27f4 318.65 ms 361.66 ms 43.01 ms
96d1d4a 354.34 ms 443.40 ms 89.06 ms

App size

Revision Plain With Sentry Diff
85d9e31 0 B 0 B 0 B
51a27f4 0 B 0 B 0 B
96d1d4a 0 B 0 B 0 B

Copy link
Copy Markdown

@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.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit cacc249. Configure here.

Comment thread sentry/src/main/java/io/sentry/Dsn.java Outdated
Comment thread sentry/src/main/java/io/sentry/Dsn.java Outdated
Copy link
Copy Markdown
Member

@0xadam-brown 0xadam-brown left a comment

Choose a reason for hiding this comment

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

A few optionals; otherwise lgtm

Comment thread sentry/src/main/java/io/sentry/Dsn.java Outdated
Comment thread sentry/src/main/java/io/sentry/Dsn.java Outdated
Comment thread sentry/src/main/java/io/sentry/Dsn.java Outdated
Comment thread sentry/src/test/java/io/sentry/DsnTest.kt Outdated
@runningcode runningcode changed the title perf: Replace java.net.URI with custom string parsing in Dsn [DNM] [Don't review] perf: Replace java.net.URI with custom string parsing in Dsn May 28, 2026
runningcode and others added 4 commits June 4, 2026 15:43
The Dsn constructor used `new URI(dsnString).normalize()` to parse the
DSN string, which is known to be slow on Android. Since `retrieveParsedDsn()`
is called on the main thread during `Sentry.init()` via
`preInitConfigurations()`, this directly impacts app startup time.

Replace the URI-based parsing with manual indexOf/substring operations.
The only remaining URI construction is from pre-parsed components
(`new URI(scheme, null, host, port, path, null, null)`), which is
significantly cheaper since the JDK doesn't need to re-parse a string.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cover edge cases specific to the manual indexOf/substring parser:
null input, missing scheme separator, no slash after host, multiple
path segments, port with path, multiple double slashes, query string
with port, empty secret key, and a realistic Sentry DSN with org id.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Harden the custom DSN parser and convert its tests to Google Truth.

- Strip URI fragments (#...) alongside query strings so they no longer
  leak into the project id and corrupt the constructed Sentry URI.
- Detect bracketed IPv6 literal hosts when locating the port separator,
  restoring behavior that java.net.URI handled.
- Narrow the parse error handling from catch (Throwable) to the
  expected exceptions, which stops swallowing Error and removes the
  doubled exception message.
- Extract the parsing steps into focused private helpers.
- Convert DsnTest to Google Truth assertions.
- Move the changelog entry to the Unreleased section, since 8.43.0 and
  8.43.1 have already been released.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@runningcode runningcode force-pushed the no/custom-dsn-parser branch from cacc249 to 4851e6d Compare June 4, 2026 14:07
Follow Truth's recommended pattern for exception testing: catch with
assertFailsWith, then assert on the caught throwable with
assertThat(ex).hasMessageThat(). Also assert the message in the
previously bare throw-only cases so they can no longer pass on an
unrelated exception.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread sentry/src/main/java/io/sentry/Dsn.java
@runningcode runningcode changed the title [DNM] [Don't review] perf: Replace java.net.URI with custom string parsing in Dsn perf: Replace java.net.URI with custom string parsing in Dsn Jun 4, 2026
Parse the port in a dedicated helper that reports the offending value
("Invalid DSN: Invalid port 'abc'.") instead of leaking the raw
NumberFormatException text. Narrow the catch to URISyntaxException now
that the port is the only parseInt, and add a test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@0xadam-brown 0xadam-brown left a comment

Choose a reason for hiding this comment

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

Thanks for the updates – lgtm 👍

Comment thread gradle/libs.versions.toml
camerax-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "camerax" }
camerax-view = { module = "androidx.camera:camera-view", version.ref = "camerax" }

google-truth = { module = "com.google.truth:truth", version = "1.4.5" }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

l: No strong opinions about introducing a new assertion library for tests + it's helpful for verifying error msgs, so I'm okay with this even though we'll only have a few tests using Truth.

Anyone else can feel free to chime in if they think otherwise...

Comment thread sentry/src/main/java/io/sentry/Dsn.java Outdated
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.

2 participants