• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

grpc / grpc-java / #20082

13 Nov 2025 11:34PM UTC coverage: 88.567% (-0.05%) from 88.617%
#20082

push

github

ejona86
Revert "core: Report marshaller error for uncompressed size too large back to the client 2 (#12477)"

This reverts commit 14087f841.

It caused the same failures as the previous attempt that was reverted in
7eab160. cl/831837315

```
java.lang.AssertionError: Failed executing read operation
	at io.grpc.internal.CompositeReadableBuffer.execute(CompositeReadableBuffer.java:328)
	at io.grpc.internal.CompositeReadableBuffer.executeNoThrow(CompositeReadableBuffer.java:336)
	at io.grpc.internal.CompositeReadableBuffer.readBytes(CompositeReadableBuffer.java:151)
	at io.grpc.internal.ReadableBuffers$BufferInputStream.read(ReadableBuffers.java:377)
	at io.grpc.protobuf.lite.ProtoLiteUtils$MessageMarshaller.parse(ProtoLiteUtils.java:205)
	at io.grpc.protobuf.lite.ProtoLiteUtils$MessageMarshaller.parse(ProtoLiteUtils.java:133)
	at io.grpc.MethodDescriptor.parseRequest(MethodDescriptor.java:307)
```

35106 of 39638 relevant lines covered (88.57%)

0.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.57
/../stub/src/main/java/io/grpc/stub/AbstractStub.java
1
/*
2
 * Copyright 2014 The gRPC Authors
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package io.grpc.stub;
18

19
import static com.google.common.base.Preconditions.checkNotNull;
20
import static io.grpc.InternalTimeUtils.convert;
21

22
import com.google.errorprone.annotations.CheckReturnValue;
23
import io.grpc.CallCredentials;
24
import io.grpc.CallOptions;
25
import io.grpc.Channel;
26
import io.grpc.ClientInterceptor;
27
import io.grpc.ClientInterceptors;
28
import io.grpc.Deadline;
29
import io.grpc.ExperimentalApi;
30
import io.grpc.ManagedChannelBuilder;
31
import java.time.Duration;
32
import java.util.concurrent.Executor;
33
import java.util.concurrent.TimeUnit;
34
import javax.annotation.Nullable;
35
import javax.annotation.concurrent.ThreadSafe;
36
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
37

38
/**
39
 * Common base type for stub implementations. Stub configuration is immutable; changing the
40
 * configuration returns a new stub with updated configuration. Changing the configuration is cheap
41
 * and may be done before every RPC, such as would be common when using {@link #withDeadlineAfter}.
42
 *
43
 * <p>Configuration is stored in {@link CallOptions} and is passed to the {@link Channel} when
44
 * performing an RPC.
45
 *
46
 * <p>DO NOT MOCK: Customizing options doesn't work properly in mocks. Use InProcessChannelBuilder
47
 * to create a real channel suitable for testing. It is also possible to mock Channel instead.
48
 *
49
 * @since 1.0.0
50
 * @param <S> the concrete type of this stub.
51
 */
52
@ThreadSafe
53
@CheckReturnValue
54
public abstract class AbstractStub<S extends AbstractStub<S>> {
55
  private final Channel channel;
56
  private final CallOptions callOptions;
57

58
  /**
59
   * Constructor for use by subclasses, with the default {@code CallOptions}.
60
   *
61
   * @since 1.0.0
62
   * @param channel the channel that this stub will use to do communications
63
   */
64
  protected AbstractStub(Channel channel) {
65
    this(channel, CallOptions.DEFAULT);
×
66
  }
×
67

68
  /**
69
   * Constructor for use by subclasses.
70
   *
71
   * @since 1.0.0
72
   * @param channel the channel that this stub will use to do communications
73
   * @param callOptions the runtime call options to be applied to every call on this stub
74
   */
75
  protected AbstractStub(Channel channel, CallOptions callOptions) {
1✔
76
    this.channel = checkNotNull(channel, "channel");
1✔
77
    this.callOptions = checkNotNull(callOptions, "callOptions");
1✔
78
  }
1✔
79

80
  /**
81
   * The underlying channel of the stub.
82
   *
83
   * @since 1.0.0
84
   */
85
  public final Channel getChannel() {
86
    return channel;
1✔
87
  }
88

89
  /**
90
   * The {@code CallOptions} of the stub.
91
   *
92
   * @since 1.0.0
93
   */
94
  public final CallOptions getCallOptions() {
95
    return callOptions;
1✔
96
  }
97

98
  /**
99
   * Returns a new stub with the given channel for the provided method configurations.
100
   *
101
   * @since 1.0.0
102
   * @param channel the channel that this stub will use to do communications
103
   * @param callOptions the runtime call options to be applied to every call on this stub
104
   */
105
  protected abstract S build(Channel channel, CallOptions callOptions);
106

107
  /**
108
   * Returns a new stub with the given channel for the provided method configurations.
109
   *
110
   * @since 1.26.0
111
   * @param factory the factory to create a stub
112
   * @param channel the channel that this stub will use to do communications
113
   */
114
  public static <T extends AbstractStub<T>> T newStub(
115
      StubFactory<T> factory, Channel channel) {
116
    return newStub(factory, channel, CallOptions.DEFAULT);
×
117
  }
118

119
  /**
120
   * Returns a new stub with the given channel for the provided method configurations.
121
   *
122
   * @since 1.26.0
123
   * @param factory the factory to create a stub
124
   * @param channel the channel that this stub will use to do communications
125
   * @param callOptions the runtime call options to be applied to every call on this stub
126
   */
127
  public static <T extends AbstractStub<T>> T newStub(
128
      StubFactory<T> factory, Channel channel, CallOptions callOptions) {
129
    return factory.newStub(channel, callOptions);
1✔
130
  }
131

132
  /**
133
   * Returns a new stub with an absolute deadline.
134
   *
135
   * <p>This is mostly used for propagating an existing deadline. {@link #withDeadlineAfter} is the
136
   * recommended way of setting a new deadline,
137
   *
138
   * @since 1.0.0
139
   * @param deadline the deadline or {@code null} for unsetting the deadline.
140
   */
141
  public final S withDeadline(@Nullable Deadline deadline) {
142
    return build(channel, callOptions.withDeadline(deadline));
1✔
143
  }
144

145
  /**
146
   * Returns a new stub with a deadline that is after the given {@code duration} from now.
147
   *
148
   * @since 1.0.0
149
   * @see CallOptions#withDeadlineAfter
150
   */
151
  public final S withDeadlineAfter(long duration, TimeUnit unit) {
152
    return build(channel, callOptions.withDeadlineAfter(duration, unit));
1✔
153
  }
154

155
  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/11657")
156
  @IgnoreJRERequirement
157
  public final S withDeadlineAfter(Duration duration) {
158
    return withDeadlineAfter(convert(duration), TimeUnit.NANOSECONDS);
1✔
159
  }
160

161
  /**
162
   * Returns a new stub with the given executor that is to be used instead of the default one
163
   * specified with {@link ManagedChannelBuilder#executor}. Note that setting this option may not
164
   * take effect for blocking calls.
165
   *
166
   * @since 1.8.0
167
   */
168
  public final S withExecutor(Executor executor) {
169
    return build(channel, callOptions.withExecutor(executor));
1✔
170
  }
171

172
  /**
173
   *  Set's the compressor name to use for the call.  It is the responsibility of the application
174
   *  to make sure the server supports decoding the compressor picked by the client.  To be clear,
175
   *  this is the compressor used by the stub to compress messages to the server.
176
   *
177
   * @since 1.0.0
178
   * @param compressorName the name (e.g. "gzip") of the compressor to use.
179
   */
180
  public final S withCompression(String compressorName) {
181
    return build(channel, callOptions.withCompression(compressorName));
×
182
  }
183

184
  /**
185
   * Returns a new stub that uses the given channel.
186
   *
187
   * <p>This method is vestigial and is unlikely to be useful.  Instead, users should prefer to
188
   * use {@link #withInterceptors}.
189
   *
190
   * @since 1.0.0
191
   */
192
  @Deprecated // use withInterceptors() instead
193
  public final S withChannel(Channel newChannel) {
194
    return build(newChannel, callOptions);
×
195
  }
196

197
  /**
198
   * Sets a custom option to be passed to client interceptors on the channel
199
   * {@link io.grpc.ClientInterceptor} via the CallOptions parameter.
200
   *
201
   * @since 1.0.0
202
   * @param key the option being set
203
   * @param value the value for the key
204
   */
205
  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1869")
206
  public final <T> S withOption(CallOptions.Key<T> key, T value) {
207
    return build(channel, callOptions.withOption(key, value));
×
208
  }
209

210
  /**
211
   * Returns a new stub that has the given interceptors attached to the underlying channel.
212
   *
213
   * @since 1.0.0
214
   */
215
  public final S withInterceptors(ClientInterceptor... interceptors) {
216
    return build(ClientInterceptors.intercept(channel, interceptors), callOptions);
1✔
217
  }
218

219
  /**
220
   * Returns a new stub that uses the given call credentials.
221
   *
222
   * @since 1.0.0
223
   */
224
  public final S withCallCredentials(CallCredentials credentials) {
225
    return build(channel, callOptions.withCallCredentials(credentials));
×
226
  }
227

228
  /**
229
   * Returns a new stub that uses
230
   * <a href="https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md">'wait for ready'</a>
231
   * for the call. Wait-for-ready queues the RPC until a connection is available. This may
232
   * dramatically increase the latency of the RPC, but avoids failing "unnecessarily." The default
233
   * queues the RPC until an attempt to connect has completed, but fails RPCs without sending them
234
   * if unable to connect.
235
   *
236
   * @since 1.1.0
237
   */
238
  public final S withWaitForReady() {
239
    return build(channel, callOptions.withWaitForReady());
1✔
240
  }
241

242
  /**
243
   * Returns a new stub that limits the maximum acceptable message size from a remote peer.
244
   *
245
   * <p>If unset, the {@link ManagedChannelBuilder#maxInboundMessageSize(int)} limit is used.
246
   *
247
   * @since 1.1.0
248
   */
249
  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2563")
250
  public final S withMaxInboundMessageSize(int maxSize) {
251
    return build(channel, callOptions.withMaxInboundMessageSize(maxSize));
1✔
252
  }
253

254
  /**
255
   * Returns a new stub that limits the maximum acceptable message size to send a remote peer.
256
   *
257
   * @since 1.1.0
258
   */
259
  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/2563")
260
  public final S withMaxOutboundMessageSize(int maxSize) {
261
    return build(channel, callOptions.withMaxOutboundMessageSize(maxSize));
1✔
262
  }
263

264
  /**
265
   * Returns a new stub that limits the maximum number of bytes per stream in the queue.
266
   *
267
   * @since 1.1.0
268
   */
269
  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/11021")
270
  public final S withOnReadyThreshold(int numBytes) {
271
    return build(channel, callOptions.withOnReadyThreshold(numBytes));
1✔
272
  }
273

274
  /**
275
   * A factory class for stub.
276
   *
277
   * @since 1.26.0
278
   */
279
  public interface StubFactory<T extends AbstractStub<T>> {
280
    T newStub(Channel channel, CallOptions callOptions);
281
  }
282
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc