Skip to content

Commit 405217b

Browse files
authored
Merge branch 'grpc:master' into master
2 parents 0f96110 + 6da93db commit 405217b

44 files changed

Lines changed: 1034 additions & 198 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ For a guided tour, take a look at the [quick start
4444
guide](https://grpc.io/docs/languages/java/quickstart) or the more explanatory [gRPC
4545
basics](https://grpc.io/docs/languages/java/basics).
4646

47-
The [examples](https://github.com/grpc/grpc-java/tree/v1.75.0/examples) and the
48-
[Android example](https://github.com/grpc/grpc-java/tree/v1.75.0/examples/android)
47+
The [examples](https://github.com/grpc/grpc-java/tree/v1.76.0/examples) and the
48+
[Android example](https://github.com/grpc/grpc-java/tree/v1.76.0/examples/android)
4949
are standalone projects that showcase the usage of gRPC.
5050

5151
Download
@@ -56,42 +56,42 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`:
5656
<dependency>
5757
<groupId>io.grpc</groupId>
5858
<artifactId>grpc-netty-shaded</artifactId>
59-
<version>1.75.0</version>
59+
<version>1.76.0</version>
6060
<scope>runtime</scope>
6161
</dependency>
6262
<dependency>
6363
<groupId>io.grpc</groupId>
6464
<artifactId>grpc-protobuf</artifactId>
65-
<version>1.75.0</version>
65+
<version>1.76.0</version>
6666
</dependency>
6767
<dependency>
6868
<groupId>io.grpc</groupId>
6969
<artifactId>grpc-stub</artifactId>
70-
<version>1.75.0</version>
70+
<version>1.76.0</version>
7171
</dependency>
7272
```
7373

7474
Or for Gradle with non-Android, add to your dependencies:
7575
```gradle
76-
runtimeOnly 'io.grpc:grpc-netty-shaded:1.75.0'
77-
implementation 'io.grpc:grpc-protobuf:1.75.0'
78-
implementation 'io.grpc:grpc-stub:1.75.0'
76+
runtimeOnly 'io.grpc:grpc-netty-shaded:1.76.0'
77+
implementation 'io.grpc:grpc-protobuf:1.76.0'
78+
implementation 'io.grpc:grpc-stub:1.76.0'
7979
```
8080

8181
For Android client, use `grpc-okhttp` instead of `grpc-netty-shaded` and
8282
`grpc-protobuf-lite` instead of `grpc-protobuf`:
8383
```gradle
84-
implementation 'io.grpc:grpc-okhttp:1.75.0'
85-
implementation 'io.grpc:grpc-protobuf-lite:1.75.0'
86-
implementation 'io.grpc:grpc-stub:1.75.0'
84+
implementation 'io.grpc:grpc-okhttp:1.76.0'
85+
implementation 'io.grpc:grpc-protobuf-lite:1.76.0'
86+
implementation 'io.grpc:grpc-stub:1.76.0'
8787
```
8888

8989
For [Bazel](https://bazel.build), you can either
9090
[use Maven](https://github.com/bazelbuild/rules_jvm_external)
9191
(with the GAVs from above), or use `@io_grpc_grpc_java//api` et al (see below).
9292

9393
[the JARs]:
94-
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.75.0
94+
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.76.0
9595

9696
Development snapshots are available in [Sonatypes's snapshot
9797
repository](https://central.sonatype.com/repository/maven-snapshots/).
@@ -121,9 +121,9 @@ For protobuf-based codegen integrated with the Maven build system, you can use
121121
<artifactId>protobuf-maven-plugin</artifactId>
122122
<version>0.6.1</version>
123123
<configuration>
124-
<protocArtifact>com.google.protobuf:protoc:3.25.5:exe:${os.detected.classifier}</protocArtifact>
124+
<protocArtifact>com.google.protobuf:protoc:3.25.8:exe:${os.detected.classifier}</protocArtifact>
125125
<pluginId>grpc-java</pluginId>
126-
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.75.0:exe:${os.detected.classifier}</pluginArtifact>
126+
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.76.0:exe:${os.detected.classifier}</pluginArtifact>
127127
</configuration>
128128
<executions>
129129
<execution>
@@ -149,11 +149,11 @@ plugins {
149149
150150
protobuf {
151151
protoc {
152-
artifact = "com.google.protobuf:protoc:3.25.5"
152+
artifact = "com.google.protobuf:protoc:3.25.8"
153153
}
154154
plugins {
155155
grpc {
156-
artifact = 'io.grpc:protoc-gen-grpc-java:1.75.0'
156+
artifact = 'io.grpc:protoc-gen-grpc-java:1.76.0'
157157
}
158158
}
159159
generateProtoTasks {
@@ -182,11 +182,11 @@ plugins {
182182
183183
protobuf {
184184
protoc {
185-
artifact = "com.google.protobuf:protoc:3.25.5"
185+
artifact = "com.google.protobuf:protoc:3.25.8"
186186
}
187187
plugins {
188188
grpc {
189-
artifact = 'io.grpc:protoc-gen-grpc-java:1.75.0'
189+
artifact = 'io.grpc:protoc-gen-grpc-java:1.76.0'
190190
}
191191
}
192192
generateProtoTasks {

android/src/main/java/io/grpc/android/UdsChannelBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.grpc.ExperimentalApi;
2222
import io.grpc.InsecureChannelCredentials;
2323
import io.grpc.ManagedChannelBuilder;
24+
import io.grpc.internal.GrpcUtil;
2425
import java.lang.reflect.InvocationTargetException;
2526
import javax.annotation.Nullable;
2627
import javax.net.SocketFactory;
@@ -81,7 +82,7 @@ public static ManagedChannelBuilder<?> forPath(String path, Namespace namespace)
8182
OKHTTP_CHANNEL_BUILDER_CLASS
8283
.getMethod("socketFactory", SocketFactory.class)
8384
.invoke(builder, new UdsSocketFactory(path, namespace));
84-
return builder;
85+
return builder.proxyDetector(GrpcUtil.NOOP_PROXY_DETECTOR);
8586
} catch (IllegalAccessException e) {
8687
throw new RuntimeException("Failed to create OkHttpChannelBuilder", e);
8788
} catch (NoSuchMethodException e) {

binder/src/main/java/io/grpc/binder/internal/BinderClientTransport.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,6 @@ public final class BinderClientTransport extends BinderTransport
8787
@GuardedBy("this")
8888
private ScheduledFuture<?> readyTimeoutFuture; // != null iff timeout scheduled.
8989

90-
@GuardedBy("this")
91-
@Nullable
92-
private ListenableFuture<Status> authResultFuture; // null before we check auth.
93-
94-
@GuardedBy("this")
95-
@Nullable
96-
private ListenableFuture<Status> preAuthResultFuture; // null before we pre-auth.
9790

9891
/**
9992
* Constructs a new transport instance.
@@ -193,7 +186,8 @@ private void preAuthorize(ServiceInfo serviceInfo) {
193186
// unauthorized server a chance to run, but the connection will still fail by SecurityPolicy
194187
// check later in handshake. Pre-auth remains effective at mitigating abuse because malware
195188
// can't typically control the exact timing of its installation.
196-
preAuthResultFuture = checkServerAuthorizationAsync(serviceInfo.applicationInfo.uid);
189+
ListenableFuture<Status> preAuthResultFuture =
190+
register(checkServerAuthorizationAsync(serviceInfo.applicationInfo.uid));
197191
Futures.addCallback(
198192
preAuthResultFuture,
199193
new FutureCallback<Status>() {
@@ -314,12 +308,6 @@ void notifyTerminated() {
314308
readyTimeoutFuture.cancel(false);
315309
readyTimeoutFuture = null;
316310
}
317-
if (preAuthResultFuture != null) {
318-
preAuthResultFuture.cancel(false); // No effect if already complete.
319-
}
320-
if (authResultFuture != null) {
321-
authResultFuture.cancel(false); // No effect if already complete.
322-
}
323311
serviceBinding.unbind();
324312
clientTransportListener.transportTerminated();
325313
}
@@ -339,7 +327,8 @@ protected void handleSetupTransport(Parcel parcel) {
339327
} else {
340328
restrictIncomingBinderToCallsFrom(remoteUid);
341329
attributes = setSecurityAttrs(attributes, remoteUid);
342-
authResultFuture = checkServerAuthorizationAsync(remoteUid);
330+
ListenableFuture<Status> authResultFuture =
331+
register(checkServerAuthorizationAsync(remoteUid));
343332
Futures.addCallback(
344333
authResultFuture,
345334
new FutureCallback<Status>() {
@@ -398,6 +387,7 @@ protected void handlePingResponse(Parcel parcel) {
398387
pingTracker.onPingResponse(parcel.readInt());
399388
}
400389

390+
401391
private static ClientStream newFailingClientStream(
402392
Status failure, Attributes attributes, Metadata headers, ClientStreamTracer[] tracers) {
403393
StatsTraceContext statsTraceContext =

binder/src/main/java/io/grpc/binder/internal/BinderServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ public synchronized boolean handleTransaction(int code, Parcel parcel) {
185185
streamTracerFactories,
186186
OneWayBinderProxy.IDENTITY_DECORATOR,
187187
callbackBinder);
188-
transport.setServerTransportListener(listener.transportCreated(transport));
188+
transport.start(listener.transportCreated(transport));
189189
return true;
190190
}
191191
}

binder/src/main/java/io/grpc/binder/internal/BinderServerTransport.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616
package io.grpc.binder.internal;
1717

18+
import static com.google.common.base.Preconditions.checkNotNull;
19+
import static com.google.common.base.Preconditions.checkState;
20+
1821
import android.os.IBinder;
1922
import com.google.errorprone.annotations.concurrent.GuardedBy;
2023
import io.grpc.Attributes;
@@ -57,9 +60,17 @@ public BinderServerTransport(
5760
setOutgoingBinder(OneWayBinderProxy.wrap(callbackBinder, getScheduledExecutorService()));
5861
}
5962

60-
public synchronized void setServerTransportListener(
61-
ServerTransportListener serverTransportListener) {
62-
this.serverTransportListener = serverTransportListener;
63+
/**
64+
* Initializes this transport instance.
65+
*
66+
* <p>Must be called exactly once, even if {@link #shutdown} or {@link #shutdownNow} was called
67+
* first.
68+
*
69+
* @param serverTransportListener where this transport will report events
70+
*/
71+
public synchronized void start(ServerTransportListener serverTransportListener) {
72+
checkState(this.serverTransportListener == null, "Already started!");
73+
this.serverTransportListener = checkNotNull(serverTransportListener, "serverTransportListener");
6374
if (isShutdown()) {
6475
setState(TransportState.SHUTDOWN_TERMINATED);
6576
notifyTerminated();

binder/src/main/java/io/grpc/binder/internal/BinderTransport.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@
4545
import java.util.ArrayList;
4646
import java.util.Iterator;
4747
import java.util.LinkedHashSet;
48+
import java.util.List;
4849
import java.util.Map;
4950
import java.util.NoSuchElementException;
5051
import java.util.concurrent.ConcurrentHashMap;
52+
import java.util.concurrent.Future;
5153
import java.util.concurrent.ScheduledExecutorService;
5254
import java.util.logging.Level;
5355
import java.util.logging.Logger;
@@ -166,6 +168,9 @@ protected enum TransportState {
166168
@GuardedBy("this")
167169
private final LinkedHashSet<Integer> callIdsToNotifyWhenReady = new LinkedHashSet<>();
168170

171+
@GuardedBy("this")
172+
private final List<Future<?>> ownedFutures = new ArrayList<>(); // To cancel upon terminate.
173+
169174
@GuardedBy("this")
170175
protected Attributes attributes;
171176

@@ -249,6 +254,13 @@ void releaseExecutors() {
249254
executorServicePool.returnObject(scheduledExecutorService);
250255
}
251256

257+
// Registers the specified future for eventual safe cancellation upon shutdown/terminate.
258+
@GuardedBy("this")
259+
protected final <T extends Future<?>> T register(T future) {
260+
ownedFutures.add(future);
261+
return future;
262+
}
263+
252264
@GuardedBy("this")
253265
boolean inState(TransportState transportState) {
254266
return this.transportState == transportState;
@@ -299,13 +311,21 @@ final void shutdownInternal(Status shutdownStatus, boolean forceTerminate) {
299311
sendShutdownTransaction();
300312
ArrayList<Inbound<?>> calls = new ArrayList<>(ongoingCalls.values());
301313
ongoingCalls.clear();
314+
ArrayList<Future<?>> futuresToCancel = new ArrayList<>(ownedFutures);
315+
ownedFutures.clear();
302316
scheduledExecutorService.execute(
303317
() -> {
304318
for (Inbound<?> inbound : calls) {
305319
synchronized (inbound) {
306320
inbound.closeAbnormal(shutdownStatus);
307321
}
308322
}
323+
324+
for (Future<?> future : futuresToCancel) {
325+
// Not holding any locks here just in case some listener runs on a direct Executor.
326+
future.cancel(false); // No effect if already isDone().
327+
}
328+
309329
synchronized (this) {
310330
notifyTerminated();
311331
}

binder/src/test/java/io/grpc/binder/internal/BinderServerTransportTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public void setUp() throws Exception {
7474
public void testSetupTransactionFailureCausesMultipleShutdowns_b153460678() throws Exception {
7575
// Make the binder fail the setup transaction.
7676
when(mockBinder.transact(anyInt(), any(Parcel.class), isNull(), anyInt())).thenReturn(false);
77-
transport.setServerTransportListener(transportListener);
77+
transport.start(transportListener);
7878

7979
// Now shut it down.
8080
transport.shutdownNow(Status.UNKNOWN.withDescription("reasons"));
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
substitutions:
2+
_GAE_SERVICE_ACCOUNT: appengine-testing-java@grpc-testing.iam.gserviceaccount.com
3+
options:
4+
env:
5+
- BUILD_ID=$BUILD_ID
6+
- KOKORO_GAE_SERVICE=java-gae-interop-test
7+
- DUMMY_DEFAULT_VERSION=dummy-default
8+
- GRADLE_OPTS=-Dorg.gradle.jvmargs='-Xmx1g'
9+
- GRADLE_FLAGS=-PskipCodegen=true -PskipAndroid=true
10+
logging: CLOUD_LOGGING_ONLY
11+
machineType: E2_HIGHCPU_8
12+
13+
steps:
14+
- id: clean-stale-deploys
15+
name: gcr.io/cloud-builders/gcloud
16+
allowFailure: true
17+
script: |
18+
#!/usr/bin/env bash
19+
set -e
20+
echo "Cleaning out stale deploys from previous runs, it is ok if this part fails"
21+
# If the test fails, the deployment is leaked.
22+
# Delete all versions whose name is not 'dummy-default' and is older than 1 hour.
23+
# This expression is an ISO8601 relative date:
24+
# https://cloud.google.com/sdk/gcloud/reference/topic/datetimes
25+
(gcloud app versions list --format="get(version.id)" \
26+
--filter="service=$KOKORO_GAE_SERVICE AND NOT version : '$DUMMY_DEFAULT_VERSION' AND version.createTime<'-p1h'" \
27+
| xargs -i gcloud app services delete "$KOKORO_GAE_SERVICE" --version {} --quiet) || true
28+
29+
- name: gcr.io/cloud-builders/docker
30+
args: ['build', '-t', 'gae-build', 'buildscripts/gae-build/']
31+
32+
- id: build
33+
name: gae-build
34+
script: |
35+
#!/usr/bin/env bash
36+
exec ./gradlew $GRADLE_FLAGS :grpc-gae-interop-testing-jdk8:appengineStage
37+
38+
- id: deploy
39+
name: gcr.io/cloud-builders/gcloud
40+
args:
41+
- app
42+
- deploy
43+
- gae-interop-testing/gae-jdk8/build/staged-app/app.yaml
44+
- --service-account=$_GAE_SERVICE_ACCOUNT
45+
- --no-promote
46+
- --no-stop-previous-version
47+
- --version=cb-$BUILD_ID
48+
49+
- id: runInteropTestRemote
50+
name: eclipse-temurin:17-jdk
51+
env:
52+
- PROJECT_ID=$PROJECT_ID
53+
script: |
54+
#!/usr/bin/env bash
55+
exec ./gradlew $GRADLE_FLAGS --stacktrace -PgaeDeployVersion="cb-$BUILD_ID" \
56+
-PgaeProjectId="$PROJECT_ID" :grpc-gae-interop-testing-jdk8:runInteropTestRemote
57+
58+
- id: cleanup
59+
name: gcr.io/cloud-builders/gcloud
60+
script: |
61+
#!/usr/bin/env bash
62+
set -e
63+
echo "Performing cleanup now."
64+
gcloud app services delete "$KOKORO_GAE_SERVICE" --version "cb-$BUILD_ID" --quiet

buildscripts/gae-build/Dockerfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
FROM eclipse-temurin:17-jdk
2+
3+
# The AppEngine Gradle plugin downloads and runs its own gcloud to get the .jar
4+
# to link against, so we need Python even if we use gcloud deploy directly
5+
# instead of using the plugin.
6+
RUN export DEBIAN_FRONTEND=noninteractive && \
7+
apt-get update && \
8+
apt-get upgrade -y && \
9+
apt-get install -y --no-install-recommends python3 && \
10+
rm -rf /var/lib/apt/lists/*

0 commit comments

Comments
 (0)