Skip to content

Commit dfb167f

Browse files
Merge branch 'master' into master
2 parents 0933dad + c643e68 commit dfb167f

File tree

12 files changed

+156
-112
lines changed

12 files changed

+156
-112
lines changed

README.md

Lines changed: 15 additions & 15 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.74.0/examples) and the
48-
[Android example](https://github.com/grpc/grpc-java/tree/v1.74.0/examples/android)
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)
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.74.0</version>
59+
<version>1.75.0</version>
6060
<scope>runtime</scope>
6161
</dependency>
6262
<dependency>
6363
<groupId>io.grpc</groupId>
6464
<artifactId>grpc-protobuf</artifactId>
65-
<version>1.74.0</version>
65+
<version>1.75.0</version>
6666
</dependency>
6767
<dependency>
6868
<groupId>io.grpc</groupId>
6969
<artifactId>grpc-stub</artifactId>
70-
<version>1.74.0</version>
70+
<version>1.75.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.74.0'
77-
implementation 'io.grpc:grpc-protobuf:1.74.0'
78-
implementation 'io.grpc:grpc-stub:1.74.0'
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'
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.74.0'
85-
implementation 'io.grpc:grpc-protobuf-lite:1.74.0'
86-
implementation 'io.grpc:grpc-stub:1.74.0'
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'
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.74.0
94+
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.75.0
9595

9696
Development snapshots are available in [Sonatypes's snapshot
9797
repository](https://central.sonatype.com/repository/maven-snapshots/).
@@ -123,7 +123,7 @@ For protobuf-based codegen integrated with the Maven build system, you can use
123123
<configuration>
124124
<protocArtifact>com.google.protobuf:protoc:3.25.5:exe:${os.detected.classifier}</protocArtifact>
125125
<pluginId>grpc-java</pluginId>
126-
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.74.0:exe:${os.detected.classifier}</pluginArtifact>
126+
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.75.0:exe:${os.detected.classifier}</pluginArtifact>
127127
</configuration>
128128
<executions>
129129
<execution>
@@ -153,7 +153,7 @@ protobuf {
153153
}
154154
plugins {
155155
grpc {
156-
artifact = 'io.grpc:protoc-gen-grpc-java:1.74.0'
156+
artifact = 'io.grpc:protoc-gen-grpc-java:1.75.0'
157157
}
158158
}
159159
generateProtoTasks {
@@ -186,7 +186,7 @@ protobuf {
186186
}
187187
plugins {
188188
grpc {
189-
artifact = 'io.grpc:protoc-gen-grpc-java:1.74.0'
189+
artifact = 'io.grpc:protoc-gen-grpc-java:1.75.0'
190190
}
191191
}
192192
generateProtoTasks {

api/src/main/java/io/grpc/Attributes.java

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ public int hashCode() {
215215
* The helper class to build an Attributes instance.
216216
*/
217217
public static final class Builder {
218+
// Exactly one of base and newdata will be set
218219
private Attributes base;
219220
private IdentityHashMap<Key<?>, Object> newdata;
220221

@@ -225,8 +226,11 @@ private Builder(Attributes base) {
225226

226227
private IdentityHashMap<Key<?>, Object> data(int size) {
227228
if (newdata == null) {
228-
newdata = new IdentityHashMap<>(size);
229+
newdata = new IdentityHashMap<>(base.data.size() + size);
230+
newdata.putAll(base.data);
231+
base = null;
229232
}
233+
assert base == null;
230234
return newdata;
231235
}
232236

@@ -243,12 +247,11 @@ public <T> Builder set(Key<T> key, T value) {
243247
* @return this
244248
*/
245249
public <T> Builder discard(Key<T> key) {
246-
if (base.data.containsKey(key)) {
247-
IdentityHashMap<Key<?>, Object> newBaseData = new IdentityHashMap<>(base.data);
248-
newBaseData.remove(key);
249-
base = new Attributes(newBaseData);
250-
}
251-
if (newdata != null) {
250+
if (base != null) {
251+
if (base.data.containsKey(key)) {
252+
data(0).remove(key);
253+
}
254+
} else {
252255
newdata.remove(key);
253256
}
254257
return this;
@@ -264,11 +267,6 @@ public Builder setAll(Attributes other) {
264267
*/
265268
public Attributes build() {
266269
if (newdata != null) {
267-
for (Map.Entry<Key<?>, Object> entry : base.data.entrySet()) {
268-
if (!newdata.containsKey(entry.getKey())) {
269-
newdata.put(entry.getKey(), entry.getValue());
270-
}
271-
}
272270
base = new Attributes(newdata);
273271
newdata = null;
274272
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,6 @@ void notifyTerminated() {
330330
@GuardedBy("this")
331331
protected void handleSetupTransport(Parcel parcel) {
332332
int remoteUid = Binder.getCallingUid();
333-
attributes = setSecurityAttrs(attributes, remoteUid);
334333
if (inState(TransportState.SETUP)) {
335334
int version = parcel.readInt();
336335
IBinder binder = parcel.readStrongBinder();
@@ -340,6 +339,7 @@ protected void handleSetupTransport(Parcel parcel) {
340339
shutdownInternal(
341340
Status.UNAVAILABLE.withDescription("Malformed SETUP_TRANSPORT data"), true);
342341
} else {
342+
attributes = setSecurityAttrs(attributes, remoteUid);
343343
authResultFuture = checkServerAuthorizationAsync(remoteUid);
344344
Futures.addCallback(
345345
authResultFuture,

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,19 +356,32 @@ public void onServiceConnected(ComponentName className, IBinder binder) {
356356
@Override
357357
@MainThread
358358
public void onServiceDisconnected(ComponentName name) {
359-
unbindInternal(Status.UNAVAILABLE.withDescription("onServiceDisconnected: " + name));
359+
unbindInternal(
360+
Status.UNAVAILABLE.withDescription(
361+
"Server process crashed, exited or was killed (onServiceDisconnected): " + name));
360362
}
361363

362364
@Override
363365
@MainThread
364366
public void onNullBinding(ComponentName name) {
365-
unbindInternal(Status.UNIMPLEMENTED.withDescription("onNullBinding: " + name));
367+
unbindInternal(
368+
Status.UNIMPLEMENTED.withDescription(
369+
"Remote Service returned null from onBind() for "
370+
+ bindIntent
371+
+ " (onNullBinding): "
372+
+ name));
366373
}
367374

368375
@Override
369376
@MainThread
370377
public void onBindingDied(ComponentName name) {
371-
unbindInternal(Status.UNAVAILABLE.withDescription("onBindingDied: " + name));
378+
unbindInternal(
379+
Status.UNAVAILABLE.withDescription(
380+
"Remote Service component "
381+
+ name.getClassName()
382+
+ " was disabled, or its package "
383+
+ name.getPackageName()
384+
+ " was disabled, force-stopped, replaced or uninstalled (onBindingDied)."));
372385
}
373386

374387
@VisibleForTesting

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

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616

1717
package io.grpc.binder.internal;
1818

19+
import static android.os.Process.myUid;
1920
import static com.google.common.truth.Truth.assertThat;
21+
import static io.grpc.binder.internal.BinderTransport.REMOTE_UID;
22+
import static io.grpc.binder.internal.BinderTransport.SETUP_TRANSPORT;
23+
import static io.grpc.binder.internal.BinderTransport.WIRE_FORMAT_VERSION;
2024
import static java.util.concurrent.TimeUnit.MILLISECONDS;
2125
import static org.mockito.Mockito.never;
2226
import static org.mockito.Mockito.timeout;
@@ -28,6 +32,8 @@
2832
import android.content.pm.ApplicationInfo;
2933
import android.content.pm.PackageInfo;
3034
import android.content.pm.ServiceInfo;
35+
import android.os.Binder;
36+
import android.os.Parcel;
3137
import androidx.test.core.app.ApplicationProvider;
3238
import androidx.test.core.content.pm.ApplicationInfoBuilder;
3339
import androidx.test.core.content.pm.PackageInfoBuilder;
@@ -38,9 +44,11 @@
3844
import io.grpc.binder.AndroidComponentAddress;
3945
import io.grpc.binder.ApiConstants;
4046
import io.grpc.binder.AsyncSecurityPolicy;
47+
import io.grpc.binder.SecurityPolicies;
4148
import io.grpc.binder.internal.SettableAsyncSecurityPolicy.AuthRequest;
4249
import io.grpc.internal.AbstractTransportTest;
4350
import io.grpc.internal.ClientTransportFactory.ClientTransportOptions;
51+
import io.grpc.internal.ConnectionClientTransport;
4452
import io.grpc.internal.GrpcUtil;
4553
import io.grpc.internal.InternalServer;
4654
import io.grpc.internal.ManagedClientTransport;
@@ -109,7 +117,7 @@ public static ImmutableList<Boolean> data() {
109117
public void setUp() {
110118
serverAppInfo =
111119
ApplicationInfoBuilder.newBuilder().setPackageName("the.server.package").build();
112-
serverAppInfo.uid = android.os.Process.myUid();
120+
serverAppInfo.uid = myUid();
113121
serverPkgInfo =
114122
PackageInfoBuilder.newBuilder()
115123
.setPackageName(serverAppInfo.packageName)
@@ -264,6 +272,38 @@ public void eagAttributeCanOverrideChannelPreAuthServerSetting() throws Exceptio
264272
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportReady();
265273
}
266274

275+
@Test
276+
public void clientIgnoresDuplicateSetupTransaction() throws Exception {
277+
server.start(serverListener);
278+
client =
279+
newClientTransportBuilder()
280+
.setFactory(
281+
newClientTransportFactoryBuilder()
282+
.setSecurityPolicy(SecurityPolicies.internalOnly())
283+
.buildClientTransportFactory())
284+
.build();
285+
runIfNotNull(client.start(mockClientTransportListener));
286+
verify(mockClientTransportListener, timeout(TIMEOUT_MS)).transportReady();
287+
288+
assertThat(((ConnectionClientTransport) client).getAttributes().get(REMOTE_UID))
289+
.isEqualTo(myUid());
290+
291+
Parcel setupParcel = Parcel.obtain();
292+
try {
293+
setupParcel.writeInt(WIRE_FORMAT_VERSION);
294+
setupParcel.writeStrongBinder(new Binder());
295+
setupParcel.setDataPosition(0);
296+
ShadowBinder.setCallingUid(1 + myUid());
297+
((BinderClientTransport) client).handleTransaction(SETUP_TRANSPORT, setupParcel);
298+
} finally {
299+
ShadowBinder.setCallingUid(myUid());
300+
setupParcel.recycle();
301+
}
302+
303+
assertThat(((ConnectionClientTransport) client).getAttributes().get(REMOTE_UID))
304+
.isEqualTo(myUid());
305+
}
306+
267307
@Test
268308
@Ignore("See BinderTransportTest#socketStats.")
269309
@Override

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ subprojects {
238238

239239
// At a test failure, log the stack trace to the console so that we don't
240240
// have to open the HTML in a browser.
241-
tasks.named("test").configure {
241+
tasks.withType(Test).configureEach {
242242
testLogging {
243243
exceptionFormat = 'full'
244244
showExceptions = true

gradle/libs.versions.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ jetty-servlet = "org.eclipse.jetty.ee10:jetty-ee10-servlet:12.0.16"
6969
jetty-servlet10 = "org.eclipse.jetty:jetty-servlet:10.0.20"
7070
jsr305 = "com.google.code.findbugs:jsr305:3.0.2"
7171
junit = "junit:junit:4.13.2"
72-
# 2.17+ require Java 11+ (not mentioned in release notes)
73-
lincheck = "org.jetbrains.kotlinx:lincheck-jvm:2.16"
72+
lincheck = "org.jetbrains.lincheck:lincheck:3.2"
7473
# Update notes / 2023-07-19 sergiitk:
7574
# Couldn't update to 5.4.0, updated to the last in 4.x line. Version 5.x breaks some tests.
7675
# Error log: https://github.com/grpc/grpc-java/pull/10359#issuecomment-1632834435
@@ -112,7 +111,7 @@ signature-java = "org.codehaus.mojo.signature:java18:1.0"
112111
tomcat-embed-core = "org.apache.tomcat.embed:tomcat-embed-core:10.1.31"
113112
tomcat-embed-core9 = "org.apache.tomcat.embed:tomcat-embed-core:9.0.89"
114113
truth = "com.google.truth:truth:1.4.4"
115-
undertow-servlet22 = "io.undertow:undertow-servlet:2.2.32.Final"
114+
undertow-servlet22 = "io.undertow:undertow-servlet:2.2.37.Final"
116115
undertow-servlet = "io.undertow:undertow-servlet:2.3.18.Final"
117116

118117
# Do not update: Pinned to the last version supporting Java 8.

servlet/build.gradle

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ dependencies {
4343
testImplementation libraries.javax.servlet.api
4444

4545
threadingTestImplementation project(':grpc-servlet'),
46-
libraries.truth,
46+
libraries.junit,
4747
libraries.javax.servlet.api,
4848
libraries.lincheck
4949

@@ -69,19 +69,12 @@ dependencies {
6969
libraries.protobuf.java
7070
}
7171

72-
tasks.named("test").configure {
73-
if (JavaVersion.current().isJava9Compatible()) {
74-
jvmArgs += [
75-
// required for Lincheck
76-
'--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED',
77-
'--add-exports=java.base/jdk.internal.util=ALL-UNNAMED',
78-
]
79-
}
80-
}
81-
8272
tasks.register('threadingTest', Test) {
8373
classpath = sourceSets.threadingTest.runtimeClasspath
8474
testClassesDirs = sourceSets.threadingTest.output.classesDirs
75+
jacoco {
76+
enabled = false
77+
}
8578
}
8679

8780
tasks.named("assemble").configure {

servlet/src/main/java/io/grpc/servlet/AsyncServletOutputStreamWriter.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
import io.grpc.InternalLogId;
2727
import io.grpc.servlet.ServletServerStream.ServletTransportState;
2828
import java.io.IOException;
29-
import java.time.Duration;
3029
import java.util.Queue;
3130
import java.util.concurrent.ConcurrentLinkedQueue;
31+
import java.util.concurrent.TimeUnit;
3232
import java.util.concurrent.atomic.AtomicReference;
3333
import java.util.concurrent.locks.LockSupport;
3434
import java.util.function.BiFunction;
@@ -128,7 +128,7 @@ public void finest(String str, Object... params) {
128128
log.fine("call completed");
129129
});
130130
};
131-
this.isReady = () -> outputStream.isReady();
131+
this.isReady = outputStream::isReady;
132132
}
133133

134134
/**
@@ -173,7 +173,9 @@ void complete() {
173173
/** Called from the container thread {@link javax.servlet.WriteListener#onWritePossible()}. */
174174
void onWritePossible() throws IOException {
175175
log.finest("onWritePossible: ENTRY. The servlet output stream becomes ready");
176-
assureReadyAndDrainedTurnsFalse();
176+
if (writeState.get().readyAndDrained) {
177+
assureReadyAndDrainedTurnsFalse();
178+
}
177179
while (isReady.getAsBoolean()) {
178180
WriteState curState = writeState.get();
179181

@@ -200,11 +202,9 @@ private void assureReadyAndDrainedTurnsFalse() {
200202
// readyAndDrained should have been set to false already.
201203
// Just in case due to a race condition readyAndDrained is still true at this moment and is
202204
// being set to false by runOrBuffer() concurrently.
205+
parkingThread = Thread.currentThread();
203206
while (writeState.get().readyAndDrained) {
204-
parkingThread = Thread.currentThread();
205-
// Try to sleep for an extremely long time to avoid writeState being changed at exactly
206-
// the time when sleep time expires (in extreme scenario, such as #9917).
207-
LockSupport.parkNanos(Duration.ofHours(1).toNanos()); // should return immediately
207+
LockSupport.parkNanos(TimeUnit.MINUTES.toNanos(1)); // should return immediately
208208
}
209209
parkingThread = null;
210210
}
@@ -254,7 +254,7 @@ interface ActionItem {
254254
@VisibleForTesting // Lincheck test can not run with java.util.logging dependency.
255255
interface Log {
256256
default boolean isLoggable(Level level) {
257-
return false;
257+
return false;
258258
}
259259

260260
default void fine(String str, Object...params) {}

servlet/src/main/java/io/grpc/servlet/ServletAdapter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,9 @@ private static final class GrpcAsyncListener implements AsyncListener {
215215
}
216216

217217
@Override
218-
public void onComplete(AsyncEvent event) {}
218+
public void onComplete(AsyncEvent event) {
219+
stream.asyncCompleted = true;
220+
}
219221

220222
@Override
221223
public void onTimeout(AsyncEvent event) {

0 commit comments

Comments
 (0)