Skip to content

Commit

Permalink
Load Conscrypt method via reflection only once
Browse files Browse the repository at this point in the history
Motivation:

The code did reflection every method call which made the code slower and
harder to read with additional cases to consider.

Modifications:

Instead of loading the method and then throwing it away, save the Method
reference instead of the Class reference. Then also use more precise
exception handling for the method invocation.

Result:

Simpler, speedier code.
  • Loading branch information
ejona86 authored and normanmaurer committed Feb 9, 2018
1 parent 6cd5e8b commit 8b27398
Showing 1 changed file with 20 additions and 24 deletions.
44 changes: 20 additions & 24 deletions handler/src/main/java/io/netty/handler/ssl/Conscrypt.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.netty.util.internal.PlatformDependent;

import javax.net.ssl.SSLEngine;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
Expand All @@ -26,44 +27,39 @@
final class Conscrypt {
// This class exists to avoid loading other conscrypt related classes using features only available in JDK8+,
// because we need to maintain JDK6+ runtime compatibility.
private static final Class<?> CONSCRYPT_CLASS = getConscryptClass();
private static final Method IS_CONSCRYPT_SSLENGINE = loadIsConscryptEngine();

/**
* Indicates whether or not conscrypt is available on the current system.
*/
static boolean isAvailable() {
return CONSCRYPT_CLASS != null && PlatformDependent.javaVersion() >= 8;
}

static boolean isEngineSupported(SSLEngine engine) {
return isAvailable() && isConscryptEngine(engine, CONSCRYPT_CLASS);
}

private static Class<?> getConscryptClass() {
private static Method loadIsConscryptEngine() {
try {
Class<?> conscryptClass = Class.forName("org.conscrypt.Conscrypt", true,
ConscryptAlpnSslEngine.class.getClassLoader());
// Ensure that it also has the isConscrypt method.
getIsConscryptMethod(conscryptClass);
return conscryptClass;
return conscryptClass.getMethod("isConscrypt", SSLEngine.class);
} catch (Throwable ignore) {
// Conscrypt was not loaded.
return null;
}
}

private static boolean isConscryptEngine(SSLEngine engine, Class<?> conscryptClass) {
/**
* Indicates whether or not conscrypt is available on the current system.
*/
static boolean isAvailable() {
return IS_CONSCRYPT_SSLENGINE != null && PlatformDependent.javaVersion() >= 8;
}

static boolean isEngineSupported(SSLEngine engine) {
return isAvailable() && isConscryptEngine(engine);
}

private static boolean isConscryptEngine(SSLEngine engine) {
try {
Method method = getIsConscryptMethod(conscryptClass);
return (Boolean) method.invoke(null, engine);
} catch (Throwable ignore) {
return (Boolean) IS_CONSCRYPT_SSLENGINE.invoke(null, engine);
} catch (IllegalAccessException ignore) {
return false;
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex);
}
}

private static Method getIsConscryptMethod(Class<?> conscryptClass) throws NoSuchMethodException {
return conscryptClass.getMethod("isConscrypt", SSLEngine.class);
}

private Conscrypt() { }
}

0 comments on commit 8b27398

Please sign in to comment.