ref(time): Deprecate the legacy date and clock providers (JAVA-571) - #6043
Draft
runningcode wants to merge 4 commits into
Draft
ref(time): Deprecate the legacy date and clock providers (JAVA-571)#6043runningcode wants to merge 4 commits into
runningcode wants to merge 4 commits into
Conversation
This was referenced Sep 2, 2026
📲 Install BuildsAndroid
|
9 tasks
runningcode
force-pushed
the
no/java-579-anr-uptime-clock
branch
from
September 2, 2026 13:35
cabb812 to
77eb8c9
Compare
runningcode
force-pushed
the
no/java-571-deprecate-date-providers
branch
from
September 2, 2026 13:35
74323cd to
4f8f1ff
Compare
It reads the wall clock into a java.util.Date at millisecond resolution. SentryDateProvider already owns wall time, is configurable, stubbable in tests and resolves finer, so there is no reason for new code to reach for the static. The class itself is not deprecated: its other fourteen statics are pure conversion and formatting helpers with no clock in them. Every caller keeps working and gets a suppression, because -Xlint:all -Werror turns the warning into a build failure. Each suppression carries a TODO [MAJOR] naming the replacement, since a suppressed warning is no longer a checklist entry — and nearly all of these callers are frozen until the next major anyway, as they stamp serialized timestamps.
One interface carried two incompatible clocks: CurrentDateProvider is System.currentTimeMillis() and AndroidCurrentDateProvider is SystemClock.uptimeMillis(). Nothing in the name or the type said which, which is the defect JAVA-571 is about — a field declared ICurrentDateProvider accepts either, and the two disagree by however long the device has been suspended. UptimeClock and ElapsedRealtimeClock name the guarantee, and SentryDateProvider covers wall time. The annotation goes on the members rather than the types: the Android modules compile at Java 8, where javac still warns on imports of a deprecated type, and an import declaration cannot carry a @SuppressWarnings. Deprecating getCurrentTimeMillis() and getInstance() warns any caller just the same, and every warning it produces lands somewhere that can be suppressed. Each suppression names the replacement the site should take at the next major. Several of these must stay on the wall clock: AnrV2Integration, TombstoneIntegration and ApplicationExitInfoHistoryDispatcher compare against epoch ApplicationExitInfo timestamps, and LifecycleWatcher against Session.getStarted().
…VA-571) Its own javadoc already told callers to prefer options.getDateProvider(); this makes the compiler say so. The static holder cannot be configured or stubbed, which is the whole reason the note was there. Annotated on the method rather than the class, for the same import reason as the current-date providers.
runningcode
force-pushed
the
no/java-571-deprecate-date-providers
branch
from
September 2, 2026 13:37
4f8f1ff to
d35ab7c
Compare
runningcode
force-pushed
the
no/java-579-anr-uptime-clock
branch
from
September 2, 2026 13:37
77eb8c9 to
2065803
Compare
9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Stack (Clock semantics hardening)
📜 Description
Marks the legacy date and clock surface as deprecated, now that the internal consumers that could
move have moved (#6029, #6030, #6032, #6041). Nothing is migrated here and nothing is removed — the
point is to start the warning cycle before the next major, so users and the
9.x.xbranch get afull release of notice.
ICurrentDateProvider.getCurrentTimeMillis()UptimeClock/ElapsedRealtimeClock, whichever the site actually meantCurrentDateProvider.getInstance()SentryDateProviderfor a timestamp,ElapsedRealtimeClockfor an intervalAndroidCurrentDateProvider.getInstance()UptimeClock(this one wasSystemClock.uptimeMillis()all along)DateUtils.getCurrentDateTime()options.getDateProvider().now()AndroidDateUtils.getCurrentSentryDateTime()options.getDateProvider()The
DateUtilsclass is deliberately not deprecated: onlygetCurrentDateTime()reads a clock,while its other fourteen statics are pure conversion and formatting helpers used all over the SDK.
Two deviations from the plan, both forced
1. The annotations sit on members, not on the types. The plan called for deprecating
ICurrentDateProvider,CurrentDateProviderandAndroidCurrentDateProvideras types. That cannotcompile here: the Android modules build at Java 8, where javac still emits a deprecation warning for
an
importof a deprecated type (JEP 211 elides those only from source 9 on),-Xlint:all -Werrorturns it into an error, and an import declaration cannot carry a
@SuppressWarnings— a class-levelsuppression does not cover it either. I verified both halves of that empirically. Thirteen Java files
in
sentry-android-coreimport these types; the alternative was writingio.sentry.transport.ICurrentDateProviderinline at ~40 use sites until the next major.Deprecating
getCurrentTimeMillis()andgetInstance()warns any caller just as loudly, and everywarning it produces lands somewhere a suppression can go. The type-level javadoc still names the
replacement, so IDEs and Javadoc readers see it.
2. Kotlin call sites are left warning, not suppressed.
-Werrorapplies toJavaCompileonly,so the 17 warnings in
sentry-android-replayandsentry-okhttpdo not break anything. They are thelive migration list for JAVA-575; suppressing them would trade a checklist for a comment. That module
already carries other deprecation warnings, so this is not a new kind of noise. Say the word if you'd
rather have them suppressed.
💡 Motivation and Context
ICurrentDateProvideris the defect JAVA-571 was filed about. One interface carried twoincompatible clocks —
CurrentDateProviderisSystem.currentTimeMillis(),AndroidCurrentDateProvideris
SystemClock.uptimeMillis()— and nothing in the name or the type said which. A field declaredICurrentDateProvideraccepts either, and the two disagree by however long the device has beensuspended.
Each of the 21 Java suppressions carries a
// TODO [MAJOR]naming the replacement that site shouldtake, because a suppressed warning stops being a checklist entry. Nearly all of them are frozen until
the next major because they produce serialized timestamps —
SentryEvent,Breadcrumb,Session,SentryReplayEvent,ProfilingTraceData, both profilers, the activity-lifecycle span helpers. OnlyClientReportRecorderandEnvelopeCacheare internal. That is expected: this PR marks the surface,it does not migrate it.
Four sites must stay on the wall clock and say so:
AnrV2Integration,TombstoneIntegrationandApplicationExitInfoHistoryDispatchercompare against epochApplicationExitInfotimestamps, andLifecycleWatcheragainstSession.getStarted().💚 How did you test it?
No behaviour changes, so no new tests — this is annotations plus suppressions.
./gradlew :sentry:test :sentry:apiCheck :sentry-android-core:testReleaseUnitTest :sentry-android-core:apiCheck :sentry-android-replay:testReleaseUnitTest :sentry-okhttp:test :sentry-apache-http-client-5:test— green../gradlew spotlessApply apiDumpproduces no.apidiff: BCV does not record annotations.📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps
The removals, and the serialized-value migrations behind every
// TODO [MAJOR]here, belong to the9.x.xbranch: JAVA-572 (span durations), JAVA-575 (replay timings), JAVA-577 (session durations),JAVA-578 (profiler re-anchoring), JAVA-642 (app-start spans).