From 459e8a1ea5929e05aa4ab3495b58997ed6a31b07 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 22 Nov 2022 19:26:15 +0100 Subject: [PATCH] Deprecate LocalVariableTableParameterNameDiscoverer completely LocalVariableTableParameterNameDiscoverer is not registered by default anymore now. Java sources should be compiled with `-parameters` instead (available since Java 8). Also retaining standard Java parameter names for all of Spring's Kotlin sources now. Closes gh-29531 --- .../springframework/build/KotlinConventions.java | 1 + .../src/docs/asciidoc/web/webflux.adoc | 4 ++-- framework-docs/src/docs/asciidoc/web/webmvc.adoc | 4 ++-- ...lifierAnnotationAutowireBeanFactoryTests.java | 10 +++++----- .../core/DefaultParameterNameDiscoverer.java | 8 +------- ...ocalVariableTableParameterNameDiscoverer.java | 2 ++ .../PayloadMethodArgumentResolverTests.java | 6 +++--- .../handler/invocation/ResolvableMethod.java | 6 +++--- .../InitBinderDataBinderFactoryTests.java | 4 ++-- .../web/method/annotation/ModelFactoryTests.java | 6 +++--- .../web/testfixture/method/ResolvableMethod.java | 6 +++--- .../InitBinderBindingContextTests.java | 4 ++-- .../RequestPartMethodArgumentResolverTests.java | 16 ++++++++-------- 13 files changed, 37 insertions(+), 40 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/build/KotlinConventions.java b/buildSrc/src/main/java/org/springframework/build/KotlinConventions.java index f0ef7f3d59..438501d228 100644 --- a/buildSrc/src/main/java/org/springframework/build/KotlinConventions.java +++ b/buildSrc/src/main/java/org/springframework/build/KotlinConventions.java @@ -38,6 +38,7 @@ public class KotlinConventions { kotlinOptions.setApiVersion("1.7"); kotlinOptions.setLanguageVersion("1.7"); kotlinOptions.setJvmTarget("17"); + kotlinOptions.setJavaParameters(true); kotlinOptions.setAllWarningsAsErrors(true); List freeCompilerArgs = new ArrayList<>(compile.getKotlinOptions().getFreeCompilerArgs()); freeCompilerArgs.addAll(List.of("-Xsuppress-version-warnings", "-Xjsr305=strict", "-opt-in=kotlin.RequiresOptIn")); diff --git a/framework-docs/src/docs/asciidoc/web/webflux.adoc b/framework-docs/src/docs/asciidoc/web/webflux.adoc index a6f37f772d..98f888bb21 100644 --- a/framework-docs/src/docs/asciidoc/web/webflux.adoc +++ b/framework-docs/src/docs/asciidoc/web/webflux.adoc @@ -1532,8 +1532,8 @@ register support for any other data type. See <> and <>. URI variables can be named explicitly (for example, `@PathVariable("customId")`), but you can -leave that detail out if the names are the same and you compile your code with debugging -information or with the `-parameters` compiler flag on Java 8. +leave that detail out if the names are the same and you compile your code with the `-parameters` +compiler flag. The syntax `{*varName}` declares a URI variable that matches zero or more remaining path segments. For example `/resources/{*path}` matches all files under `/resources/`, and the diff --git a/framework-docs/src/docs/asciidoc/web/webmvc.adoc b/framework-docs/src/docs/asciidoc/web/webmvc.adoc index d534b837a8..1c72cf68f6 100644 --- a/framework-docs/src/docs/asciidoc/web/webmvc.adoc +++ b/framework-docs/src/docs/asciidoc/web/webmvc.adoc @@ -1699,8 +1699,8 @@ register support for any other data type. See <> and <>. You can explicitly name URI variables (for example, `@PathVariable("customId")`), but you can -leave that detail out if the names are the same and your code is compiled with debugging -information or with the `-parameters` compiler flag on Java 8. +leave that detail out if the names are the same and your code is compiled with the `-parameters` +compiler flag. The syntax `{varName:regex}` declares a URI variable with a regular expression that has syntax of `{varName:regex}`. For example, given URL `"/spring-web-3.0.5.jar"`, the following method diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/QualifierAnnotationAutowireBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/QualifierAnnotationAutowireBeanFactoryTests.java index f660a8af02..fe190c8b9f 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/QualifierAnnotationAutowireBeanFactoryTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/QualifierAnnotationAutowireBeanFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.beans.factory.config.DependencyDescriptor; -import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.MethodParameter; import org.springframework.util.ClassUtils; @@ -148,7 +148,7 @@ public class QualifierAnnotationAutowireBeanFactoryTests { lbf.registerBeanDefinition(MARK, person2); MethodParameter param = new MethodParameter(QualifiedTestBean.class.getDeclaredConstructor(Person.class), 0); DependencyDescriptor qualifiedDescriptor = new DependencyDescriptor(param, false); - param.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer()); + param.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); assertThat(param.getParameterName()).isEqualTo("tpb"); assertThat(lbf.isAutowireCandidate(JUERGEN, null)).isTrue(); assertThat(lbf.isAutowireCandidate(JUERGEN, qualifiedDescriptor)).isTrue(); @@ -174,9 +174,9 @@ public class QualifierAnnotationAutowireBeanFactoryTests { new MethodParameter(QualifiedTestBean.class.getDeclaredMethod("autowireNonqualified", Person.class), 0); DependencyDescriptor qualifiedDescriptor = new DependencyDescriptor(qualifiedParam, false); DependencyDescriptor nonqualifiedDescriptor = new DependencyDescriptor(nonqualifiedParam, false); - qualifiedParam.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer()); + qualifiedParam.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); assertThat(qualifiedParam.getParameterName()).isEqualTo("tpb"); - nonqualifiedParam.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer()); + nonqualifiedParam.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); assertThat(nonqualifiedParam.getParameterName()).isEqualTo("tpb"); assertThat(lbf.isAutowireCandidate(JUERGEN, null)).isTrue(); assertThat(lbf.isAutowireCandidate(JUERGEN, nonqualifiedDescriptor)).isTrue(); diff --git a/spring-core/src/main/java/org/springframework/core/DefaultParameterNameDiscoverer.java b/spring-core/src/main/java/org/springframework/core/DefaultParameterNameDiscoverer.java index 11b68ace14..e5c428b82f 100644 --- a/spring-core/src/main/java/org/springframework/core/DefaultParameterNameDiscoverer.java +++ b/spring-core/src/main/java/org/springframework/core/DefaultParameterNameDiscoverer.java @@ -18,9 +18,7 @@ package org.springframework.core; /** * Default implementation of the {@link ParameterNameDiscoverer} strategy interface, - * using the Java 8 standard reflection mechanism (if available), and falling back - * to the ASM-based {@link LocalVariableTableParameterNameDiscoverer} (when not in - * a native image) for checking debug information in the class file. + * delegating to the Java 8 standard reflection mechanism. * *

If a Kotlin reflection implementation is present, * {@link KotlinReflectionParameterNameDiscoverer} is added first in the list and @@ -33,7 +31,6 @@ package org.springframework.core; * @author Sam Brannen * @since 4.0 * @see StandardReflectionParameterNameDiscoverer - * @see LocalVariableTableParameterNameDiscoverer * @see KotlinReflectionParameterNameDiscoverer */ public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDiscoverer { @@ -43,9 +40,6 @@ public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDisc addDiscoverer(new KotlinReflectionParameterNameDiscoverer()); } addDiscoverer(new StandardReflectionParameterNameDiscoverer()); - if (!NativeDetector.inNativeImage()) { - addDiscoverer(new LocalVariableTableParameterNameDiscoverer()); - } } } diff --git a/spring-core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.java b/spring-core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.java index f20807f119..8b194cf72d 100644 --- a/spring-core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.java +++ b/spring-core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.java @@ -53,7 +53,9 @@ import org.springframework.util.ClassUtils; * @author Chris Beams * @author Sam Brannen * @since 2.0 + * @deprecated as of 6.0.1, in favor of {@link StandardReflectionParameterNameDiscoverer} */ +@Deprecated public class LocalVariableTableParameterNameDiscoverer implements ParameterNameDiscoverer { private static final Log logger = LogFactory.getLog(LocalVariableTableParameterNameDiscoverer.class); diff --git a/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolverTests.java b/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolverTests.java index 2e71ce8815..1535df80cb 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolverTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import java.util.Locale; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.SynthesizingMethodParameter; import org.springframework.messaging.Message; @@ -81,7 +81,7 @@ public class PayloadMethodArgumentResolverTests { this.paramAnnotatedRequired = new SynthesizingMethodParameter(payloadMethod, 2); this.paramWithSpelExpression = new SynthesizingMethodParameter(payloadMethod, 3); this.paramValidated = new SynthesizingMethodParameter(payloadMethod, 4); - this.paramValidated.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer()); + this.paramValidated.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); this.paramValidatedNotAnnotated = new SynthesizingMethodParameter(payloadMethod, 5); this.paramNotAnnotated = new SynthesizingMethodParameter(payloadMethod, 6); } diff --git a/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/ResolvableMethod.java b/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/ResolvableMethod.java index 026e4a1162..0d44a805bd 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/ResolvableMethod.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/handler/invocation/ResolvableMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,7 @@ import org.springframework.cglib.proxy.Callback; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.Factory; import org.springframework.cglib.proxy.MethodProxy; -import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.MethodIntrospector; import org.springframework.core.MethodParameter; import org.springframework.core.ParameterNameDiscoverer; @@ -131,7 +131,7 @@ public class ResolvableMethod { private static final SpringObjenesis objenesis = new SpringObjenesis(); - private static final ParameterNameDiscoverer nameDiscoverer = new LocalVariableTableParameterNameDiscoverer(); + private static final ParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer(); // Matches ValueConstants.DEFAULT_NONE (spring-web and spring-messaging) private static final String DEFAULT_VALUE_NONE = "\n\t\t\n\t\t\n\uE000\uE001\uE002\n\t\t\t\t\n"; diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/InitBinderDataBinderFactoryTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/InitBinderDataBinderFactoryTests.java index ce284f935e..08fd411307 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/InitBinderDataBinderFactoryTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/InitBinderDataBinderFactoryTests.java @@ -21,7 +21,7 @@ import java.util.Collections; import org.junit.jupiter.api.Test; -import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.convert.ConversionService; import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.web.bind.WebDataBinder; @@ -128,7 +128,7 @@ public class InitBinderDataBinderFactoryTests { InvocableHandlerMethod handlerMethod = new InvocableHandlerMethod(handler, method); handlerMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers); handlerMethod.setDataBinderFactory(new DefaultDataBinderFactory(null)); - handlerMethod.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer()); + handlerMethod.setParameterNameDiscoverer(new DefaultParameterNameDiscoverer()); return new InitBinderDataBinderFactory( Collections.singletonList(handlerMethod), this.bindingInitializer); diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/ModelFactoryTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/ModelFactoryTests.java index b2c51c0e97..f859cb880f 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/ModelFactoryTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/ModelFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ import java.util.Collections; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.validation.BindingResult; @@ -252,7 +252,7 @@ public class ModelFactoryTests { InvocableHandlerMethod modelMethod = createHandlerMethod(methodName, parameterTypes); modelMethod.setHandlerMethodArgumentResolvers(resolvers); modelMethod.setDataBinderFactory(null); - modelMethod.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer()); + modelMethod.setParameterNameDiscoverer(new DefaultParameterNameDiscoverer()); return new ModelFactory(Collections.singletonList(modelMethod), null, this.attributeHandler); } diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/method/ResolvableMethod.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/method/ResolvableMethod.java index 82f73b06ca..163bc54794 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/method/ResolvableMethod.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/method/ResolvableMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,7 @@ import org.springframework.cglib.proxy.Callback; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.Factory; import org.springframework.cglib.proxy.MethodProxy; -import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.MethodIntrospector; import org.springframework.core.MethodParameter; import org.springframework.core.ParameterNameDiscoverer; @@ -130,7 +130,7 @@ public class ResolvableMethod { private static final SpringObjenesis objenesis = new SpringObjenesis(); - private static final ParameterNameDiscoverer nameDiscoverer = new LocalVariableTableParameterNameDiscoverer(); + private static final ParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer(); // Matches ValueConstants.DEFAULT_NONE (spring-web and spring-messaging) private static final String DEFAULT_VALUE_NONE = "\n\t\t\n\t\t\n\uE000\uE001\uE002\n\t\t\t\t\n"; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/InitBinderBindingContextTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/InitBinderBindingContextTests.java index d695a3f750..5233a4a52e 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/InitBinderBindingContextTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/InitBinderBindingContextTests.java @@ -23,7 +23,7 @@ import java.util.List; import org.junit.jupiter.api.Test; -import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.ReactiveAdapterRegistry; import org.springframework.core.convert.ConversionService; import org.springframework.format.support.DefaultFormattingConversionService; @@ -131,7 +131,7 @@ public class InitBinderBindingContextTests { SyncInvocableHandlerMethod handlerMethod = new SyncInvocableHandlerMethod(handler, method); handlerMethod.setArgumentResolvers(new ArrayList<>(this.argumentResolvers)); - handlerMethod.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer()); + handlerMethod.setParameterNameDiscoverer(new DefaultParameterNameDiscoverer()); return new InitBinderBindingContext(this.bindingInitializer, Collections.singletonList(handlerMethod)); } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolverTests.java index 7dd476cb30..2c075f1b63 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestPartMethodArgumentResolverTests.java @@ -32,7 +32,7 @@ import jakarta.validation.constraints.NotNull; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.SynthesizingMethodParameter; import org.springframework.http.HttpInputMessage; @@ -137,7 +137,7 @@ public class RequestPartMethodArgumentResolverTests { Method method = ReflectionUtils.findMethod(getClass(), "handle", (Class[]) null); paramRequestPart = new SynthesizingMethodParameter(method, 0); - paramRequestPart.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer()); + paramRequestPart.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); paramNamedRequestPart = new SynthesizingMethodParameter(method, 1); paramValidRequestPart = new SynthesizingMethodParameter(method, 2); paramMultipartFile = new SynthesizingMethodParameter(method, 3); @@ -145,20 +145,20 @@ public class RequestPartMethodArgumentResolverTests { paramMultipartFileArray = new SynthesizingMethodParameter(method, 5); paramInt = new SynthesizingMethodParameter(method, 6); paramMultipartFileNotAnnot = new SynthesizingMethodParameter(method, 7); - paramMultipartFileNotAnnot.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer()); + paramMultipartFileNotAnnot.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); paramPart = new SynthesizingMethodParameter(method, 8); - paramPart.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer()); + paramPart.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); paramPartList = new SynthesizingMethodParameter(method, 9); paramPartArray = new SynthesizingMethodParameter(method, 10); paramRequestParamAnnot = new SynthesizingMethodParameter(method, 11); optionalMultipartFile = new SynthesizingMethodParameter(method, 12); - optionalMultipartFile.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer()); + optionalMultipartFile.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); optionalMultipartFileList = new SynthesizingMethodParameter(method, 13); - optionalMultipartFileList.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer()); + optionalMultipartFileList.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); optionalPart = new SynthesizingMethodParameter(method, 14); - optionalPart.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer()); + optionalPart.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); optionalPartList = new SynthesizingMethodParameter(method, 15); - optionalPartList.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer()); + optionalPartList.initParameterNameDiscovery(new DefaultParameterNameDiscoverer()); optionalRequestPart = new SynthesizingMethodParameter(method, 16); }