Skip to content

Commit c637b42

Browse files
committed
core: Stop using context ClassLoader in Providers
currentThread().getContextClassLoader() was originally used to match ServiceLoader's default. ServiceLoader is mostly used with SPIs that exist in the bootclasspath and so the class's ClassLoader would not work. But in gRPC we have a library in the application's ClassLoader. Context ClassLoader has been causing problems in any case more than one application ClassLoader exists, like in Servlet containers, Android, and plugins. To my knowledge, in every case the context class loader is different from the provider's class loader, the context class loader has caused breakage, not success. In addition, since we use static fields for storing the provider results, using anything but the provider's class loader is asking to have results that vary simply depending on which thread called gRPC first. Fixes grpc#2375
1 parent 424eeea commit c637b42

3 files changed

Lines changed: 3 additions & 25 deletions

File tree

core/src/main/java/io/grpc/ManagedChannelProvider.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
@Internal
3535
public abstract class ManagedChannelProvider {
3636
private static final ManagedChannelProvider provider
37-
= load(getCorrectClassLoader());
37+
= load(ManagedChannelProvider.class.getClassLoader());
3838

3939
@VisibleForTesting
4040
static ManagedChannelProvider load(ClassLoader classLoader) {
@@ -118,17 +118,6 @@ public static ManagedChannelProvider provider() {
118118
return provider;
119119
}
120120

121-
private static ClassLoader getCorrectClassLoader() {
122-
if (isAndroid()) {
123-
// When android:sharedUserId or android:process is used, Android will setup a dummy
124-
// ClassLoader for the thread context (http://stackoverflow.com/questions/13407006),
125-
// instead of letting users to manually set context class loader, we choose the
126-
// correct class loader here.
127-
return ManagedChannelProvider.class.getClassLoader();
128-
}
129-
return Thread.currentThread().getContextClassLoader();
130-
}
131-
132121
/**
133122
* Returns whether current platform is Android.
134123
*/

core/src/main/java/io/grpc/NameResolverProvider.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public abstract class NameResolverProvider extends NameResolver.Factory {
4343
NameResolver.Factory.PARAMS_DEFAULT_PORT;
4444

4545
private static final List<NameResolverProvider> providers
46-
= load(getCorrectClassLoader());
46+
= load(NameResolverProvider.class.getClassLoader());
4747
private static final NameResolver.Factory factory = new NameResolverFactory(providers);
4848

4949
@VisibleForTesting
@@ -120,17 +120,6 @@ static NameResolver.Factory asFactory(List<NameResolverProvider> providers) {
120120
return new NameResolverFactory(providers);
121121
}
122122

123-
private static ClassLoader getCorrectClassLoader() {
124-
if (isAndroid()) {
125-
// When android:sharedUserId or android:process is used, Android will setup a dummy
126-
// ClassLoader for the thread context (http://stackoverflow.com/questions/13407006),
127-
// instead of letting users to manually set context class loader, we choose the
128-
// correct class loader here.
129-
return NameResolverProvider.class.getClassLoader();
130-
}
131-
return Thread.currentThread().getContextClassLoader();
132-
}
133-
134123
private static boolean isAndroid() {
135124
try {
136125
Class.forName("android.app.Application", /*initialize=*/ false, null);

core/src/main/java/io/grpc/ServerProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
@Internal
3131
public abstract class ServerProvider {
3232
private static final ServerProvider provider =
33-
load(Thread.currentThread().getContextClassLoader());
33+
load(ServerProvider.class.getClassLoader());
3434

3535
@VisibleForTesting
3636
static final ServerProvider load(ClassLoader cl) {

0 commit comments

Comments
 (0)