Fix reflection exceptions caused by having identically named fallback/blockHandler with different parameter types (#3395)

This commit is contained in:
dowenliu-xyz 2024-05-29 20:26:30 +08:00 committed by GitHub
parent bb813ddff3
commit 568e2df296
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 180 additions and 51 deletions

View File

@ -33,7 +33,7 @@ public class DemoController {
private TestService service;
@GetMapping("/foo")
public String apiFoo(@RequestParam(required = false) Long t) throws Exception {
public String apiFoo(@RequestParam(required = false) Long t) {
if (t == null) {
t = System.currentTimeMillis();
}
@ -41,6 +41,12 @@ public class DemoController {
return service.hello(t);
}
@GetMapping("/bar")
public String apiBar(@RequestParam(required = false) String t) {
service.test();
return service.hello(t);
}
@GetMapping("/baz/{name}")
public String apiBaz(@PathVariable("name") String name) {
return service.helloAnother(name);

View File

@ -24,5 +24,7 @@ public interface TestService {
String hello(long s);
String hello(String s);
String helloAnother(String name);
}

View File

@ -16,8 +16,6 @@
package com.alibaba.csp.sentinel.demo.annotation.aop.service;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;
/**
@ -41,6 +39,15 @@ public class TestServiceImpl implements TestService {
return String.format("Hello at %d", s);
}
@Override
@SentinelResource(value = "helloStr", fallback = "helloFallback")
public String hello(String s) {
if (s == null || s.trim().isEmpty()) {
throw new IllegalArgumentException("unknown");
}
return String.format("Hello, %s", s);
}
@Override
@SentinelResource(value = "helloAnother", defaultFallback = "defaultFallback",
exceptionsToIgnore = {IllegalStateException.class})
@ -60,6 +67,12 @@ public class TestServiceImpl implements TestService {
return "Oops, error occurred at " + s;
}
private String helloFallback(String ignored, Throwable e) {
// Do some log here.
e.printStackTrace();
return "Hello, stranger";
}
public String defaultFallback() {
System.out.println("Go to default fallback");
return "default_fallback";

View File

@ -34,6 +34,7 @@ import java.util.Arrays;
*
* @author Eric Zhao
* @author zhaoyuguang
* @author dowenliu-xyz(hawkdowen@hotmail.com)
*/
public abstract class AbstractSentinelAspectSupport {
@ -177,12 +178,13 @@ public abstract class AbstractSentinelAspectSupport {
}
boolean mustStatic = locationClass != null && locationClass.length >= 1;
Class<?> clazz = mustStatic ? locationClass[0] : pjp.getTarget().getClass();
MethodWrapper m = ResourceMetadataRegistry.lookupFallback(clazz, fallbackName);
Method originMethod = resolveMethod(pjp);
MethodWrapper m = ResourceMetadataRegistry.lookupFallback(clazz, fallbackName, originMethod.getParameterTypes());
if (m == null) {
// First time, resolve the fallback.
Method method = resolveFallbackInternal(pjp, fallbackName, clazz, mustStatic);
Method method = resolveFallbackInternal(originMethod, fallbackName, clazz, mustStatic);
// Cache the method instance.
ResourceMetadataRegistry.updateFallbackFor(clazz, fallbackName, method);
ResourceMetadataRegistry.updateFallbackFor(clazz, fallbackName, originMethod.getParameterTypes(), method);
return method;
}
if (!m.isPresent()) {
@ -232,9 +234,7 @@ public abstract class AbstractSentinelAspectSupport {
return m.getMethod();
}
private Method resolveFallbackInternal(ProceedingJoinPoint pjp, /*@NonNull*/ String name, Class<?> clazz,
boolean mustStatic) {
Method originMethod = resolveMethod(pjp);
private Method resolveFallbackInternal(Method originMethod, String name, Class<?> clazz, boolean mustStatic) {
// Fallback function allows two kinds of parameter list.
Class<?>[] defaultParamTypes = originMethod.getParameterTypes();
Class<?>[] paramTypesWithException = Arrays.copyOf(defaultParamTypes, defaultParamTypes.length + 1);
@ -261,12 +261,13 @@ public abstract class AbstractSentinelAspectSupport {
// By default current class.
clazz = pjp.getTarget().getClass();
}
MethodWrapper m = ResourceMetadataRegistry.lookupBlockHandler(clazz, name);
Method originMethod = resolveMethod(pjp);
MethodWrapper m = ResourceMetadataRegistry.lookupBlockHandler(clazz, name, originMethod.getParameterTypes());
if (m == null) {
// First time, resolve the block handler.
Method method = resolveBlockHandlerInternal(pjp, name, clazz, mustStatic);
Method method = resolveBlockHandlerInternal(originMethod, name, clazz, mustStatic);
// Cache the method instance.
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, name, method);
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, name, originMethod.getParameterTypes(), method);
return method;
}
if (!m.isPresent()) {
@ -275,9 +276,7 @@ public abstract class AbstractSentinelAspectSupport {
return m.getMethod();
}
private Method resolveBlockHandlerInternal(ProceedingJoinPoint pjp, /*@NonNull*/ String name, Class<?> clazz,
boolean mustStatic) {
Method originMethod = resolveMethod(pjp);
private Method resolveBlockHandlerInternal(Method originMethod, String name, Class<?> clazz, boolean mustStatic) {
Class<?>[] originList = originMethod.getParameterTypes();
Class<?>[] parameterTypes = Arrays.copyOf(originList, originList.length + 1);
parameterTypes[parameterTypes.length - 1] = BlockException.class;

View File

@ -16,8 +16,10 @@
package com.alibaba.csp.sentinel.annotation.aspectj;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import com.alibaba.csp.sentinel.util.StringUtil;
@ -25,6 +27,7 @@ import com.alibaba.csp.sentinel.util.StringUtil;
* Registry for resource configuration metadata (e.g. fallback method)
*
* @author Eric Zhao
* @author dowenliu-xyz(hawkdowen@hotmail.com)
*/
final class ResourceMetadataRegistry {
@ -32,18 +35,38 @@ final class ResourceMetadataRegistry {
private static final Map<String, MethodWrapper> DEFAULT_FALLBACK_MAP = new ConcurrentHashMap<>();
private static final Map<String, MethodWrapper> BLOCK_HANDLER_MAP = new ConcurrentHashMap<>();
/**
* @deprecated use {@link #lookupFallback(Class, String, Class[])}
*/
@Deprecated
static MethodWrapper lookupFallback(Class<?> clazz, String name) {
return FALLBACK_MAP.get(getKey(clazz, name));
}
static MethodWrapper lookupFallback(Class<?> clazz, String name, Class<?>[] parameterTypes) {
return FALLBACK_MAP.get(getKey(clazz, name, parameterTypes));
}
static MethodWrapper lookupDefaultFallback(Class<?> clazz, String name) {
return DEFAULT_FALLBACK_MAP.get(getKey(clazz, name));
}
/**
* @deprecated use {@link #lookupBlockHandler(Class, String, Class[])}
*/
@Deprecated
static MethodWrapper lookupBlockHandler(Class<?> clazz, String name) {
return BLOCK_HANDLER_MAP.get(getKey(clazz, name));
}
static MethodWrapper lookupBlockHandler(Class<?> clazz, String name, Class<?>[] parameterTypes) {
return BLOCK_HANDLER_MAP.get(getKey(clazz, name, parameterTypes));
}
/**
* @deprecated use {@link #updateFallbackFor(Class, String, Class[], Method)}
*/
@Deprecated
static void updateFallbackFor(Class<?> clazz, String name, Method method) {
if (clazz == null || StringUtil.isBlank(name)) {
throw new IllegalArgumentException("Bad argument");
@ -51,6 +74,13 @@ final class ResourceMetadataRegistry {
FALLBACK_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method));
}
static void updateFallbackFor(Class<?> clazz, String handlerName, Class<?>[] parameterTypes, Method handlerMethod) {
if (clazz == null || StringUtil.isBlank(handlerName)) {
throw new IllegalArgumentException("Bad argument");
}
FALLBACK_MAP.put(getKey(clazz, handlerName, parameterTypes), MethodWrapper.wrap(handlerMethod));
}
static void updateDefaultFallbackFor(Class<?> clazz, String name, Method method) {
if (clazz == null || StringUtil.isBlank(name)) {
throw new IllegalArgumentException("Bad argument");
@ -58,6 +88,11 @@ final class ResourceMetadataRegistry {
DEFAULT_FALLBACK_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method));
}
/**
* @deprecated use {@link #updateBlockHandlerFor(Class, String, Class[], Method)}
*/
@Deprecated
static void updateBlockHandlerFor(Class<?> clazz, String name, Method method) {
if (clazz == null || StringUtil.isBlank(name)) {
throw new IllegalArgumentException("Bad argument");
@ -65,10 +100,27 @@ final class ResourceMetadataRegistry {
BLOCK_HANDLER_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method));
}
static void updateBlockHandlerFor(Class<?> clazz, String handlerName, Class<?>[] parameterTypes,
Method handlerMethod) {
if (clazz == null || StringUtil.isBlank(handlerName)) {
throw new IllegalArgumentException("Bad argument");
}
BLOCK_HANDLER_MAP.put(getKey(clazz, handlerName, parameterTypes), MethodWrapper.wrap(handlerMethod));
}
private static String getKey(Class<?> clazz, String name) {
return String.format("%s:%s", clazz.getCanonicalName(), name);
}
private static String getKey(Class<?> clazz, String name, Class<?>[] parameterTypes) {
return String.format(
"%s:%s;%s",
clazz.getCanonicalName(),
name,
Arrays.stream(parameterTypes).map(Class::getCanonicalName).collect(Collectors.joining(","))
);
}
/**
* Only for internal test.
*/

View File

@ -26,6 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Eric Zhao
* @author dowenliu-xyz(hawkdowen@hotmail.com)
*/
public class ResourceMetadataRegistryTest {
@ -45,14 +46,15 @@ public class ResourceMetadataRegistryTest {
public void testUpdateThenLookupFallback() {
Class<?> clazz = FooService.class;
String methodName = "someMethodFallback";
Class<?>[] parameterTypes = new Class<?>[]{String.class, int.class};
Method method = clazz.getMethods()[0];
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName)).isNull();
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes)).isNull();
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, null);
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName).isPresent()).isFalse();
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, parameterTypes, null);
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes).isPresent()).isFalse();
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, method);
MethodWrapper wrapper = ResourceMetadataRegistry.lookupFallback(clazz, methodName);
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, parameterTypes, method);
MethodWrapper wrapper = ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes);
assertThat(wrapper.isPresent()).isTrue();
assertThat(wrapper.getMethod()).isSameAs(method);
}
@ -61,25 +63,26 @@ public class ResourceMetadataRegistryTest {
public void testUpdateThenLookupBlockHandler() {
Class<?> clazz = FooService.class;
String methodName = "someMethodBlockHand;er";
Class<?>[] parameterTypes = new Class<?>[]{String.class, int.class};
Method method = clazz.getMethods()[1];
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName)).isNull();
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes)).isNull();
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, null);
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName).isPresent()).isFalse();
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, parameterTypes, null);
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes).isPresent()).isFalse();
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, method);
MethodWrapper wrapper = ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName);
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, parameterTypes, method);
MethodWrapper wrapper = ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes);
assertThat(wrapper.isPresent()).isTrue();
assertThat(wrapper.getMethod()).isSameAs(method);
}
@Test(expected = IllegalArgumentException.class)
public void testUpdateBlockHandlerBadArgument() {
ResourceMetadataRegistry.updateBlockHandlerFor(null, "sxs", String.class.getMethods()[0]);
ResourceMetadataRegistry.updateBlockHandlerFor(null, "sxs", new Class<?>[]{}, String.class.getMethods()[0]);
}
@Test(expected = IllegalArgumentException.class)
public void testUpdateFallbackBadArgument() {
ResourceMetadataRegistry.updateBlockHandlerFor(String.class, "", String.class.getMethods()[0]);
ResourceMetadataRegistry.updateBlockHandlerFor(String.class, "", new Class[0], String.class.getMethods()[0]);
}
}

View File

@ -34,6 +34,7 @@ import java.util.Arrays;
*
* @author Eric Zhao
* @author seasidesky
* @author dowenliu-xyz(hawkdowen@hotmail.com)
*/
public abstract class AbstractSentinelInterceptorSupport {
@ -170,12 +171,13 @@ public abstract class AbstractSentinelInterceptorSupport {
}
boolean mustStatic = locationClass != null && locationClass.length >= 1;
Class<?> clazz = mustStatic ? locationClass[0] : ctx.getTarget().getClass();
MethodWrapper m = ResourceMetadataRegistry.lookupFallback(clazz, fallbackName);
Method originMethod = resolveMethod(ctx);
MethodWrapper m = ResourceMetadataRegistry.lookupFallback(clazz, fallbackName, originMethod.getParameterTypes());
if (m == null) {
// First time, resolve the fallback.
Method method = resolveFallbackInternal(ctx, fallbackName, clazz, mustStatic);
Method method = resolveFallbackInternal(originMethod, fallbackName, clazz, mustStatic);
// Cache the method instance.
ResourceMetadataRegistry.updateFallbackFor(clazz, fallbackName, method);
ResourceMetadataRegistry.updateFallbackFor(clazz, fallbackName, originMethod.getParameterTypes(), method);
return method;
}
if (!m.isPresent()) {
@ -225,9 +227,7 @@ public abstract class AbstractSentinelInterceptorSupport {
return m.getMethod();
}
private Method resolveFallbackInternal(InvocationContext ctx, /*@NonNull*/ String name, Class<?> clazz,
boolean mustStatic) {
Method originMethod = resolveMethod(ctx);
private Method resolveFallbackInternal(Method originMethod, String name, Class<?> clazz, boolean mustStatic) {
// Fallback function allows two kinds of parameter list.
Class<?>[] defaultParamTypes = originMethod.getParameterTypes();
Class<?>[] paramTypesWithException = Arrays.copyOf(defaultParamTypes, defaultParamTypes.length + 1);
@ -254,12 +254,13 @@ public abstract class AbstractSentinelInterceptorSupport {
// By default current class.
clazz = ctx.getTarget().getClass();
}
MethodWrapper m = ResourceMetadataRegistry.lookupBlockHandler(clazz, name);
Method originMethod = resolveMethod(ctx);
MethodWrapper m = ResourceMetadataRegistry.lookupBlockHandler(clazz, name, originMethod.getParameterTypes());
if (m == null) {
// First time, resolve the block handler.
Method method = resolveBlockHandlerInternal(ctx, name, clazz, mustStatic);
Method method = resolveBlockHandlerInternal(originMethod, name, clazz, mustStatic);
// Cache the method instance.
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, name, method);
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, name, originMethod.getParameterTypes(), method);
return method;
}
if (!m.isPresent()) {
@ -268,9 +269,7 @@ public abstract class AbstractSentinelInterceptorSupport {
return m.getMethod();
}
private Method resolveBlockHandlerInternal(InvocationContext ctx, /*@NonNull*/ String name, Class<?> clazz,
boolean mustStatic) {
Method originMethod = resolveMethod(ctx);
private Method resolveBlockHandlerInternal(Method originMethod, String name, Class<?> clazz, boolean mustStatic) {
Class<?>[] originList = originMethod.getParameterTypes();
Class<?>[] parameterTypes = Arrays.copyOf(originList, originList.length + 1);
parameterTypes[parameterTypes.length - 1] = BlockException.class;

View File

@ -18,13 +18,16 @@ package com.alibaba.csp.sentinel.annotation.cdi.interceptor;
import com.alibaba.csp.sentinel.util.StringUtil;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* Registry for resource configuration metadata (e.g. fallback method)
*
* @author Eric Zhao
* @author dowenliu-xyz(hawkdowen@hotmail.com)
*/
final class ResourceMetadataRegistry {
@ -32,18 +35,38 @@ final class ResourceMetadataRegistry {
private static final Map<String, MethodWrapper> DEFAULT_FALLBACK_MAP = new ConcurrentHashMap<>();
private static final Map<String, MethodWrapper> BLOCK_HANDLER_MAP = new ConcurrentHashMap<>();
/**
* @deprecated use {@link #lookupFallback(Class, String, Class[])}
*/
@Deprecated
static MethodWrapper lookupFallback(Class<?> clazz, String name) {
return FALLBACK_MAP.get(getKey(clazz, name));
}
static MethodWrapper lookupFallback(Class<?> clazz, String name, Class<?>[] parameterTypes) {
return FALLBACK_MAP.get(getKey(clazz, name, parameterTypes));
}
static MethodWrapper lookupDefaultFallback(Class<?> clazz, String name) {
return DEFAULT_FALLBACK_MAP.get(getKey(clazz, name));
}
/**
* @deprecated use {@link #lookupBlockHandler(Class, String, Class[])}
*/
@Deprecated
static MethodWrapper lookupBlockHandler(Class<?> clazz, String name) {
return BLOCK_HANDLER_MAP.get(getKey(clazz, name));
}
static MethodWrapper lookupBlockHandler(Class<?> clazz, String name, Class<?>[] parameterTypes) {
return BLOCK_HANDLER_MAP.get(getKey(clazz, name, parameterTypes));
}
/**
* @deprecated use {@link #updateFallbackFor(Class, String, Class[], Method)}
*/
@Deprecated
static void updateFallbackFor(Class<?> clazz, String name, Method method) {
if (clazz == null || StringUtil.isBlank(name)) {
throw new IllegalArgumentException("Bad argument");
@ -51,6 +74,13 @@ final class ResourceMetadataRegistry {
FALLBACK_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method));
}
static void updateFallbackFor(Class<?> clazz, String handlerName, Class<?>[] parameterTypes, Method handlerMethod) {
if (clazz == null || StringUtil.isBlank(handlerName)) {
throw new IllegalArgumentException("Bad argument");
}
FALLBACK_MAP.put(getKey(clazz, handlerName, parameterTypes), MethodWrapper.wrap(handlerMethod));
}
static void updateDefaultFallbackFor(Class<?> clazz, String name, Method method) {
if (clazz == null || StringUtil.isBlank(name)) {
throw new IllegalArgumentException("Bad argument");
@ -58,6 +88,11 @@ final class ResourceMetadataRegistry {
DEFAULT_FALLBACK_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method));
}
/**
* @deprecated use {@link #updateBlockHandlerFor(Class, String, Class[], Method)}
*/
@Deprecated
static void updateBlockHandlerFor(Class<?> clazz, String name, Method method) {
if (clazz == null || StringUtil.isBlank(name)) {
throw new IllegalArgumentException("Bad argument");
@ -65,10 +100,27 @@ final class ResourceMetadataRegistry {
BLOCK_HANDLER_MAP.put(getKey(clazz, name), MethodWrapper.wrap(method));
}
static void updateBlockHandlerFor(Class<?> clazz, String handlerName, Class<?>[] parameterTypes,
Method handlerMethod) {
if (clazz == null || StringUtil.isBlank(handlerName)) {
throw new IllegalArgumentException("Bad argument");
}
BLOCK_HANDLER_MAP.put(getKey(clazz, handlerName, parameterTypes), MethodWrapper.wrap(handlerMethod));
}
private static String getKey(Class<?> clazz, String name) {
return String.format("%s:%s", clazz.getCanonicalName(), name);
}
private static String getKey(Class<?> clazz, String name, Class<?>[] parameterTypes) {
return String.format(
"%s:%s;%s",
clazz.getCanonicalName(),
name,
Arrays.stream(parameterTypes).map(Class::getCanonicalName).collect(Collectors.joining(","))
);
}
/**
* Only for internal test.
*/

View File

@ -27,6 +27,7 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Eric Zhao
* @author dowenliu-xyz(hawkdowen@hotmail.com)
*/
public class ResourceMetadataRegistryTest {
@ -46,14 +47,15 @@ public class ResourceMetadataRegistryTest {
public void testUpdateThenLookupFallback() {
Class<?> clazz = FooService.class;
String methodName = "someMethodFallback";
Class<?>[] parameterTypes = new Class<?>[] {String.class};
Method method = clazz.getMethods()[0];
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName)).isNull();
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes)).isNull();
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, null);
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName).isPresent()).isFalse();
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, parameterTypes, null);
assertThat(ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes).isPresent()).isFalse();
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, method);
MethodWrapper wrapper = ResourceMetadataRegistry.lookupFallback(clazz, methodName);
ResourceMetadataRegistry.updateFallbackFor(clazz, methodName, parameterTypes, method);
MethodWrapper wrapper = ResourceMetadataRegistry.lookupFallback(clazz, methodName, parameterTypes);
assertThat(wrapper.isPresent()).isTrue();
assertThat(wrapper.getMethod()).isSameAs(method);
}
@ -62,25 +64,26 @@ public class ResourceMetadataRegistryTest {
public void testUpdateThenLookupBlockHandler() {
Class<?> clazz = FooService.class;
String methodName = "someMethodBlockHand;er";
Class<?>[] parameterTypes = new Class<?>[] {String.class};
Method method = clazz.getMethods()[1];
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName)).isNull();
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes)).isNull();
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, null);
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName).isPresent()).isFalse();
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, parameterTypes, null);
assertThat(ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes).isPresent()).isFalse();
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, method);
MethodWrapper wrapper = ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName);
ResourceMetadataRegistry.updateBlockHandlerFor(clazz, methodName, parameterTypes, method);
MethodWrapper wrapper = ResourceMetadataRegistry.lookupBlockHandler(clazz, methodName, parameterTypes);
assertThat(wrapper.isPresent()).isTrue();
assertThat(wrapper.getMethod()).isSameAs(method);
}
@Test(expected = IllegalArgumentException.class)
public void testUpdateBlockHandlerBadArgument() {
ResourceMetadataRegistry.updateBlockHandlerFor(null, "sxs", String.class.getMethods()[0]);
ResourceMetadataRegistry.updateBlockHandlerFor(null, "sxs", new Class[0], String.class.getMethods()[0]);
}
@Test(expected = IllegalArgumentException.class)
public void testUpdateFallbackBadArgument() {
ResourceMetadataRegistry.updateBlockHandlerFor(String.class, "", String.class.getMethods()[0]);
ResourceMetadataRegistry.updateBlockHandlerFor(String.class, "", new Class[0], String.class.getMethods()[0]);
}
}