Reinstantiate checks for kotlin-reflect
This commit reinstantiates checks for kotlin-reflect (via static final fields for faster Java code paths and better native code removal) which were removed as part of gh-34275, which did not consider the increasingly popular use cases where kotlin-stdlib is present in the classpath as a transitive dependency in Java applications. Closes gh-35511
This commit is contained in:
parent
7635ac38f6
commit
c79e4e230b
|
@ -88,6 +88,8 @@ public abstract class BeanUtils {
|
|||
double.class, 0D,
|
||||
char.class, '\0');
|
||||
|
||||
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||
|
||||
|
||||
/**
|
||||
* Convenience method to instantiate a class using its no-arg constructor.
|
||||
|
@ -186,7 +188,7 @@ public abstract class BeanUtils {
|
|||
Assert.notNull(ctor, "Constructor must not be null");
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(ctor);
|
||||
if (KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
|
||||
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
|
||||
return KotlinDelegate.instantiateClass(ctor, args);
|
||||
}
|
||||
else {
|
||||
|
@ -279,7 +281,7 @@ public abstract class BeanUtils {
|
|||
*/
|
||||
public static <T> @Nullable Constructor<T> findPrimaryConstructor(Class<T> clazz) {
|
||||
Assert.notNull(clazz, "Class must not be null");
|
||||
if (KotlinDetector.isKotlinType(clazz)) {
|
||||
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(clazz)) {
|
||||
return KotlinDelegate.findPrimaryConstructor(clazz);
|
||||
}
|
||||
if (clazz.isRecord()) {
|
||||
|
@ -659,7 +661,7 @@ public abstract class BeanUtils {
|
|||
ConstructorProperties cp = ctor.getAnnotation(ConstructorProperties.class);
|
||||
@Nullable String[] paramNames = (cp != null ? cp.value() : parameterNameDiscoverer.getParameterNames(ctor));
|
||||
Assert.state(paramNames != null, () -> "Cannot resolve parameter names for constructor " + ctor);
|
||||
int parameterCount = (KotlinDetector.isKotlinReflectPresent() && KotlinDelegate.hasDefaultConstructorMarker(ctor) ?
|
||||
int parameterCount = (KOTLIN_REFLECT_PRESENT && KotlinDelegate.hasDefaultConstructorMarker(ctor) ?
|
||||
ctor.getParameterCount() - 1 : ctor.getParameterCount());
|
||||
Assert.state(paramNames.length == parameterCount,
|
||||
() -> "Invalid number of parameter names: " + paramNames.length + " for constructor " + ctor);
|
||||
|
|
|
@ -88,6 +88,8 @@ public class InstanceSupplierCodeGenerator {
|
|||
|
||||
private static final CodeBlock NO_ARGS = CodeBlock.of("");
|
||||
|
||||
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||
|
||||
|
||||
private final GenerationContext generationContext;
|
||||
|
||||
|
@ -161,7 +163,7 @@ public class InstanceSupplierCodeGenerator {
|
|||
registeredBean.getBeanName(), constructor, registeredBean.getBeanClass());
|
||||
|
||||
Class<?> publicType = descriptor.publicType();
|
||||
if (KotlinDetector.isKotlinType(publicType) && KotlinDelegate.hasConstructorWithOptionalParameter(publicType)) {
|
||||
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(publicType) && KotlinDelegate.hasConstructorWithOptionalParameter(publicType)) {
|
||||
return generateCodeForInaccessibleConstructor(descriptor,
|
||||
hints -> hints.registerType(publicType, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
|
||||
}
|
||||
|
|
|
@ -35,8 +35,11 @@ package org.springframework.core;
|
|||
*/
|
||||
public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDiscoverer {
|
||||
|
||||
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||
|
||||
|
||||
public DefaultParameterNameDiscoverer() {
|
||||
if (KotlinDetector.isKotlinReflectPresent()) {
|
||||
if (KOTLIN_REFLECT_PRESENT) {
|
||||
addDiscoverer(new KotlinReflectionParameterNameDiscoverer());
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ public class MethodParameter {
|
|||
|
||||
private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
|
||||
|
||||
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||
|
||||
|
||||
private final Executable executable;
|
||||
|
||||
|
@ -396,7 +398,8 @@ public class MethodParameter {
|
|||
*/
|
||||
public boolean isOptional() {
|
||||
return (getParameterType() == Optional.class || Nullness.forMethodParameter(this) == Nullness.NULLABLE ||
|
||||
(KotlinDetector.isKotlinType(getContainingClass()) && KotlinDelegate.isOptional(this)));
|
||||
(KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(getContainingClass()) &&
|
||||
KotlinDelegate.isOptional(this)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -484,7 +487,7 @@ public class MethodParameter {
|
|||
if (this.parameterIndex < 0) {
|
||||
Method method = getMethod();
|
||||
paramType = (method != null ?
|
||||
(KotlinDetector.isKotlinType(getContainingClass()) ?
|
||||
(KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(getContainingClass()) ?
|
||||
KotlinDelegate.getGenericReturnType(method) : method.getGenericReturnType()) : void.class);
|
||||
}
|
||||
else {
|
||||
|
@ -512,7 +515,7 @@ public class MethodParameter {
|
|||
if (method == null) {
|
||||
return void.class;
|
||||
}
|
||||
if (KotlinDetector.isKotlinType(getContainingClass())) {
|
||||
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(getContainingClass())) {
|
||||
return KotlinDelegate.getReturnType(method);
|
||||
}
|
||||
return method.getReturnType();
|
||||
|
|
|
@ -77,6 +77,8 @@ public enum Nullness {
|
|||
*/
|
||||
NON_NULL;
|
||||
|
||||
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||
|
||||
|
||||
/**
|
||||
* Return the nullness of the return type for the given method.
|
||||
|
@ -84,7 +86,7 @@ public enum Nullness {
|
|||
* @return the corresponding nullness
|
||||
*/
|
||||
public static Nullness forMethodReturnType(Method method) {
|
||||
if (KotlinDetector.isKotlinType(method.getDeclaringClass())) {
|
||||
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(method.getDeclaringClass())) {
|
||||
return KotlinDelegate.forMethodReturnType(method);
|
||||
}
|
||||
return (hasNullableAnnotation(method) ? Nullness.NULLABLE :
|
||||
|
@ -97,7 +99,7 @@ public enum Nullness {
|
|||
* @return the corresponding nullness
|
||||
*/
|
||||
public static Nullness forParameter(Parameter parameter) {
|
||||
if (KotlinDetector.isKotlinType(parameter.getDeclaringExecutable().getDeclaringClass())) {
|
||||
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(parameter.getDeclaringExecutable().getDeclaringClass())) {
|
||||
// TODO Optimize when kotlin-reflect provide a more direct Parameter to KParameter resolution
|
||||
MethodParameter methodParameter = MethodParameter.forParameter(parameter);
|
||||
return KotlinDelegate.forParameter(methodParameter.getExecutable(), methodParameter.getParameterIndex());
|
||||
|
@ -124,7 +126,7 @@ public enum Nullness {
|
|||
* @return the corresponding nullness
|
||||
*/
|
||||
public static Nullness forField(Field field) {
|
||||
if (KotlinDetector.isKotlinType(field.getDeclaringClass())) {
|
||||
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(field.getDeclaringClass())) {
|
||||
return KotlinDelegate.forField(field);
|
||||
}
|
||||
return (hasNullableAnnotation(field) ? Nullness.NULLABLE :
|
||||
|
|
|
@ -360,8 +360,11 @@ public class SpringFactoriesLoader {
|
|||
*/
|
||||
static final class FactoryInstantiator<T> {
|
||||
|
||||
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||
|
||||
private final Constructor<T> constructor;
|
||||
|
||||
|
||||
private FactoryInstantiator(Constructor<T> constructor) {
|
||||
ReflectionUtils.makeAccessible(constructor);
|
||||
this.constructor = constructor;
|
||||
|
@ -369,7 +372,7 @@ public class SpringFactoriesLoader {
|
|||
|
||||
T instantiate(@Nullable ArgumentResolver argumentResolver) throws Exception {
|
||||
Object[] args = resolveArgs(argumentResolver);
|
||||
if (KotlinDetector.isKotlinType(this.constructor.getDeclaringClass())) {
|
||||
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(this.constructor.getDeclaringClass())) {
|
||||
return KotlinDelegate.instantiate(this.constructor, args);
|
||||
}
|
||||
return this.constructor.newInstance(args);
|
||||
|
|
|
@ -75,6 +75,9 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
|||
|
||||
private static final Set<Class<?>> BOOLEAN_TYPES = Set.of(Boolean.class, boolean.class);
|
||||
|
||||
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||
|
||||
|
||||
private final boolean allowWrite;
|
||||
|
||||
private final Map<PropertyCacheKey, InvokerPair> readerCache = new ConcurrentHashMap<>(64);
|
||||
|
@ -558,7 +561,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
|||
|
||||
private static boolean isKotlinProperty(Method method, String methodSuffix) {
|
||||
Class<?> clazz = method.getDeclaringClass();
|
||||
return KotlinDetector.isKotlinType(clazz) &&
|
||||
return KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(clazz) &&
|
||||
KotlinDelegate.isKotlinProperty(method, methodSuffix);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
|||
*/
|
||||
public abstract class AbstractNamedValueMethodArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||
|
||||
private final @Nullable ConfigurableBeanFactory configurableBeanFactory;
|
||||
|
||||
private final @Nullable BeanExpressionContext expressionContext;
|
||||
|
@ -103,7 +105,7 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
|||
|
||||
NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);
|
||||
MethodParameter nestedParameter = parameter.nestedIfOptional();
|
||||
boolean hasDefaultValue = KotlinDetector.isKotlinType(parameter.getDeclaringClass()) &&
|
||||
boolean hasDefaultValue = KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(parameter.getDeclaringClass()) &&
|
||||
KotlinDelegate.hasDefaultValue(nestedParameter);
|
||||
|
||||
Object resolvedName = resolveEmbeddedValuesAndExpressions(namedValueInfo.name);
|
||||
|
|
|
@ -66,6 +66,8 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
|||
|
||||
private static final Class<?>[] EMPTY_GROUPS = new Class<?>[0];
|
||||
|
||||
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||
|
||||
|
||||
private HandlerMethodArgumentResolverComposite resolvers = new HandlerMethodArgumentResolverComposite();
|
||||
|
||||
|
@ -247,7 +249,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
|||
protected @Nullable Object doInvoke(@Nullable Object... args) throws Exception {
|
||||
Method method = getBridgedMethod();
|
||||
try {
|
||||
if (KotlinDetector.isKotlinType(method.getDeclaringClass())) {
|
||||
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(method.getDeclaringClass())) {
|
||||
if (KotlinDetector.isSuspendingFunction(method)) {
|
||||
return invokeSuspendingFunction(method, getBean(), args);
|
||||
}
|
||||
|
|
|
@ -85,6 +85,8 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
|||
|
||||
private static final Object NO_ARG_VALUE = new Object();
|
||||
|
||||
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||
|
||||
|
||||
private final HandlerMethodArgumentResolverComposite resolvers = new HandlerMethodArgumentResolverComposite();
|
||||
|
||||
|
@ -197,12 +199,17 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
|||
}
|
||||
}
|
||||
Object value;
|
||||
boolean isSuspendingFunction;
|
||||
Method method = getBridgedMethod();
|
||||
boolean isSuspendingFunction = KotlinDetector.isSuspendingFunction(method);
|
||||
try {
|
||||
value = (KotlinDetector.isKotlinType(method.getDeclaringClass()) ?
|
||||
KotlinDelegate.invokeFunction(method, getBean(), args, isSuspendingFunction, exchange) :
|
||||
method.invoke(getBean(), args));
|
||||
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(method.getDeclaringClass())) {
|
||||
isSuspendingFunction = KotlinDetector.isSuspendingFunction(method);
|
||||
value = KotlinDelegate.invokeFunction(method, getBean(), args, isSuspendingFunction, exchange);
|
||||
}
|
||||
else {
|
||||
isSuspendingFunction = false;
|
||||
value = method.invoke(getBean(), args);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
assertTargetBean(getBridgedMethod(), getBean(), args);
|
||||
|
|
|
@ -69,6 +69,8 @@ import org.springframework.web.server.ServerWebInputException;
|
|||
*/
|
||||
public abstract class AbstractNamedValueArgumentResolver extends HandlerMethodArgumentResolverSupport {
|
||||
|
||||
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||
|
||||
private final @Nullable ConfigurableBeanFactory configurableBeanFactory;
|
||||
|
||||
private final @Nullable BeanExpressionContext expressionContext;
|
||||
|
@ -222,7 +224,7 @@ public abstract class AbstractNamedValueArgumentResolver extends HandlerMethodAr
|
|||
|
||||
return Mono.fromSupplier(() -> {
|
||||
Object value = null;
|
||||
boolean hasDefaultValue = KotlinDetector.isKotlinType(parameter.getDeclaringClass()) &&
|
||||
boolean hasDefaultValue = KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(parameter.getDeclaringClass()) &&
|
||||
KotlinDelegate.hasDefaultValue(parameter);
|
||||
if (namedValueInfo.defaultValue != null) {
|
||||
value = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.springframework.context.ApplicationContextAware;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.core.KotlinDetector;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.format.Formatter;
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
|
@ -184,6 +185,8 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
|||
|
||||
private static final boolean JACKSON_2_PRESENT;
|
||||
|
||||
private static final boolean KOTLIN_REFLECT_PRESENT;
|
||||
|
||||
private static final boolean KOTLIN_SERIALIZATION_PRESENT;
|
||||
|
||||
|
||||
|
@ -192,6 +195,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
|||
JACKSON_PRESENT = ClassUtils.isPresent("tools.jackson.databind.ObjectMapper", classLoader);
|
||||
JACKSON_2_PRESENT = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
|
||||
KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||
KOTLIN_SERIALIZATION_PRESENT = ClassUtils.isPresent("kotlinx.serialization.Serializable", classLoader);
|
||||
}
|
||||
|
||||
|
@ -659,7 +663,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
|||
requestBodyAdvices.add(new JsonViewRequestBodyAdvice());
|
||||
responseBodyAdvices.add(new JsonViewResponseBodyAdvice());
|
||||
}
|
||||
if (KOTLIN_SERIALIZATION_PRESENT) {
|
||||
if (KOTLIN_REFLECT_PRESENT && KOTLIN_SERIALIZATION_PRESENT) {
|
||||
requestBodyAdvices.add(new KotlinRequestBodyAdvice());
|
||||
responseBodyAdvices.add(new KotlinResponseBodyAdvice());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue