netty: Use the bootstrap ClassLoader for ALPN/NPN

If ALPN.class isn't in the bootclasspath, we don't want to find it as it
won't work. Also, if someone has fiddled with ClassLoaders, we really
want to make sure we get the proper ALPN class.

Passing "null" to Class.forName() means "bootstrap class loader". In
fact, ClassLoader.getParent() says, "Some implementations may use null
to represent the bootstrap class loader."

We must load the Proxy in the bootstrap class loader as well, because
our class loader may not have access to ALPN.{Client,Server}Provider,
for the same reasons as above. Even if we have multiple instances of
gRPC (due to class loaders), combined they will only create two Proxy
classes: one for ALPN.ClientProvider and one for ALPN.ServerProvider.
This commit is contained in:
Eric Anderson 2015-04-07 14:11:22 -07:00
parent 44f9904ab0
commit fd7ba566aa
1 changed files with 7 additions and 5 deletions

View File

@ -287,19 +287,21 @@ public class Http2Negotiator {
try {
Class<?> negoClass;
try {
negoClass = Class.forName(protocolNegoClassName);
negoClass = Class.forName(protocolNegoClassName, true, null);
} catch (ClassNotFoundException ignored) {
// Not on the classpath.
log.warning("Jetty extension " + protocolNegoClassName + " not found");
continue;
}
Class<?> providerClass = Class.forName(protocolNegoClassName + "$Provider");
Class<?> clientProviderClass = Class.forName(protocolNegoClassName + "$ClientProvider");
Class<?> serverProviderClass = Class.forName(protocolNegoClassName + "$ServerProvider");
Class<?> providerClass = Class.forName(protocolNegoClassName + "$Provider", true, null);
Class<?> clientProviderClass
= Class.forName(protocolNegoClassName + "$ClientProvider", true, null);
Class<?> serverProviderClass
= Class.forName(protocolNegoClassName + "$ServerProvider", true, null);
Method putMethod = negoClass.getMethod("put", SSLEngine.class, providerClass);
final Method removeMethod = negoClass.getMethod("remove", SSLEngine.class);
putMethod.invoke(null, engine, Proxy.newProxyInstance(
Http2Negotiator.class.getClassLoader(),
null,
new Class[] {server ? serverProviderClass : clientProviderClass},
new InvocationHandler() {
@Override