From f676c7179488a3e450d31af8c0e59bc47b41688e Mon Sep 17 00:00:00 2001 From: Kainsin Date: Fri, 17 Apr 2026 08:59:05 -0400 Subject: [PATCH 1/2] Remove JSR-305 ThreadSafe annotation and replace with JavaDoc where appropriate --- api/src/main/java/io/grpc/Channel.java | 5 +++-- api/src/main/java/io/grpc/ChannelLogger.java | 5 +++-- api/src/main/java/io/grpc/ClientInterceptor.java | 5 +++-- api/src/main/java/io/grpc/ClientStreamTracer.java | 5 +++-- api/src/main/java/io/grpc/CompressorRegistry.java | 5 +++-- api/src/main/java/io/grpc/DecompressorRegistry.java | 5 +++-- api/src/main/java/io/grpc/HandlerRegistry.java | 5 +++-- api/src/main/java/io/grpc/LoadBalancer.java | 13 +++++++++---- api/src/main/java/io/grpc/LoadBalancerRegistry.java | 7 ++++--- api/src/main/java/io/grpc/ManagedChannel.java | 5 +++-- .../main/java/io/grpc/ManagedChannelRegistry.java | 7 ++++--- api/src/main/java/io/grpc/NameResolver.java | 7 ++++--- api/src/main/java/io/grpc/NameResolverRegistry.java | 7 ++++--- api/src/main/java/io/grpc/Server.java | 5 +++-- api/src/main/java/io/grpc/ServerCallHandler.java | 5 +++-- api/src/main/java/io/grpc/ServerInterceptor.java | 5 +++-- api/src/main/java/io/grpc/ServerRegistry.java | 5 +++-- api/src/main/java/io/grpc/ServerStreamTracer.java | 5 +++-- api/src/main/java/io/grpc/StreamTracer.java | 5 +++-- .../main/java/io/grpc/SynchronizationContext.java | 5 ++--- .../grpc/binder/internal/BinderClientTransport.java | 9 ++++++--- .../java/io/grpc/binder/internal/BinderServer.java | 5 +++-- .../io/grpc/binder/internal/BinderTransport.java | 5 +++-- .../io/grpc/binder/internal/ServiceBinding.java | 5 +++-- .../main/java/io/grpc/internal/AtomicBackoff.java | 10 +++++++--- .../main/java/io/grpc/internal/ClientTransport.java | 5 +++-- .../io/grpc/internal/ConnectionClientTransport.java | 5 +++-- .../main/java/io/grpc/internal/InternalServer.java | 5 +++-- .../java/io/grpc/internal/InternalSubchannel.java | 5 +++-- .../java/io/grpc/internal/KeepAliveManager.java | 4 ++-- .../java/io/grpc/internal/ManagedChannelImpl.java | 9 ++++++--- .../io/grpc/internal/ManagedClientTransport.java | 5 +++-- core/src/main/java/io/grpc/internal/ObjectPool.java | 5 +++-- .../java/io/grpc/internal/SharedResourceHolder.java | 5 +++-- .../java/io/grpc/internal/StatsTraceContext.java | 5 +++-- .../java/io/grpc/internal/TransportProvider.java | 5 +++-- .../grpc/gcp/observability/ObservabilityConfig.java | 5 +++-- .../io/grpc/grpclb/GrpclbClientLoadRecorder.java | 5 +++-- .../java/io/grpc/inprocess/InProcessServer.java | 6 ++++-- .../java/io/grpc/inprocess/InProcessTransport.java | 6 ++++-- .../io/grpc/testing/integration/XdsTestClient.java | 9 ++++++--- .../main/java/io/grpc/rls/CachingRlsLbClient.java | 5 +++-- rls/src/main/java/io/grpc/rls/Throttler.java | 5 +++-- .../channel/S2AHandshakerServiceChannel.java | 5 +++-- .../handshaker/tokenmanager/AccessTokenManager.java | 9 ++++++--- .../io/grpc/protobuf/services/BinlogHelper.java | 5 +++-- .../main/java/io/grpc/services/AdminInterface.java | 5 +++-- .../java/io/grpc/services/CallMetricRecorder.java | 5 +++-- .../main/java/io/grpc/stub/AbstractAsyncStub.java | 5 +++-- .../java/io/grpc/stub/AbstractBlockingStub.java | 5 +++-- .../main/java/io/grpc/stub/AbstractFutureStub.java | 5 +++-- stub/src/main/java/io/grpc/stub/AbstractStub.java | 5 +++-- .../java/io/grpc/util/MutableHandlerRegistry.java | 5 +++-- .../main/java/io/grpc/xds/SharedCallCounterMap.java | 5 +++-- .../io/grpc/xds/SharedXdsClientPoolProvider.java | 10 +++++++--- xds/src/main/java/io/grpc/xds/ThreadSafeRandom.java | 6 ++++-- .../java/io/grpc/xds/XdsCredentialsRegistry.java | 5 +++-- .../java/io/grpc/xds/client/LoadStatsManager2.java | 13 +++++++++---- .../xds/internal/security/ReferenceCountingMap.java | 5 +++-- .../certprovider/CertificateProviderRegistry.java | 9 ++++++--- .../certprovider/CertificateProviderStore.java | 5 +++-- 61 files changed, 223 insertions(+), 138 deletions(-) diff --git a/api/src/main/java/io/grpc/Channel.java b/api/src/main/java/io/grpc/Channel.java index 60ff76ff082..fe95ddce0ee 100644 --- a/api/src/main/java/io/grpc/Channel.java +++ b/api/src/main/java/io/grpc/Channel.java @@ -16,7 +16,6 @@ package io.grpc; -import javax.annotation.concurrent.ThreadSafe; /** * A virtual connection to a conceptual endpoint, to perform RPCs. A channel is free to have zero or @@ -29,8 +28,10 @@ * implementations using {@link ClientInterceptor}. It is expected that most application * code will not use this class directly but rather work with stubs that have been bound to a * Channel that was decorated during application initialization. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public abstract class Channel { /** * Create a {@link ClientCall} to the remote operation specified by the given diff --git a/api/src/main/java/io/grpc/ChannelLogger.java b/api/src/main/java/io/grpc/ChannelLogger.java index ce654ec9d5b..fea0506c89a 100644 --- a/api/src/main/java/io/grpc/ChannelLogger.java +++ b/api/src/main/java/io/grpc/ChannelLogger.java @@ -16,15 +16,16 @@ package io.grpc; -import javax.annotation.concurrent.ThreadSafe; /** * A Channel-specific logger provided by GRPC library to {@link LoadBalancer} implementations. * Information logged here goes to Channelz, and to the Java logger of this class * as well. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/5029") -@ThreadSafe public abstract class ChannelLogger { /** * Log levels. See the table below for the mapping from the ChannelLogger levels to Channelz diff --git a/api/src/main/java/io/grpc/ClientInterceptor.java b/api/src/main/java/io/grpc/ClientInterceptor.java index c27c31c8474..d6c8cd7e6fb 100644 --- a/api/src/main/java/io/grpc/ClientInterceptor.java +++ b/api/src/main/java/io/grpc/ClientInterceptor.java @@ -16,7 +16,6 @@ package io.grpc; -import javax.annotation.concurrent.ThreadSafe; /** * Interface for intercepting outgoing calls before they are dispatched by a {@link Channel}. @@ -37,8 +36,10 @@ * without completing the previous ones first. Refer to the * {@link io.grpc.ClientCall.Listener ClientCall.Listener} docs for more details regarding thread * safety of the returned listener. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public interface ClientInterceptor { /** * Intercept {@link ClientCall} creation by the {@code next} {@link Channel}. diff --git a/api/src/main/java/io/grpc/ClientStreamTracer.java b/api/src/main/java/io/grpc/ClientStreamTracer.java index 42e1fdfebea..564bf8fd858 100644 --- a/api/src/main/java/io/grpc/ClientStreamTracer.java +++ b/api/src/main/java/io/grpc/ClientStreamTracer.java @@ -19,13 +19,14 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; -import javax.annotation.concurrent.ThreadSafe; /** * {@link StreamTracer} for the client-side. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861") -@ThreadSafe public abstract class ClientStreamTracer extends StreamTracer { /** * Indicates how long the call was delayed, in nanoseconds, due to waiting for name resolution diff --git a/api/src/main/java/io/grpc/CompressorRegistry.java b/api/src/main/java/io/grpc/CompressorRegistry.java index 4711f6917d0..c8ab5307198 100644 --- a/api/src/main/java/io/grpc/CompressorRegistry.java +++ b/api/src/main/java/io/grpc/CompressorRegistry.java @@ -22,13 +22,14 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Encloses classes related to the compression and decompression of messages. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1704") -@ThreadSafe public final class CompressorRegistry { private static final CompressorRegistry DEFAULT_INSTANCE = new CompressorRegistry( new Codec.Gzip(), diff --git a/api/src/main/java/io/grpc/DecompressorRegistry.java b/api/src/main/java/io/grpc/DecompressorRegistry.java index ea0433d8d0a..fd7f1175d13 100644 --- a/api/src/main/java/io/grpc/DecompressorRegistry.java +++ b/api/src/main/java/io/grpc/DecompressorRegistry.java @@ -27,13 +27,14 @@ import java.util.Map; import java.util.Set; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Encloses classes related to the compression and decompression of messages. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1704") -@ThreadSafe public final class DecompressorRegistry { static final Joiner ACCEPT_ENCODING_JOINER = Joiner.on(','); diff --git a/api/src/main/java/io/grpc/HandlerRegistry.java b/api/src/main/java/io/grpc/HandlerRegistry.java index 4aaf0114fb1..b82fb9ce618 100644 --- a/api/src/main/java/io/grpc/HandlerRegistry.java +++ b/api/src/main/java/io/grpc/HandlerRegistry.java @@ -19,12 +19,13 @@ import java.util.Collections; import java.util.List; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Registry of services and their methods used by servers to dispatching incoming calls. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public abstract class HandlerRegistry { /** diff --git a/api/src/main/java/io/grpc/LoadBalancer.java b/api/src/main/java/io/grpc/LoadBalancer.java index 3187ae8ef1b..d0268794f67 100644 --- a/api/src/main/java/io/grpc/LoadBalancer.java +++ b/api/src/main/java/io/grpc/LoadBalancer.java @@ -32,7 +32,6 @@ import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.NotThreadSafe; -import javax.annotation.concurrent.ThreadSafe; /** * A pluggable component that receives resolved addresses from {@link NameResolver} and provides the @@ -447,10 +446,12 @@ public void requestConnection() {} /** * The main balancing logic. It must be thread-safe. Typically it should only * synchronize on its own state, and avoid synchronizing with the LoadBalancer's state. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. * * @since 1.2.0 */ - @ThreadSafe @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771") public abstract static class SubchannelPicker { /** @@ -1030,9 +1031,11 @@ public String toString() { /** * Provides essentials for LoadBalancer implementations. * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + * * @since 1.2.0 */ - @ThreadSafe @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771") public abstract static class Helper { /** @@ -1551,9 +1554,11 @@ public interface SubchannelStateListener { /** * Factory to create {@link LoadBalancer} instance. * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + * * @since 1.2.0 */ - @ThreadSafe @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771") public abstract static class Factory { /** diff --git a/api/src/main/java/io/grpc/LoadBalancerRegistry.java b/api/src/main/java/io/grpc/LoadBalancerRegistry.java index a8fbc102f5f..4894f049f40 100644 --- a/api/src/main/java/io/grpc/LoadBalancerRegistry.java +++ b/api/src/main/java/io/grpc/LoadBalancerRegistry.java @@ -30,16 +30,17 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Registry of {@link LoadBalancerProvider}s. The {@link #getDefaultRegistry default instance} * loads providers at runtime through the Java service provider mechanism. - * + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + * * @since 1.17.0 */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771") -@ThreadSafe public final class LoadBalancerRegistry { private static final Logger logger = Logger.getLogger(LoadBalancerRegistry.class.getName()); private static LoadBalancerRegistry instance; diff --git a/api/src/main/java/io/grpc/ManagedChannel.java b/api/src/main/java/io/grpc/ManagedChannel.java index 7875fdb57f2..6aa0b6865a0 100644 --- a/api/src/main/java/io/grpc/ManagedChannel.java +++ b/api/src/main/java/io/grpc/ManagedChannel.java @@ -17,12 +17,13 @@ package io.grpc; import java.util.concurrent.TimeUnit; -import javax.annotation.concurrent.ThreadSafe; /** * A {@link Channel} that provides lifecycle management. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public abstract class ManagedChannel extends Channel { /** * Initiates an orderly shutdown in which preexisting calls continue but new calls are immediately diff --git a/api/src/main/java/io/grpc/ManagedChannelRegistry.java b/api/src/main/java/io/grpc/ManagedChannelRegistry.java index ec47b325ffc..ff56f30817c 100644 --- a/api/src/main/java/io/grpc/ManagedChannelRegistry.java +++ b/api/src/main/java/io/grpc/ManagedChannelRegistry.java @@ -32,16 +32,17 @@ import java.util.ServiceLoader; import java.util.logging.Level; import java.util.logging.Logger; -import javax.annotation.concurrent.ThreadSafe; /** * Registry of {@link ManagedChannelProvider}s. The {@link #getDefaultRegistry default instance} * loads providers at runtime through the Java service provider mechanism. - * + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + * * @since 1.32.0 */ @Internal -@ThreadSafe public final class ManagedChannelRegistry { private static final Logger logger = Logger.getLogger(ManagedChannelRegistry.class.getName()); private static ManagedChannelRegistry instance; diff --git a/api/src/main/java/io/grpc/NameResolver.java b/api/src/main/java/io/grpc/NameResolver.java index e44a26309ae..86cb4b537ed 100644 --- a/api/src/main/java/io/grpc/NameResolver.java +++ b/api/src/main/java/io/grpc/NameResolver.java @@ -35,7 +35,6 @@ import java.util.concurrent.ScheduledExecutorService; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; -import javax.annotation.concurrent.ThreadSafe; /** * A pluggable component that resolves a target {@link URI} and return addresses to the caller. @@ -214,11 +213,13 @@ public NameResolver newNameResolver(Uri targetUri, final Args args) { * Receives address updates. * *

All methods are expected to return quickly. - * + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + * * @since 1.0.0 */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1770") - @ThreadSafe public interface Listener { /** * Handles updates on resolved addresses and attributes. diff --git a/api/src/main/java/io/grpc/NameResolverRegistry.java b/api/src/main/java/io/grpc/NameResolverRegistry.java index c5e9f7467ab..1fd3769a011 100644 --- a/api/src/main/java/io/grpc/NameResolverRegistry.java +++ b/api/src/main/java/io/grpc/NameResolverRegistry.java @@ -33,16 +33,17 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Registry of {@link NameResolverProvider}s. The {@link #getDefaultRegistry default instance} * loads providers at runtime through the Java service provider mechanism. - * + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + * * @since 1.21.0 */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/4159") -@ThreadSafe public final class NameResolverRegistry { private static final Logger logger = Logger.getLogger(NameResolverRegistry.class.getName()); private static NameResolverRegistry instance; diff --git a/api/src/main/java/io/grpc/Server.java b/api/src/main/java/io/grpc/Server.java index 97ea06a81c2..a1301ff66d9 100644 --- a/api/src/main/java/io/grpc/Server.java +++ b/api/src/main/java/io/grpc/Server.java @@ -21,13 +21,14 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; -import javax.annotation.concurrent.ThreadSafe; /** * Server for listening for and dispatching incoming calls. It is not expected to be implemented by * application code or interceptors. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public abstract class Server { /** diff --git a/api/src/main/java/io/grpc/ServerCallHandler.java b/api/src/main/java/io/grpc/ServerCallHandler.java index fdfa9997957..df7b6aaa688 100644 --- a/api/src/main/java/io/grpc/ServerCallHandler.java +++ b/api/src/main/java/io/grpc/ServerCallHandler.java @@ -16,13 +16,14 @@ package io.grpc; -import javax.annotation.concurrent.ThreadSafe; /** * Interface to initiate processing of incoming remote calls. Advanced applications and generated * code will implement this interface to allows {@link Server}s to invoke service methods. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public interface ServerCallHandler { /** * Starts asynchronous processing of an incoming call. diff --git a/api/src/main/java/io/grpc/ServerInterceptor.java b/api/src/main/java/io/grpc/ServerInterceptor.java index 9b2e76ef608..6207c191527 100644 --- a/api/src/main/java/io/grpc/ServerInterceptor.java +++ b/api/src/main/java/io/grpc/ServerInterceptor.java @@ -16,7 +16,6 @@ package io.grpc; -import javax.annotation.concurrent.ThreadSafe; /** * Interface for intercepting incoming calls before they are dispatched by @@ -34,8 +33,10 @@ * without completing the previous ones first. Refer to the * {@link io.grpc.ServerCall.Listener ServerCall.Listener} docs for more details regarding thread * safety of the returned listener. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public interface ServerInterceptor { /** * Intercept {@link ServerCall} dispatch by the {@code next} {@link ServerCallHandler}. General diff --git a/api/src/main/java/io/grpc/ServerRegistry.java b/api/src/main/java/io/grpc/ServerRegistry.java index 1ec7030b82b..1753a61bb41 100644 --- a/api/src/main/java/io/grpc/ServerRegistry.java +++ b/api/src/main/java/io/grpc/ServerRegistry.java @@ -27,14 +27,15 @@ import java.util.ServiceLoader; import java.util.logging.Level; import java.util.logging.Logger; -import javax.annotation.concurrent.ThreadSafe; /** * Registry of {@link ServerProvider}s. The {@link #getDefaultRegistry default instance} loads * providers at runtime through the Java service provider mechanism. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ @Internal -@ThreadSafe public final class ServerRegistry { private static final Logger logger = Logger.getLogger(ServerRegistry.class.getName()); private static ServerRegistry instance; diff --git a/api/src/main/java/io/grpc/ServerStreamTracer.java b/api/src/main/java/io/grpc/ServerStreamTracer.java index d522610ab3a..85ed74e1fea 100644 --- a/api/src/main/java/io/grpc/ServerStreamTracer.java +++ b/api/src/main/java/io/grpc/ServerStreamTracer.java @@ -17,13 +17,14 @@ package io.grpc; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Listens to events on a stream to collect metrics. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861") -@ThreadSafe public abstract class ServerStreamTracer extends StreamTracer { /** * Called before the interceptors and the call handlers and make changes to the Context object diff --git a/api/src/main/java/io/grpc/StreamTracer.java b/api/src/main/java/io/grpc/StreamTracer.java index 66b3de8be6b..6de9a8ee7c7 100644 --- a/api/src/main/java/io/grpc/StreamTracer.java +++ b/api/src/main/java/io/grpc/StreamTracer.java @@ -16,15 +16,16 @@ package io.grpc; -import javax.annotation.concurrent.ThreadSafe; /** * Listens to events on a stream to collect metrics. * *

DO NOT MOCK: Use TestStreamTracer. Mocks are not thread-safe + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861") -@ThreadSafe public abstract class StreamTracer { /** * Stream is closed. This will be called exactly once. diff --git a/api/src/main/java/io/grpc/SynchronizationContext.java b/api/src/main/java/io/grpc/SynchronizationContext.java index 94916a1b473..f22e9f0aec9 100644 --- a/api/src/main/java/io/grpc/SynchronizationContext.java +++ b/api/src/main/java/io/grpc/SynchronizationContext.java @@ -29,7 +29,6 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import javax.annotation.concurrent.ThreadSafe; /** * A synchronization context is a queue of tasks that run in sequence. It offers following @@ -54,11 +53,11 @@ * are held when calling the context. So it is encouraged to avoid mixing locks and synchronization * context except via {@link #executeLater}. * - *

This class is thread-safe. + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. * * @since 1.17.0 */ -@ThreadSafe public final class SynchronizationContext implements Executor { private final UncaughtExceptionHandler uncaughtExceptionHandler; diff --git a/binder/src/main/java/io/grpc/binder/internal/BinderClientTransport.java b/binder/src/main/java/io/grpc/binder/internal/BinderClientTransport.java index bef1eefd43e..b2b282cf901 100644 --- a/binder/src/main/java/io/grpc/binder/internal/BinderClientTransport.java +++ b/binder/src/main/java/io/grpc/binder/internal/BinderClientTransport.java @@ -62,10 +62,13 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.atomic.AtomicInteger; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; -/** Concrete client-side transport implementation. */ -@ThreadSafe +/** + * Concrete client-side transport implementation. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + */ @Internal public final class BinderClientTransport extends BinderTransport implements ConnectionClientTransport, Bindable.Observer { diff --git a/binder/src/main/java/io/grpc/binder/internal/BinderServer.java b/binder/src/main/java/io/grpc/binder/internal/BinderServer.java index 96685a2f8bd..754a73c11ba 100644 --- a/binder/src/main/java/io/grpc/binder/internal/BinderServer.java +++ b/binder/src/main/java/io/grpc/binder/internal/BinderServer.java @@ -49,7 +49,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * A gRPC InternalServer which accepts connections via a host AndroidService. @@ -58,8 +57,10 @@ * *

IMPORTANT: This implementation must comply with this published wire format. * https://github.com/grpc/proposal/blob/master/L73-java-binderchannel/wireformat.md + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public final class BinderServer implements InternalServer, LeakSafeOneWayBinder.TransactionHandler { private static final Logger logger = Logger.getLogger(BinderServer.class.getName()); diff --git a/binder/src/main/java/io/grpc/binder/internal/BinderTransport.java b/binder/src/main/java/io/grpc/binder/internal/BinderTransport.java index 1592f6977df..97549818ee7 100644 --- a/binder/src/main/java/io/grpc/binder/internal/BinderTransport.java +++ b/binder/src/main/java/io/grpc/binder/internal/BinderTransport.java @@ -54,7 +54,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Base class for binder-based gRPC transport. @@ -76,8 +75,10 @@ * *

IMPORTANT: This implementation must comply with this published wire format. * https://github.com/grpc/proposal/blob/master/L73-java-binderchannel/wireformat.md + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public abstract class BinderTransport implements IBinder.DeathRecipient { private static final Logger logger = Logger.getLogger(BinderTransport.class.getName()); diff --git a/binder/src/main/java/io/grpc/binder/internal/ServiceBinding.java b/binder/src/main/java/io/grpc/binder/internal/ServiceBinding.java index 4b6bf7d06fb..d50499d5606 100644 --- a/binder/src/main/java/io/grpc/binder/internal/ServiceBinding.java +++ b/binder/src/main/java/io/grpc/binder/internal/ServiceBinding.java @@ -41,7 +41,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Manages an Android binding that's restricted to at most one connection to the remote Service. @@ -53,8 +52,10 @@ *

For this reason, while internal consistency is handled with synchronization (the state field), * consistency on our observer callbacks is ensured by doing everything on the application's main * thread. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe final class ServiceBinding implements Bindable, ServiceConnection { private static final Logger logger = Logger.getLogger(ServiceBinding.class.getName()); diff --git a/core/src/main/java/io/grpc/internal/AtomicBackoff.java b/core/src/main/java/io/grpc/internal/AtomicBackoff.java index 68ba9bece0c..e7724576f5c 100644 --- a/core/src/main/java/io/grpc/internal/AtomicBackoff.java +++ b/core/src/main/java/io/grpc/internal/AtomicBackoff.java @@ -20,12 +20,13 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import java.util.logging.Logger; -import javax.annotation.concurrent.ThreadSafe; /** * A {@code long} atomically updated due to errors caused by the value being too small. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public final class AtomicBackoff { private static final Logger log = Logger.getLogger(AtomicBackoff.class.getName()); @@ -44,7 +45,10 @@ public State getState() { return new State(value.get()); } - @ThreadSafe + /** + * This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + */ public final class State { private final long savedValue; diff --git a/core/src/main/java/io/grpc/internal/ClientTransport.java b/core/src/main/java/io/grpc/internal/ClientTransport.java index fd0f30b8bf1..b7d9470027f 100644 --- a/core/src/main/java/io/grpc/internal/ClientTransport.java +++ b/core/src/main/java/io/grpc/internal/ClientTransport.java @@ -24,15 +24,16 @@ import io.grpc.MethodDescriptor; import io.grpc.Status; import java.util.concurrent.Executor; -import javax.annotation.concurrent.ThreadSafe; /** * The client-side transport typically encapsulating a single connection to a remote * server. However, streams created before the client has discovered any server address may * eventually be issued on different connections. All methods on the transport and its callbacks * are expected to execute quickly. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public interface ClientTransport extends InternalInstrumented { /** diff --git a/core/src/main/java/io/grpc/internal/ConnectionClientTransport.java b/core/src/main/java/io/grpc/internal/ConnectionClientTransport.java index 8385316d608..a70745b5327 100644 --- a/core/src/main/java/io/grpc/internal/ConnectionClientTransport.java +++ b/core/src/main/java/io/grpc/internal/ConnectionClientTransport.java @@ -17,12 +17,13 @@ package io.grpc.internal; import io.grpc.Attributes; -import javax.annotation.concurrent.ThreadSafe; /** * A {@link ManagedClientTransport} that is based on a connection. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public interface ConnectionClientTransport extends ManagedClientTransport { /** * Returns a set of attributes, which may vary depending on the state of the transport. The keys diff --git a/core/src/main/java/io/grpc/internal/InternalServer.java b/core/src/main/java/io/grpc/internal/InternalServer.java index a6079081233..db9077b8505 100644 --- a/core/src/main/java/io/grpc/internal/InternalServer.java +++ b/core/src/main/java/io/grpc/internal/InternalServer.java @@ -22,13 +22,14 @@ import java.net.SocketAddress; import java.util.List; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * An object that accepts new incoming connections on one or more listening socket addresses. * This would commonly encapsulate a bound socket that {@code accept()}s new connections. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public interface InternalServer { /** * Starts transport. Implementations must not call {@code listener} until after {@code start()} diff --git a/core/src/main/java/io/grpc/internal/InternalSubchannel.java b/core/src/main/java/io/grpc/internal/InternalSubchannel.java index 00a66b1c1df..957335080ce 100644 --- a/core/src/main/java/io/grpc/internal/InternalSubchannel.java +++ b/core/src/main/java/io/grpc/internal/InternalSubchannel.java @@ -63,12 +63,13 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Transports for a single {@link SocketAddress}. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe final class InternalSubchannel implements InternalInstrumented, TransportProvider { private final InternalLogId logId; diff --git a/core/src/main/java/io/grpc/internal/KeepAliveManager.java b/core/src/main/java/io/grpc/internal/KeepAliveManager.java index 535b3a82524..a42eb290051 100644 --- a/core/src/main/java/io/grpc/internal/KeepAliveManager.java +++ b/core/src/main/java/io/grpc/internal/KeepAliveManager.java @@ -27,7 +27,6 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import javax.annotation.concurrent.ThreadSafe; /** * Manages keepalive pings. @@ -268,8 +267,9 @@ public static final class ClientKeepAlivePinger implements KeepAlivePinger { /** * A {@link ClientTransport} that has life-cycle management. * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ - @ThreadSafe public interface TransportWithDisconnectReason extends ClientTransport { /** diff --git a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java index e423220e3ad..6849bb45101 100644 --- a/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java +++ b/core/src/main/java/io/grpc/internal/ManagedChannelImpl.java @@ -118,10 +118,13 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; -/** A communication channel for making outgoing RPCs. */ -@ThreadSafe +/** + * A communication channel for making outgoing RPCs. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + */ final class ManagedChannelImpl extends ManagedChannel implements InternalInstrumented { @VisibleForTesting diff --git a/core/src/main/java/io/grpc/internal/ManagedClientTransport.java b/core/src/main/java/io/grpc/internal/ManagedClientTransport.java index 8350a005409..0b671b36bd5 100644 --- a/core/src/main/java/io/grpc/internal/ManagedClientTransport.java +++ b/core/src/main/java/io/grpc/internal/ManagedClientTransport.java @@ -20,7 +20,6 @@ import io.grpc.Attributes; import io.grpc.Status; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * A {@link ClientTransport} that has life-cycle management. @@ -32,8 +31,10 @@ * implementations may transfer the streams to somewhere else. Either way they must conform to the * contract defined by {@link #shutdown}, {@link Listener#transportShutdown} and * {@link Listener#transportTerminated}. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public interface ManagedClientTransport extends ClientTransport { /** diff --git a/core/src/main/java/io/grpc/internal/ObjectPool.java b/core/src/main/java/io/grpc/internal/ObjectPool.java index 13547bc274a..358ef6ae02f 100644 --- a/core/src/main/java/io/grpc/internal/ObjectPool.java +++ b/core/src/main/java/io/grpc/internal/ObjectPool.java @@ -16,12 +16,13 @@ package io.grpc.internal; -import javax.annotation.concurrent.ThreadSafe; /** * An object pool. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public interface ObjectPool { /** * Get an object from the pool. diff --git a/core/src/main/java/io/grpc/internal/SharedResourceHolder.java b/core/src/main/java/io/grpc/internal/SharedResourceHolder.java index 1dfa1f90718..99b1dc957a2 100644 --- a/core/src/main/java/io/grpc/internal/SharedResourceHolder.java +++ b/core/src/main/java/io/grpc/internal/SharedResourceHolder.java @@ -22,7 +22,6 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import javax.annotation.concurrent.ThreadSafe; /** * A holder for shared resource singletons. @@ -37,8 +36,10 @@ * to an object cached in the holder. * *

Resources are ref-counted and shut down after a delay when the ref-count reaches zero. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public final class SharedResourceHolder { static final long DESTROY_DELAY_SECONDS = 1; diff --git a/core/src/main/java/io/grpc/internal/StatsTraceContext.java b/core/src/main/java/io/grpc/internal/StatsTraceContext.java index 650f0b979ae..17298a21607 100644 --- a/core/src/main/java/io/grpc/internal/StatsTraceContext.java +++ b/core/src/main/java/io/grpc/internal/StatsTraceContext.java @@ -31,12 +31,13 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; -import javax.annotation.concurrent.ThreadSafe; /** * The stats and tracing information for a stream. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public final class StatsTraceContext { public static final StatsTraceContext NOOP = new StatsTraceContext(new StreamTracer[0]); diff --git a/core/src/main/java/io/grpc/internal/TransportProvider.java b/core/src/main/java/io/grpc/internal/TransportProvider.java index 47230443e97..04c010ae06c 100644 --- a/core/src/main/java/io/grpc/internal/TransportProvider.java +++ b/core/src/main/java/io/grpc/internal/TransportProvider.java @@ -17,12 +17,13 @@ package io.grpc.internal; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Provides transports for sending RPCs. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe interface TransportProvider { /** * Returns a READY transport that will be used to create new streams. diff --git a/gcp-observability/src/main/java/io/grpc/gcp/observability/ObservabilityConfig.java b/gcp-observability/src/main/java/io/grpc/gcp/observability/ObservabilityConfig.java index 0489c8b5e3b..d0f845be0a0 100644 --- a/gcp-observability/src/main/java/io/grpc/gcp/observability/ObservabilityConfig.java +++ b/gcp-observability/src/main/java/io/grpc/gcp/observability/ObservabilityConfig.java @@ -21,7 +21,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import javax.annotation.concurrent.ThreadSafe; @Internal public interface ObservabilityConfig { @@ -51,8 +50,10 @@ public interface ObservabilityConfig { /** * POJO for representing a filter used in configuration. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ - @ThreadSafe class LogFilter { /** Set of services. */ public final Set services; diff --git a/grpclb/src/main/java/io/grpc/grpclb/GrpclbClientLoadRecorder.java b/grpclb/src/main/java/io/grpc/grpclb/GrpclbClientLoadRecorder.java index fe928263ef9..2d8d811ac23 100644 --- a/grpclb/src/main/java/io/grpc/grpclb/GrpclbClientLoadRecorder.java +++ b/grpclb/src/main/java/io/grpc/grpclb/GrpclbClientLoadRecorder.java @@ -30,13 +30,14 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicLongFieldUpdater; -import javax.annotation.concurrent.ThreadSafe; /** * Record and aggregate client-side load data for GRPCLB. This records load occurred during the * span of an LB stream with the remote load-balancer. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe final class GrpclbClientLoadRecorder extends ClientStreamTracer.Factory { private static final AtomicLongFieldUpdater callsStartedUpdater = diff --git a/inprocess/src/main/java/io/grpc/inprocess/InProcessServer.java b/inprocess/src/main/java/io/grpc/inprocess/InProcessServer.java index ffaca78f397..913cf6a088e 100644 --- a/inprocess/src/main/java/io/grpc/inprocess/InProcessServer.java +++ b/inprocess/src/main/java/io/grpc/inprocess/InProcessServer.java @@ -33,9 +33,11 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ScheduledExecutorService; -import javax.annotation.concurrent.ThreadSafe; -@ThreadSafe +/** + * This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + */ final class InProcessServer implements InternalServer { private static final ConcurrentMap registry = new ConcurrentHashMap<>(); diff --git a/inprocess/src/main/java/io/grpc/inprocess/InProcessTransport.java b/inprocess/src/main/java/io/grpc/inprocess/InProcessTransport.java index a92f10fd5c5..676f635782e 100644 --- a/inprocess/src/main/java/io/grpc/inprocess/InProcessTransport.java +++ b/inprocess/src/main/java/io/grpc/inprocess/InProcessTransport.java @@ -77,9 +77,11 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; -@ThreadSafe +/** + * This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + */ final class InProcessTransport implements ServerTransport, ConnectionClientTransport { private static final Logger log = Logger.getLogger(InProcessTransport.class.getName()); static boolean isEnabledSupportTracingMessageSizes = diff --git a/interop-testing/src/main/java/io/grpc/testing/integration/XdsTestClient.java b/interop-testing/src/main/java/io/grpc/testing/integration/XdsTestClient.java index 89519041a79..fa473a5b6a2 100644 --- a/interop-testing/src/main/java/io/grpc/testing/integration/XdsTestClient.java +++ b/interop-testing/src/main/java/io/grpc/testing/integration/XdsTestClient.java @@ -77,7 +77,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; /** Client for xDS interop tests. */ @@ -557,8 +556,12 @@ private RpcConfig(RpcType rpcType, Metadata metadata, int timeoutSec) { } } - /** Stats recorder for test RPCs. */ - @ThreadSafe + /** + * Stats recorder for test RPCs. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + */ private static final class StatsAccumulator { private final Map rpcsStartedByMethod = new HashMap<>(); // TODO(chengyuanzhang): delete the following two after corresponding fields deleted in proto. diff --git a/rls/src/main/java/io/grpc/rls/CachingRlsLbClient.java b/rls/src/main/java/io/grpc/rls/CachingRlsLbClient.java index a2846fd04c8..8cd4a259ece 100644 --- a/rls/src/main/java/io/grpc/rls/CachingRlsLbClient.java +++ b/rls/src/main/java/io/grpc/rls/CachingRlsLbClient.java @@ -77,14 +77,15 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * A CachingRlsLbClient is a core implementation of RLS loadbalancer supports dynamic request * routing by fetching the decision from route lookup server. Every single request is routed by * the server's decision. To reduce the performance penalty, {@link LruCache} is used. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe final class CachingRlsLbClient { private static final Converter diff --git a/rls/src/main/java/io/grpc/rls/Throttler.java b/rls/src/main/java/io/grpc/rls/Throttler.java index 96d17e70adf..cb8b77d394a 100644 --- a/rls/src/main/java/io/grpc/rls/Throttler.java +++ b/rls/src/main/java/io/grpc/rls/Throttler.java @@ -16,12 +16,13 @@ package io.grpc.rls; -import javax.annotation.concurrent.ThreadSafe; /** * A strategy for deciding when to throttle requests at the client. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe interface Throttler { /** diff --git a/s2a/src/main/java/io/grpc/s2a/internal/channel/S2AHandshakerServiceChannel.java b/s2a/src/main/java/io/grpc/s2a/internal/channel/S2AHandshakerServiceChannel.java index 8453268efc0..9664015541b 100644 --- a/s2a/src/main/java/io/grpc/s2a/internal/channel/S2AHandshakerServiceChannel.java +++ b/s2a/src/main/java/io/grpc/s2a/internal/channel/S2AHandshakerServiceChannel.java @@ -24,7 +24,6 @@ import io.grpc.ManagedChannel; import io.grpc.internal.SharedResourceHolder.Resource; import io.grpc.netty.NettyChannelBuilder; -import javax.annotation.concurrent.ThreadSafe; /** * Provides APIs for managing gRPC channels to an S2A server. Each channel is local and plaintext. @@ -44,8 +43,10 @@ * // Send an RPC over the channel to the S2A server running at localhost:1234. * resource.close(channel); * } + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public final class S2AHandshakerServiceChannel { /** diff --git a/s2a/src/main/java/io/grpc/s2a/internal/handshaker/tokenmanager/AccessTokenManager.java b/s2a/src/main/java/io/grpc/s2a/internal/handshaker/tokenmanager/AccessTokenManager.java index 65fca46bbb2..2d60693a02c 100644 --- a/s2a/src/main/java/io/grpc/s2a/internal/handshaker/tokenmanager/AccessTokenManager.java +++ b/s2a/src/main/java/io/grpc/s2a/internal/handshaker/tokenmanager/AccessTokenManager.java @@ -18,10 +18,13 @@ import io.grpc.s2a.internal.handshaker.S2AIdentity; import java.util.Optional; -import javax.annotation.concurrent.ThreadSafe; -/** Manages access tokens for authenticating to the S2A. */ -@ThreadSafe +/** + * Manages access tokens for authenticating to the S2A. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + */ public final class AccessTokenManager { private final TokenFetcher tokenFetcher; diff --git a/services/src/main/java/io/grpc/protobuf/services/BinlogHelper.java b/services/src/main/java/io/grpc/protobuf/services/BinlogHelper.java index e810c983beb..6426e9a71a0 100644 --- a/services/src/main/java/io/grpc/protobuf/services/BinlogHelper.java +++ b/services/src/main/java/io/grpc/protobuf/services/BinlogHelper.java @@ -69,12 +69,13 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * A binary log class that is configured for a specific {@link MethodDescriptor}. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe final class BinlogHelper { private static final Logger logger = Logger.getLogger(BinlogHelper.class.getName()); // Normally 'grpc-' metadata keys are set from within gRPC, and applications are not allowed diff --git a/services/src/main/java/io/grpc/services/AdminInterface.java b/services/src/main/java/io/grpc/services/AdminInterface.java index 2288d844fd1..4ab9ba06271 100644 --- a/services/src/main/java/io/grpc/services/AdminInterface.java +++ b/services/src/main/java/io/grpc/services/AdminInterface.java @@ -27,15 +27,16 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import javax.annotation.concurrent.ThreadSafe; /** * Admin Interface provides a class of services for exposing the overall state of gRPC * activity in a given binary. It aims to be a convenient API that provides available admin * services. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/7929") -@ThreadSafe public final class AdminInterface { private static final int DEFAULT_CHANNELZ_MAX_PAGE_SIZE = 100; private static final Logger logger = Logger.getLogger(AdminInterface.class.getName()); diff --git a/services/src/main/java/io/grpc/services/CallMetricRecorder.java b/services/src/main/java/io/grpc/services/CallMetricRecorder.java index d480f0f4c3b..5bc982a889b 100644 --- a/services/src/main/java/io/grpc/services/CallMetricRecorder.java +++ b/services/src/main/java/io/grpc/services/CallMetricRecorder.java @@ -24,13 +24,14 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; -import javax.annotation.concurrent.ThreadSafe; /** * Utility to record call metrics for load-balancing. One instance per call. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/6012") -@ThreadSafe public final class CallMetricRecorder { private static final CallMetricRecorder NOOP = new CallMetricRecorder().disable(); diff --git a/stub/src/main/java/io/grpc/stub/AbstractAsyncStub.java b/stub/src/main/java/io/grpc/stub/AbstractAsyncStub.java index f369eeaf87f..c5f9026a994 100644 --- a/stub/src/main/java/io/grpc/stub/AbstractAsyncStub.java +++ b/stub/src/main/java/io/grpc/stub/AbstractAsyncStub.java @@ -20,7 +20,6 @@ import io.grpc.CallOptions; import io.grpc.Channel; import io.grpc.stub.ClientCalls.StubType; -import javax.annotation.concurrent.ThreadSafe; /** * Stub implementations for async stubs. @@ -28,9 +27,11 @@ *

DO NOT MOCK: Customizing options doesn't work properly in mocks. Use InProcessChannelBuilder * to create a real channel suitable for testing. It is also possible to mock Channel instead. * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + * * @since 1.26.0 */ -@ThreadSafe @CheckReturnValue public abstract class AbstractAsyncStub> extends AbstractStub { diff --git a/stub/src/main/java/io/grpc/stub/AbstractBlockingStub.java b/stub/src/main/java/io/grpc/stub/AbstractBlockingStub.java index 4bdb3c0bb94..331ac147a85 100644 --- a/stub/src/main/java/io/grpc/stub/AbstractBlockingStub.java +++ b/stub/src/main/java/io/grpc/stub/AbstractBlockingStub.java @@ -20,7 +20,6 @@ import io.grpc.CallOptions; import io.grpc.Channel; import io.grpc.stub.ClientCalls.StubType; -import javax.annotation.concurrent.ThreadSafe; /** * Stub implementations for blocking stubs. @@ -28,9 +27,11 @@ *

DO NOT MOCK: Customizing options doesn't work properly in mocks. Use InProcessChannelBuilder * to create a real channel suitable for testing. It is also possible to mock Channel instead. * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + * * @since 1.26.0 */ -@ThreadSafe @CheckReturnValue public abstract class AbstractBlockingStub> extends AbstractStub { diff --git a/stub/src/main/java/io/grpc/stub/AbstractFutureStub.java b/stub/src/main/java/io/grpc/stub/AbstractFutureStub.java index 5e37b1e4915..73fec0f2135 100644 --- a/stub/src/main/java/io/grpc/stub/AbstractFutureStub.java +++ b/stub/src/main/java/io/grpc/stub/AbstractFutureStub.java @@ -20,7 +20,6 @@ import io.grpc.CallOptions; import io.grpc.Channel; import io.grpc.stub.ClientCalls.StubType; -import javax.annotation.concurrent.ThreadSafe; /** * Stub implementations for future stubs. @@ -28,9 +27,11 @@ *

DO NOT MOCK: Customizing options doesn't work properly in mocks. Use InProcessChannelBuilder * to create a real channel suitable for testing. It is also possible to mock Channel instead. * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + * * @since 1.26.0 */ -@ThreadSafe @CheckReturnValue public abstract class AbstractFutureStub> extends AbstractStub { diff --git a/stub/src/main/java/io/grpc/stub/AbstractStub.java b/stub/src/main/java/io/grpc/stub/AbstractStub.java index 697107760db..9587c652eab 100644 --- a/stub/src/main/java/io/grpc/stub/AbstractStub.java +++ b/stub/src/main/java/io/grpc/stub/AbstractStub.java @@ -32,7 +32,6 @@ import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; /** @@ -46,10 +45,12 @@ *

DO NOT MOCK: Customizing options doesn't work properly in mocks. Use InProcessChannelBuilder * to create a real channel suitable for testing. It is also possible to mock Channel instead. * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + * * @since 1.0.0 * @param the concrete type of this stub. */ -@ThreadSafe @CheckReturnValue public abstract class AbstractStub> { private final Channel channel; diff --git a/util/src/main/java/io/grpc/util/MutableHandlerRegistry.java b/util/src/main/java/io/grpc/util/MutableHandlerRegistry.java index 307142b642c..03ce1a7a6e2 100644 --- a/util/src/main/java/io/grpc/util/MutableHandlerRegistry.java +++ b/util/src/main/java/io/grpc/util/MutableHandlerRegistry.java @@ -28,15 +28,16 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Default implementation of {@link HandlerRegistry}. * *

Uses {@link ConcurrentHashMap} to avoid service registration excessively * blocking method lookup. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public final class MutableHandlerRegistry extends HandlerRegistry { private final ConcurrentMap services = new ConcurrentHashMap<>(); diff --git a/xds/src/main/java/io/grpc/xds/SharedCallCounterMap.java b/xds/src/main/java/io/grpc/xds/SharedCallCounterMap.java index 7aa55c27429..e7db7e593b3 100644 --- a/xds/src/main/java/io/grpc/xds/SharedCallCounterMap.java +++ b/xds/src/main/java/io/grpc/xds/SharedCallCounterMap.java @@ -26,12 +26,13 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * The global map for holding circuit breaker atomic counters. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe final class SharedCallCounterMap implements CallCounterProvider { private final ReferenceQueue refQueue = new ReferenceQueue<>(); diff --git a/xds/src/main/java/io/grpc/xds/SharedXdsClientPoolProvider.java b/xds/src/main/java/io/grpc/xds/SharedXdsClientPoolProvider.java index 45c379244af..6386702a328 100644 --- a/xds/src/main/java/io/grpc/xds/SharedXdsClientPoolProvider.java +++ b/xds/src/main/java/io/grpc/xds/SharedXdsClientPoolProvider.java @@ -40,13 +40,14 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * The global factory for creating a singleton {@link XdsClient} instance to be used by all gRPC * clients in the process. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe final class SharedXdsClientPoolProvider implements XdsClientPoolFactory { private static final boolean LOG_XDS_NODE_ID = Boolean.parseBoolean( System.getenv("GRPC_LOG_XDS_NODE_ID")); @@ -126,7 +127,10 @@ private static class SharedXdsClientPoolProviderHolder { private static final SharedXdsClientPoolProvider instance = new SharedXdsClientPoolProvider(); } - @ThreadSafe + /** + * This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + */ @VisibleForTesting class RefCountedXdsClientObjectPool implements ObjectPool { diff --git a/xds/src/main/java/io/grpc/xds/ThreadSafeRandom.java b/xds/src/main/java/io/grpc/xds/ThreadSafeRandom.java index 533ccee2375..d5c7ecb4c9e 100644 --- a/xds/src/main/java/io/grpc/xds/ThreadSafeRandom.java +++ b/xds/src/main/java/io/grpc/xds/ThreadSafeRandom.java @@ -17,9 +17,11 @@ package io.grpc.xds; import java.util.concurrent.ThreadLocalRandom; -import javax.annotation.concurrent.ThreadSafe; -@ThreadSafe // Except for impls/mocks in tests +/** + * This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + */ interface ThreadSafeRandom { int nextInt(int bound); diff --git a/xds/src/main/java/io/grpc/xds/XdsCredentialsRegistry.java b/xds/src/main/java/io/grpc/xds/XdsCredentialsRegistry.java index 9dd77a400cd..83e35d16f9c 100644 --- a/xds/src/main/java/io/grpc/xds/XdsCredentialsRegistry.java +++ b/xds/src/main/java/io/grpc/xds/XdsCredentialsRegistry.java @@ -33,13 +33,14 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Registry of {@link XdsCredentialsProvider}s. The {@link #getDefaultRegistry default * instance} loads providers at runtime through the Java service provider mechanism. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe final class XdsCredentialsRegistry { private static final Logger logger = Logger.getLogger(XdsCredentialsRegistry.class.getName()); private static XdsCredentialsRegistry instance; diff --git a/xds/src/main/java/io/grpc/xds/client/LoadStatsManager2.java b/xds/src/main/java/io/grpc/xds/client/LoadStatsManager2.java index cd858dccd99..b64fa848b0b 100644 --- a/xds/src/main/java/io/grpc/xds/client/LoadStatsManager2.java +++ b/xds/src/main/java/io/grpc/xds/client/LoadStatsManager2.java @@ -42,13 +42,14 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; /** * Manages client side traffic stats. Drop stats are maintained in cluster (with edsServiceName) * granularity and load stats (request counts) are maintained in locality granularity. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe @Internal public final class LoadStatsManager2 { // Recorders for drops of each cluster:edsServiceName. @@ -252,8 +253,10 @@ synchronized List getAllClusterStatsReports() { /** * Recorder for dropped requests. One instance per cluster with edsServiceName. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ - @ThreadSafe public final class ClusterDropStats { private final String clusterName; @Nullable @@ -327,8 +330,10 @@ private ClusterDropStatsSnapshot( /** * Recorder for client loads. One instance per locality (in cluster with edsService). + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ - @ThreadSafe public final class ClusterLocalityStats { private final String clusterName; @Nullable diff --git a/xds/src/main/java/io/grpc/xds/internal/security/ReferenceCountingMap.java b/xds/src/main/java/io/grpc/xds/internal/security/ReferenceCountingMap.java index 08b8f6a325b..2a4165c72db 100644 --- a/xds/src/main/java/io/grpc/xds/internal/security/ReferenceCountingMap.java +++ b/xds/src/main/java/io/grpc/xds/internal/security/ReferenceCountingMap.java @@ -23,7 +23,6 @@ import com.google.errorprone.annotations.CheckReturnValue; import java.util.HashMap; import java.util.Map; -import javax.annotation.concurrent.ThreadSafe; /** * A map for managing reference-counted shared resources - typically providers. @@ -32,10 +31,12 @@ * factory {@link ValueFactory} to create a new instance of V as needed. Values are ref-counted and * closed by calling {@link Closeable#close()} when ref-count reaches zero. * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + * * @param Key type for the map * @param Value type for the map - it should be a {@link Closeable} */ -@ThreadSafe public final class ReferenceCountingMap { private final Map> instances = new HashMap<>(); diff --git a/xds/src/main/java/io/grpc/xds/internal/security/certprovider/CertificateProviderRegistry.java b/xds/src/main/java/io/grpc/xds/internal/security/certprovider/CertificateProviderRegistry.java index f8ced7bb2cc..678bff7e2f9 100644 --- a/xds/src/main/java/io/grpc/xds/internal/security/certprovider/CertificateProviderRegistry.java +++ b/xds/src/main/java/io/grpc/xds/internal/security/certprovider/CertificateProviderRegistry.java @@ -21,10 +21,13 @@ import com.google.common.annotations.VisibleForTesting; import java.util.LinkedHashMap; import javax.annotation.Nullable; -import javax.annotation.concurrent.ThreadSafe; -/** Maintains {@link CertificateProvider}s for all registered plugins. */ -@ThreadSafe +/** + * Maintains {@link CertificateProvider}s for all registered plugins. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. + */ public final class CertificateProviderRegistry { private static CertificateProviderRegistry instance; private final LinkedHashMap providers = diff --git a/xds/src/main/java/io/grpc/xds/internal/security/certprovider/CertificateProviderStore.java b/xds/src/main/java/io/grpc/xds/internal/security/certprovider/CertificateProviderStore.java index 0fe342a36c0..1ccc9e81c16 100644 --- a/xds/src/main/java/io/grpc/xds/internal/security/certprovider/CertificateProviderStore.java +++ b/xds/src/main/java/io/grpc/xds/internal/security/certprovider/CertificateProviderStore.java @@ -23,15 +23,16 @@ import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; -import javax.annotation.concurrent.ThreadSafe; /** * Global map of all ref-counted {@link CertificateProvider}s that have been instantiated in * the application. Also propagates updates received from a {@link CertificateProvider} to all * the {@link Watcher}s registered for that CertificateProvider. The Store is meant to be * used internally by gRPC and *not* a public API. + * + *

This is thread-safe and should be considered + * for the errorprone ThreadSafe annotation in the future. */ -@ThreadSafe public final class CertificateProviderStore { private static final Logger logger = Logger.getLogger(CertificateProviderStore.class.getName()); From 5fbc141f035b7b578d89a3ec5559986b06bc3b63 Mon Sep 17 00:00:00 2001 From: Kainsin Date: Mon, 20 Apr 2026 08:39:05 -0400 Subject: [PATCH 2/2] Fixes a potential race condition with logging This fixes a potential race condition where a test runs a thread in the executor that does some logging. Without waiting for threads to finish, another test can be run while that background thread is still executing. This can cause flaky issues with tests that only think that their test code is executing. --- .../java/io/grpc/okhttp/OkHttpClientTransportTest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/okhttp/src/test/java/io/grpc/okhttp/OkHttpClientTransportTest.java b/okhttp/src/test/java/io/grpc/okhttp/OkHttpClientTransportTest.java index f87912c44ea..87675e2d8aa 100644 --- a/okhttp/src/test/java/io/grpc/okhttp/OkHttpClientTransportTest.java +++ b/okhttp/src/test/java/io/grpc/okhttp/OkHttpClientTransportTest.java @@ -192,7 +192,12 @@ public class OkHttpClientTransportTest { @After public void tearDown() { - executor.shutdownNow(); + try { + executor.shutdownNow(); + executor.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + // Ignore in a test and continue on as normal. + } } private void initTransport() throws Exception {