Skip to content

Commit 7634dff

Browse files
authored
Merge branch 'grpc:master' into grpc-uri-xds
2 parents 5762219 + fc08423 commit 7634dff

73 files changed

Lines changed: 817 additions & 425 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.

MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module(
22
name = "grpc-java",
3-
version = "1.80.0-SNAPSHOT", # CURRENT_GRPC_VERSION
3+
version = "1.81.0-SNAPSHOT", # CURRENT_GRPC_VERSION
44
compatibility_level = 0,
55
repo_name = "io_grpc_grpc_java",
66
)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ gRPC-Java - An RPC library and framework
2020
Supported Platforms
2121
-------------------
2222

23-
gRPC-Java supports Java 8 and later. Android minSdkVersion 21 (Lollipop) and
23+
gRPC-Java supports Java 8 and later. Android minSdkVersion 23 (Marshmallow) and
2424
later are supported with [Java 8 language desugaring][android-java-8].
2525

2626
TLS usage on Android typically requires Play Services Dynamic Security Provider.

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ android {
1414
}
1515
compileSdkVersion 34
1616
defaultConfig {
17-
minSdkVersion 22
17+
minSdkVersion 23
1818
targetSdkVersion 33
1919
versionCode 1
2020
versionName "1.0"

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
package io.grpc;
1818

1919
import com.google.common.annotations.VisibleForTesting;
20+
import java.util.Iterator;
2021
import java.util.List;
22+
import java.util.ServiceLoader;
2123

2224
@Internal
2325
public final class InternalServiceProviders {
@@ -27,12 +29,28 @@ private InternalServiceProviders() {
2729
/**
2830
* Accessor for method.
2931
*/
32+
@Deprecated
3033
public static <T> List<T> loadAll(
3134
Class<T> klass,
3235
Iterable<Class<?>> hardCodedClasses,
3336
ClassLoader classLoader,
3437
PriorityAccessor<T> priorityAccessor) {
35-
return ServiceProviders.loadAll(klass, hardCodedClasses, classLoader, priorityAccessor);
38+
return loadAll(
39+
klass,
40+
ServiceLoader.load(klass, classLoader).iterator(),
41+
() -> hardCodedClasses,
42+
priorityAccessor);
43+
}
44+
45+
/**
46+
* Accessor for method.
47+
*/
48+
public static <T> List<T> loadAll(
49+
Class<T> klass,
50+
Iterator<T> serviceLoader,
51+
Supplier<Iterable<Class<?>>> hardCodedClasses,
52+
PriorityAccessor<T> priorityAccessor) {
53+
return ServiceProviders.loadAll(klass, serviceLoader, hardCodedClasses::get, priorityAccessor);
3654
}
3755

3856
/**
@@ -60,4 +78,8 @@ public static boolean isAndroid(ClassLoader cl) {
6078
}
6179

6280
public interface PriorityAccessor<T> extends ServiceProviders.PriorityAccessor<T> {}
81+
82+
public interface Supplier<T> {
83+
T get();
84+
}
6385
}

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,8 @@ private PickResult(
632632
* stream is created at all in some cases.
633633
* @since 1.3.0
634634
*/
635+
// TODO(shivaspeaks): Need to deprecate old APIs and create new ones,
636+
// per https://github.com/grpc/grpc-java/issues/12662.
635637
public static PickResult withSubchannel(
636638
Subchannel subchannel, @Nullable ClientStreamTracer.Factory streamTracerFactory) {
637639
return new PickResult(
@@ -661,6 +663,28 @@ public static PickResult withSubchannel(Subchannel subchannel) {
661663
return withSubchannel(subchannel, null);
662664
}
663665

666+
/**
667+
* Creates a new {@code PickResult} with the given {@code subchannel},
668+
* but retains all other properties from this {@code PickResult}.
669+
*
670+
* @since 1.80.0
671+
*/
672+
public PickResult copyWithSubchannel(Subchannel subchannel) {
673+
return new PickResult(checkNotNull(subchannel, "subchannel"), streamTracerFactory,
674+
status, drop, authorityOverride);
675+
}
676+
677+
/**
678+
* Creates a new {@code PickResult} with the given {@code streamTracerFactory},
679+
* but retains all other properties from this {@code PickResult}.
680+
*
681+
* @since 1.80.0
682+
*/
683+
public PickResult copyWithStreamTracerFactory(
684+
@Nullable ClientStreamTracer.Factory streamTracerFactory) {
685+
return new PickResult(subchannel, streamTracerFactory, status, drop, authorityOverride);
686+
}
687+
664688
/**
665689
* A decision to report a connectivity error to the RPC. If the RPC is {@link
666690
* CallOptions#withWaitForReady wait-for-ready}, it will stay buffered. Otherwise, it will fail

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.LinkedHashSet;
2727
import java.util.List;
2828
import java.util.Map;
29+
import java.util.ServiceLoader;
2930
import java.util.logging.Level;
3031
import java.util.logging.Logger;
3132
import javax.annotation.Nullable;
@@ -42,7 +43,6 @@
4243
public final class LoadBalancerRegistry {
4344
private static final Logger logger = Logger.getLogger(LoadBalancerRegistry.class.getName());
4445
private static LoadBalancerRegistry instance;
45-
private static final Iterable<Class<?>> HARDCODED_CLASSES = getHardCodedClasses();
4646

4747
private final LinkedHashSet<LoadBalancerProvider> allProviders =
4848
new LinkedHashSet<>();
@@ -101,8 +101,10 @@ public static synchronized LoadBalancerRegistry getDefaultRegistry() {
101101
if (instance == null) {
102102
List<LoadBalancerProvider> providerList = ServiceProviders.loadAll(
103103
LoadBalancerProvider.class,
104-
HARDCODED_CLASSES,
105-
LoadBalancerProvider.class.getClassLoader(),
104+
ServiceLoader
105+
.load(LoadBalancerProvider.class, LoadBalancerProvider.class.getClassLoader())
106+
.iterator(),
107+
LoadBalancerRegistry::getHardCodedClasses,
106108
new LoadBalancerPriorityAccessor());
107109
instance = new LoadBalancerRegistry();
108110
for (LoadBalancerProvider provider : providerList) {

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.Comparator;
3030
import java.util.LinkedHashSet;
3131
import java.util.List;
32+
import java.util.ServiceLoader;
3233
import java.util.logging.Level;
3334
import java.util.logging.Logger;
3435
import javax.annotation.concurrent.ThreadSafe;
@@ -100,8 +101,10 @@ public static synchronized ManagedChannelRegistry getDefaultRegistry() {
100101
if (instance == null) {
101102
List<ManagedChannelProvider> providerList = ServiceProviders.loadAll(
102103
ManagedChannelProvider.class,
103-
getHardCodedClasses(),
104-
ManagedChannelProvider.class.getClassLoader(),
104+
ServiceLoader
105+
.load(ManagedChannelProvider.class, ManagedChannelProvider.class.getClassLoader())
106+
.iterator(),
107+
ManagedChannelRegistry::getHardCodedClasses,
105108
new ManagedChannelPriorityAccessor());
106109
instance = new ManagedChannelRegistry();
107110
for (ManagedChannelProvider provider : providerList) {

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.List;
3030
import java.util.Locale;
3131
import java.util.Map;
32+
import java.util.ServiceLoader;
3233
import java.util.logging.Level;
3334
import java.util.logging.Logger;
3435
import javax.annotation.Nullable;
@@ -125,8 +126,10 @@ public static synchronized NameResolverRegistry getDefaultRegistry() {
125126
if (instance == null) {
126127
List<NameResolverProvider> providerList = ServiceProviders.loadAll(
127128
NameResolverProvider.class,
128-
getHardCodedClasses(),
129-
NameResolverProvider.class.getClassLoader(),
129+
ServiceLoader
130+
.load(NameResolverProvider.class, NameResolverProvider.class.getClassLoader())
131+
.iterator(),
132+
NameResolverRegistry::getHardCodedClasses,
130133
new NameResolverPriorityAccessor());
131134
if (providerList.isEmpty()) {
132135
logger.warning("No NameResolverProviders found via ServiceLoader, including for DNS. This "

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Comparator;
2525
import java.util.LinkedHashSet;
2626
import java.util.List;
27+
import java.util.ServiceLoader;
2728
import java.util.logging.Level;
2829
import java.util.logging.Logger;
2930
import javax.annotation.concurrent.ThreadSafe;
@@ -93,8 +94,9 @@ public static synchronized ServerRegistry getDefaultRegistry() {
9394
if (instance == null) {
9495
List<ServerProvider> providerList = ServiceProviders.loadAll(
9596
ServerProvider.class,
96-
getHardCodedClasses(),
97-
ServerProvider.class.getClassLoader(),
97+
ServiceLoader.load(ServerProvider.class, ServerProvider.class.getClassLoader())
98+
.iterator(),
99+
ServerRegistry::getHardCodedClasses,
98100
new ServerPriorityAccessor());
99101
instance = new ServerRegistry();
100102
for (ServerProvider provider : providerList) {

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

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717
package io.grpc;
1818

1919
import com.google.common.annotations.VisibleForTesting;
20+
import com.google.common.base.Supplier;
2021
import java.util.ArrayList;
2122
import java.util.Collections;
2223
import java.util.Comparator;
24+
import java.util.Iterator;
2325
import java.util.List;
26+
import java.util.ListIterator;
2427
import java.util.ServiceConfigurationError;
2528
import java.util.ServiceLoader;
2629

@@ -34,20 +37,39 @@ private ServiceProviders() {
3437
* {@link ServiceLoader}.
3538
* If this is Android, returns all available implementations in {@code hardcoded}.
3639
* The list is sorted in descending priority order.
40+
*
41+
* <p>{@code serviceLoader} should be created with {@code ServiceLoader.load(MyClass.class,
42+
* MyClass.class.getClassLoader()).iterator()} in order to be detected by R8 so that R8 full mode
43+
* will keep the constructors for the provider classes.
3744
*/
3845
public static <T> List<T> loadAll(
3946
Class<T> klass,
40-
Iterable<Class<?>> hardcoded,
41-
ClassLoader cl,
47+
Iterator<T> serviceLoader,
48+
Supplier<Iterable<Class<?>>> hardcoded,
4249
final PriorityAccessor<T> priorityAccessor) {
43-
Iterable<T> candidates;
44-
if (isAndroid(cl)) {
45-
candidates = getCandidatesViaHardCoded(klass, hardcoded);
50+
Iterator<T> candidates;
51+
if (serviceLoader instanceof ListIterator) {
52+
// A rewriting tool has replaced the ServiceLoader with a List of some sort (R8 uses
53+
// ArrayList, AppReduce uses singletonList). We prefer to use such iterators on Android as
54+
// they won't need reflection like the hard-coded list does. In addition, the provider
55+
// instances will have already been created, so it seems we should use them.
56+
//
57+
// R8: https://r8.googlesource.com/r8/+/490bc53d9310d4cc2a5084c05df4aadaec8c885d/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
58+
// AppReduce: service_loader_pass.cc
59+
candidates = serviceLoader;
60+
} else if (isAndroid(klass.getClassLoader())) {
61+
// Avoid getResource() on Android, which must read from a zip which uses a lot of memory
62+
candidates = getCandidatesViaHardCoded(klass, hardcoded.get()).iterator();
63+
} else if (!serviceLoader.hasNext()) {
64+
// Attempt to load using the context class loader and ServiceLoader.
65+
// This allows frameworks like http://aries.apache.org/modules/spi-fly.html to plug in.
66+
candidates = ServiceLoader.load(klass).iterator();
4667
} else {
47-
candidates = getCandidatesViaServiceLoader(klass, cl);
68+
candidates = serviceLoader;
4869
}
4970
List<T> list = new ArrayList<>();
50-
for (T current: candidates) {
71+
while (candidates.hasNext()) {
72+
T current = candidates.next();
5173
if (!priorityAccessor.isAvailable(current)) {
5274
continue;
5375
}
@@ -84,15 +106,14 @@ static boolean isAndroid(ClassLoader cl) {
84106
}
85107

86108
/**
87-
* Loads service providers for the {@code klass} service using {@link ServiceLoader}.
109+
* For testing only: Loads service providers for the {@code klass} service using {@link
110+
* ServiceLoader}. Does not support spi-fly and related tricks.
88111
*/
89112
@VisibleForTesting
90113
public static <T> Iterable<T> getCandidatesViaServiceLoader(Class<T> klass, ClassLoader cl) {
91114
Iterable<T> i = ServiceLoader.load(klass, cl);
92-
// Attempt to load using the context class loader and ServiceLoader.
93-
// This allows frameworks like http://aries.apache.org/modules/spi-fly.html to plug in.
94115
if (!i.iterator().hasNext()) {
95-
i = ServiceLoader.load(klass);
116+
return null;
96117
}
97118
return i;
98119
}

0 commit comments

Comments
 (0)