From fd7ba566aa775d15c97cdad501dfedca65ab1d7e Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Tue, 7 Apr 2015 14:11:22 -0700 Subject: [PATCH] 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. --- .../io/grpc/transport/netty/Http2Negotiator.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/netty/src/main/java/io/grpc/transport/netty/Http2Negotiator.java b/netty/src/main/java/io/grpc/transport/netty/Http2Negotiator.java index d869ebb7c3..7a0400a0ea 100644 --- a/netty/src/main/java/io/grpc/transport/netty/Http2Negotiator.java +++ b/netty/src/main/java/io/grpc/transport/netty/Http2Negotiator.java @@ -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