Handle missing methods on ChannelHandlerMask (#9221)

Motivation:

When Netty is run through ProGuard, seemingly unused methods are removed.  This breaks reflection, making the Handler skipping throw a reflective error.

Modification:

If a method is seemingly absent, just disable the optimization.

Result:

Dealing with ProGuard sucks infinitesimally less.
This commit is contained in:
Carl Mastrangelo 2019-06-07 13:39:47 -07:00 committed by Norman Maurer
parent e0bfc4f91f
commit c27fbb5ff2

View File

@ -18,11 +18,14 @@ package io.netty.channel;
import io.netty.util.concurrent.FastThreadLocal;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.net.SocketAddress;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
@ -30,6 +33,7 @@ import java.util.Map;
import java.util.WeakHashMap;
final class ChannelHandlerMask {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(ChannelHandlerMask.class);
// Using to mask which methods must be called for a ChannelHandler.
static final int MASK_EXCEPTION_CAUGHT = 1;
@ -166,9 +170,17 @@ final class ChannelHandlerMask {
@SuppressWarnings("rawtypes")
private static boolean isSkippable(
final Class<?> handlerType, final String methodName, final Class<?>... paramTypes) throws Exception {
return AccessController.doPrivileged((PrivilegedExceptionAction<Boolean>) () ->
handlerType.getMethod(methodName, paramTypes).isAnnotationPresent(Skip.class));
return AccessController.doPrivileged((PrivilegedExceptionAction<Boolean>) () -> {
Method m;
try {
m = handlerType.getMethod(methodName, paramTypes);
} catch (NoSuchMethodException e) {
logger.debug(
"Class {} missing method {}, assume we can not skip execution", handlerType, methodName, e);
return false;
}
return m.isAnnotationPresent(Skip.class);
});
}
private ChannelHandlerMask() { }