Skip to content

Commit 3ddb0f6

Browse files
committed
Only create hard-coded when it is being used
1 parent 76b245e commit 3ddb0f6

File tree

8 files changed

+47
-25
lines changed

8 files changed

+47
-25
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public static <T> List<T> loadAll(
3838
return loadAll(
3939
klass,
4040
ServiceLoader.load(klass, classLoader).iterator(),
41-
hardCodedClasses,
41+
() -> hardCodedClasses,
4242
priorityAccessor);
4343
}
4444

@@ -48,9 +48,9 @@ public static <T> List<T> loadAll(
4848
public static <T> List<T> loadAll(
4949
Class<T> klass,
5050
Iterator<T> serviceLoader,
51-
Iterable<Class<?>> hardCodedClasses,
51+
Supplier<Iterable<Class<?>>> hardCodedClasses,
5252
PriorityAccessor<T> priorityAccessor) {
53-
return ServiceProviders.loadAll(klass, serviceLoader, hardCodedClasses, priorityAccessor);
53+
return ServiceProviders.loadAll(klass, serviceLoader, hardCodedClasses::get, priorityAccessor);
5454
}
5555

5656
/**
@@ -78,4 +78,8 @@ public static boolean isAndroid(ClassLoader cl) {
7878
}
7979

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

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
public final class LoadBalancerRegistry {
4444
private static final Logger logger = Logger.getLogger(LoadBalancerRegistry.class.getName());
4545
private static LoadBalancerRegistry instance;
46-
private static final Iterable<Class<?>> HARDCODED_CLASSES = getHardCodedClasses();
4746

4847
private final LinkedHashSet<LoadBalancerProvider> allProviders =
4948
new LinkedHashSet<>();
@@ -105,7 +104,7 @@ public static synchronized LoadBalancerRegistry getDefaultRegistry() {
105104
ServiceLoader
106105
.load(LoadBalancerProvider.class, LoadBalancerProvider.class.getClassLoader())
107106
.iterator(),
108-
HARDCODED_CLASSES,
107+
LoadBalancerRegistry::getHardCodedClasses,
109108
new LoadBalancerPriorityAccessor());
110109
instance = new LoadBalancerRegistry();
111110
for (LoadBalancerProvider provider : providerList) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public static synchronized ManagedChannelRegistry getDefaultRegistry() {
104104
ServiceLoader
105105
.load(ManagedChannelProvider.class, ManagedChannelProvider.class.getClassLoader())
106106
.iterator(),
107-
getHardCodedClasses(),
107+
ManagedChannelRegistry::getHardCodedClasses,
108108
new ManagedChannelPriorityAccessor());
109109
instance = new ManagedChannelRegistry();
110110
for (ManagedChannelProvider provider : providerList) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public static synchronized NameResolverRegistry getDefaultRegistry() {
129129
ServiceLoader
130130
.load(NameResolverProvider.class, NameResolverProvider.class.getClassLoader())
131131
.iterator(),
132-
getHardCodedClasses(),
132+
NameResolverRegistry::getHardCodedClasses,
133133
new NameResolverPriorityAccessor());
134134
if (providerList.isEmpty()) {
135135
logger.warning("No NameResolverProviders found via ServiceLoader, including for DNS. This "

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public static synchronized ServerRegistry getDefaultRegistry() {
9696
ServerProvider.class,
9797
ServiceLoader.load(ServerProvider.class, ServerProvider.class.getClassLoader())
9898
.iterator(),
99-
getHardCodedClasses(),
99+
ServerRegistry::getHardCodedClasses,
100100
new ServerPriorityAccessor());
101101
instance = new ServerRegistry();
102102
for (ServerProvider provider : providerList) {

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
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;
@@ -44,7 +45,7 @@ private ServiceProviders() {
4445
public static <T> List<T> loadAll(
4546
Class<T> klass,
4647
Iterator<T> serviceLoader,
47-
Iterable<Class<?>> hardcoded,
48+
Supplier<Iterable<Class<?>>> hardcoded,
4849
final PriorityAccessor<T> priorityAccessor) {
4950
Iterator<T> candidates;
5051
if (serviceLoader instanceof ListIterator) {
@@ -58,7 +59,7 @@ public static <T> List<T> loadAll(
5859
candidates = serviceLoader;
5960
} else if (isAndroid(klass.getClassLoader())) {
6061
// Avoid getResource() on Android, which must read from a zip which uses a lot of memory
61-
candidates = getCandidatesViaHardCoded(klass, hardcoded).iterator();
62+
candidates = getCandidatesViaHardCoded(klass, hardcoded.get()).iterator();
6263
} else if (!serviceLoader.hasNext()) {
6364
// Attempt to load using the context class loader and ServiceLoader.
6465
// This allows frameworks like http://aries.apache.org/modules/spi-fly.html to plug in.

api/src/test/java/io/grpc/ServiceProvidersTest.java

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,30 @@
1616

1717
package io.grpc;
1818

19+
import static com.google.common.truth.Truth.assertThat;
1920
import static org.junit.Assert.assertEquals;
2021
import static org.junit.Assert.assertFalse;
2122
import static org.junit.Assert.assertNull;
2223
import static org.junit.Assert.assertSame;
2324
import static org.junit.Assert.assertTrue;
2425
import static org.junit.Assert.fail;
2526

27+
import com.google.common.base.Supplier;
2628
import com.google.common.collect.ImmutableList;
2729
import io.grpc.InternalServiceProviders.PriorityAccessor;
2830
import java.util.Collections;
2931
import java.util.Iterator;
3032
import java.util.List;
3133
import java.util.ServiceConfigurationError;
3234
import java.util.ServiceLoader;
35+
import org.junit.After;
3336
import org.junit.Test;
3437
import org.junit.runner.RunWith;
3538
import org.junit.runners.JUnit4;
3639

3740
/** Unit tests for {@link ServiceProviders}. */
3841
@RunWith(JUnit4.class)
3942
public class ServiceProvidersTest {
40-
private static final List<Class<?>> NO_HARDCODED = Collections.emptyList();
4143
private static final PriorityAccessor<ServiceProvidersTestAbstractProvider> ACCESSOR =
4244
new PriorityAccessor<ServiceProvidersTestAbstractProvider>() {
4345
@Override
@@ -52,6 +54,19 @@ public int getPriority(ServiceProvidersTestAbstractProvider provider) {
5254
};
5355
private final String serviceFile =
5456
"META-INF/services/io.grpc.ServiceProvidersTestAbstractProvider";
57+
private boolean failingHardCodedAccessed;
58+
private final Supplier<Iterable<Class<?>>> failingHardCoded = new Supplier<Iterable<Class<?>>>() {
59+
@Override
60+
public Iterable<Class<?>> get() {
61+
failingHardCodedAccessed = true;
62+
throw new AssertionError();
63+
}
64+
};
65+
66+
@After
67+
public void tearDown() {
68+
assertThat(failingHardCodedAccessed).isFalse();
69+
}
5570

5671
@Test
5772
public void contextClassLoaderProvider() {
@@ -70,7 +85,8 @@ public void contextClassLoaderProvider() {
7085
Thread.currentThread().setContextClassLoader(rcll);
7186
assertEquals(
7287
Available7Provider.class,
73-
load(ServiceProvidersTestAbstractProvider.class, NO_HARDCODED, cl, ACCESSOR).getClass());
88+
load(ServiceProvidersTestAbstractProvider.class, failingHardCoded, cl, ACCESSOR)
89+
.getClass());
7490
} finally {
7591
Thread.currentThread().setContextClassLoader(ccl);
7692
}
@@ -85,7 +101,7 @@ public void noProvider() {
85101
serviceFile,
86102
"io/grpc/ServiceProvidersTestAbstractProvider-doesNotExist.txt");
87103
Thread.currentThread().setContextClassLoader(cl);
88-
assertNull(load(ServiceProvidersTestAbstractProvider.class, NO_HARDCODED, cl, ACCESSOR));
104+
assertNull(load(ServiceProvidersTestAbstractProvider.class, failingHardCoded, cl, ACCESSOR));
89105
} finally {
90106
Thread.currentThread().setContextClassLoader(ccl);
91107
}
@@ -97,10 +113,11 @@ public void multipleProvider() throws Exception {
97113
"io/grpc/ServiceProvidersTestAbstractProvider-multipleProvider.txt");
98114
assertSame(
99115
Available7Provider.class,
100-
load(ServiceProvidersTestAbstractProvider.class, NO_HARDCODED, cl, ACCESSOR).getClass());
116+
load(ServiceProvidersTestAbstractProvider.class, failingHardCoded, cl, ACCESSOR)
117+
.getClass());
101118

102119
List<ServiceProvidersTestAbstractProvider> providers = loadAll(
103-
ServiceProvidersTestAbstractProvider.class, NO_HARDCODED, cl, ACCESSOR);
120+
ServiceProvidersTestAbstractProvider.class, failingHardCoded, cl, ACCESSOR);
104121
assertEquals(3, providers.size());
105122
assertEquals(Available7Provider.class, providers.get(0).getClass());
106123
assertEquals(Available5Provider.class, providers.get(1).getClass());
@@ -114,15 +131,16 @@ public void unavailableProvider() {
114131
"io/grpc/ServiceProvidersTestAbstractProvider-unavailableProvider.txt");
115132
assertEquals(
116133
Available7Provider.class,
117-
load(ServiceProvidersTestAbstractProvider.class, NO_HARDCODED, cl, ACCESSOR).getClass());
134+
load(ServiceProvidersTestAbstractProvider.class, failingHardCoded, cl, ACCESSOR)
135+
.getClass());
118136
}
119137

120138
@Test
121139
public void unknownClassProvider() {
122140
ClassLoader cl = new ReplacingClassLoader(getClass().getClassLoader(), serviceFile,
123141
"io/grpc/ServiceProvidersTestAbstractProvider-unknownClassProvider.txt");
124142
try {
125-
loadAll(ServiceProvidersTestAbstractProvider.class, NO_HARDCODED, cl, ACCESSOR);
143+
loadAll(ServiceProvidersTestAbstractProvider.class, failingHardCoded, cl, ACCESSOR);
126144
fail("Exception expected");
127145
} catch (ServiceConfigurationError e) {
128146
// noop
@@ -136,7 +154,7 @@ public void exceptionSurfacedToCaller_failAtInit() {
136154
try {
137155
// Even though there is a working provider, if any providers fail then we should fail
138156
// completely to avoid returning something unexpected.
139-
loadAll(ServiceProvidersTestAbstractProvider.class, NO_HARDCODED, cl, ACCESSOR);
157+
loadAll(ServiceProvidersTestAbstractProvider.class, failingHardCoded, cl, ACCESSOR);
140158
fail("Expected exception");
141159
} catch (ServiceConfigurationError expected) {
142160
// noop
@@ -149,7 +167,7 @@ public void exceptionSurfacedToCaller_failAtPriority() {
149167
"io/grpc/ServiceProvidersTestAbstractProvider-failAtPriorityProvider.txt");
150168
try {
151169
// The exception should be surfaced to the caller
152-
loadAll(ServiceProvidersTestAbstractProvider.class, NO_HARDCODED, cl, ACCESSOR);
170+
loadAll(ServiceProvidersTestAbstractProvider.class, failingHardCoded, cl, ACCESSOR);
153171
fail("Expected exception");
154172
} catch (FailAtPriorityProvider.PriorityException expected) {
155173
// noop
@@ -162,7 +180,7 @@ public void exceptionSurfacedToCaller_failAtAvailable() {
162180
"io/grpc/ServiceProvidersTestAbstractProvider-failAtAvailableProvider.txt");
163181
try {
164182
// The exception should be surfaced to the caller
165-
loadAll(ServiceProvidersTestAbstractProvider.class, NO_HARDCODED, cl, ACCESSOR);
183+
loadAll(ServiceProvidersTestAbstractProvider.class, failingHardCoded, cl, ACCESSOR);
166184
fail("Expected exception");
167185
} catch (FailAtAvailableProvider.AvailableException expected) {
168186
// noop
@@ -239,10 +257,10 @@ class RandomClass {}
239257

240258
private static <T> T load(
241259
Class<T> klass,
242-
Iterable<Class<?>> hardcoded,
260+
Supplier<Iterable<Class<?>>> hardCoded,
243261
ClassLoader cl,
244262
PriorityAccessor<T> priorityAccessor) {
245-
List<T> candidates = loadAll(klass, hardcoded, cl, priorityAccessor);
263+
List<T> candidates = loadAll(klass, hardCoded, cl, priorityAccessor);
246264
if (candidates.isEmpty()) {
247265
return null;
248266
}
@@ -251,13 +269,13 @@ private static <T> T load(
251269

252270
private static <T> List<T> loadAll(
253271
Class<T> klass,
254-
Iterable<Class<?>> hardcoded,
272+
Supplier<Iterable<Class<?>>> hardCoded,
255273
ClassLoader classLoader,
256274
PriorityAccessor<T> priorityAccessor) {
257275
return ServiceProviders.loadAll(
258276
klass,
259277
ServiceLoader.load(klass, classLoader).iterator(),
260-
hardcoded,
278+
hardCoded,
261279
priorityAccessor);
262280
}
263281

xds/src/main/java/io/grpc/xds/XdsCredentialsRegistry.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public static synchronized XdsCredentialsRegistry getDefaultRegistry() {
113113
ServiceLoader
114114
.load(XdsCredentialsProvider.class, XdsCredentialsProvider.class.getClassLoader())
115115
.iterator(),
116-
getHardCodedClasses(),
116+
XdsCredentialsRegistry::getHardCodedClasses,
117117
new XdsCredentialsProviderPriorityAccessor());
118118
if (providerList.isEmpty()) {
119119
logger.warning("No XdsCredsRegistry found via ServiceLoader, including for GoogleDefault, "

0 commit comments

Comments
 (0)