Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AnnotatedElementUtils does not find merged repeatable annotations on other repeatable annotations #20279

Closed
spring-projects-issues opened this issue Jul 1, 2017 · 4 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Jul 1, 2017

Liam Bryan opened SPR-15723 and commented

Meta annotations are not detected when present on Repeatable annotations.

Provided zip contains a quick example highlighting this, but for a contained example here (@Retention and @Target annotations omitted):

@Repeatable(A.List.class)
@interface A {

    int value() default 1;
    
    @interface List {
        A[] value();
    }

}
@Repeatable(B.List.class)
@A
@interface B {

    @AliasFor(annotation = A.class, attribute = "value")
    int value();
    
    @interface List {
        B[] value();
    }

}

None of the provided methods in AnnotationUtils or AnnotatedElementUtils can locate the meta-@A annotations for an element with repeated @B annotations.


Affects: 4.3.8

Attachments:

@spring-projects-issues spring-projects-issues added type: bug A general bug status: waiting-for-triage An issue we've not yet triaged or decided on in: core Issues in core modules (aop, beans, core, context, expression) and removed type: bug A general bug labels Jan 11, 2019
@sbrannen
Copy link
Member

Thanks for raising the issue, and I apologize that we took so long to triage it.

I was able to reproduce this against master with the following all-in-one test class.

import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;

import org.junit.jupiter.api.Test;
import org.springframework.core.annotation.AliasFor;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;

@SuppressWarnings("unused")
class AnnotationRetrievalTest {

	@Test
	void findAnnotationsSingle() throws Exception {
		Method singleAnnotatedMethod = getClass().getDeclaredMethod("singleAnnotatedMethod");

		// Passes.
		performTest(singleAnnotatedMethod, 1);
	}

	@Test
	void findAnnotationsMulti() throws Exception {
		Method multiAnnotatedMethod = getClass().getDeclaredMethod("multiAnnotatedMethod");

		// Fails (for all 3 sub-assertions).
		performTest(multiAnnotatedMethod, 2);
	}

	private void performTest(Method method, int expectedAnnotationCount) {
		Set<A> fromFindMergedRepeatable = AnnotatedElementUtils.findMergedRepeatableAnnotations(method, A.class);
		Set<A> fromFindMergedRepeatableWithContainer = AnnotatedElementUtils.findMergedRepeatableAnnotations(method,
				A.class, A.Container.class);
		Set<A> fromGetRepeatable = AnnotationUtils.getRepeatableAnnotations(method, A.class);
		List<A> fromJUnitFindRepeatable = org.junit.platform.commons.util.AnnotationUtils
				.findRepeatableAnnotations(method, A.class);

		assertAll(() -> assertEquals(expectedAnnotationCount, fromFindMergedRepeatable.size()),
				() -> assertEquals(expectedAnnotationCount, fromFindMergedRepeatableWithContainer.size()),
				() -> assertEquals(expectedAnnotationCount, fromGetRepeatable.size()),
				() -> assertEquals(expectedAnnotationCount, fromJUnitFindRepeatable.size()));
	}

	@Retention(RetentionPolicy.RUNTIME)
	@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
	@Repeatable(A.Container.class)
	public @interface A {

		int value() default 0;

		@Retention(RetentionPolicy.RUNTIME)
		@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
		@interface Container {
			A[] value();
		}
	}

	@Retention(RetentionPolicy.RUNTIME)
	@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
	@Repeatable(B.Container.class)
	@A
	public @interface B {

		@AliasFor(annotation = A.class)
		int value();

		@Retention(RetentionPolicy.RUNTIME)
		@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
		@interface Container {
			B[] value();
		}
	}

	@B(5)
	void singleAnnotatedMethod() {
	}

	@B(5)
	@B(10)
	void multiAnnotatedMethod() {
	}

}

Interestingly, the supplied example.zip was testing org.junit.platform.commons.util.AnnotationUtils.findRepeatableAnnotations from JUnit 5 instead of org.springframework.core.annotation.AnnotationUtils.getRepeatableAnnotations from Spring. In any case, the error is the same. Neither Spring nor JUnit 5 find the repeatable annotation for the "multi" scenario.

@philwebb and @jhoeller, do you think we should try to add support for this scenario?

@sbrannen sbrannen added for: team-attention and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Aug 18, 2020
@sbrannen
Copy link
Member

sbrannen commented Aug 18, 2020

Actually, after having put further thought into it, the expectation for AnnotationUtils.getRepeatableAnnotations (as well as for JUnit's similar method) is invalid.

getRepeatableAnnotations does not merge annotation attributes. Thus, the algorithm may encounter @A twice, but each encounter is seen as the same instance. The @A annotation is therefore only found once. Consequently, the expectation should be 1 instead of 2 for the non-merging search algorithms.

@sbrannen sbrannen added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 18, 2021
@rstoyanchev rstoyanchev self-assigned this Oct 11, 2022
@sbrannen sbrannen assigned sbrannen and unassigned rstoyanchev Oct 11, 2022
@sbrannen sbrannen added type: bug A general bug and removed for: team-attention status: waiting-for-triage An issue we've not yet triaged or decided on labels Oct 11, 2022
@sbrannen sbrannen added this to the 5.3.24 milestone Oct 11, 2022
@sbrannen sbrannen changed the title Repeated meta-annotations not locatable on repeated annotation. [SPR-15723] AnnotatedElementUtils.findMergedRepeatableAnnotations() does not support nested repeatable annotation types Oct 11, 2022
@sbrannen
Copy link
Member

Reopening to address the same issue in AnnotatedElementUtils.getMergedRepeatableAnnotations().

@sbrannen sbrannen reopened this Oct 11, 2022
@sbrannen sbrannen changed the title AnnotatedElementUtils.findMergedRepeatableAnnotations() does not support nested repeatable annotation types AnnotatedElementUtils does not find merged repeatable annotations on other repeatable annotations Oct 11, 2022
@sbrannen
Copy link
Member

It turns out that we already had support for finding repeatable annotations used as meta-annotations on other repeatable annotations.

This is possible via the MergedAnnotations API.

However, the way that RepeatableContainers were previously configured in AnnotatedElementUtils for the getMergedRepeatableAnnotations() and findMergedRepeatableAnnotations() methods effectively limited the annotation search in a way that it only supported one type of repeatable annotation.

I fixed this in 828f74f and 9876701.

See the commit messages as well as the associated tests for details.

sbrannen added a commit to sbrannen/spring-framework that referenced this issue Oct 11, 2022
sbrannen added a commit that referenced this issue Dec 13, 2022
Prior to this commit, there was a bug in the implementation of
StandardRepeatableContainers.computeRepeatedAnnotationsMethod() which
has existed since Spring Framework 5.2 (when
StandardRepeatableContainers was introduced). Specifically,
StandardRepeatableContainers ignored any repeatable container
annotation if it declared attributes other than `value()`. However,
Java permits any number of attributes in a repeatable container
annotation.

In addition, the changes made in conjunction with gh-20279 made the bug
in StandardRepeatableContainers apparent when using the
getMergedRepeatableAnnotations() or findMergedRepeatableAnnotations()
method in AnnotatedElementUtils, resulting in regressions for the
behavior of those two methods.

This commit fixes the regressions and bug by altering the logic in
StandardRepeatableContainers.computeRepeatedAnnotationsMethod() so that
it explicitly looks for the `value()` method and ignores any other
methods declared in a repeatable container annotation candidate.

See gh-29685
Closes gh-29686
sbrannen added a commit to sbrannen/spring-framework that referenced this issue Dec 13, 2022
Prior to this commit, there was a bug in the implementation of
StandardRepeatableContainers.computeRepeatedAnnotationsMethod() which
has existed since Spring Framework 5.2 (when
StandardRepeatableContainers was introduced). Specifically,
StandardRepeatableContainers ignored any repeatable container
annotation if it declared attributes other than `value()`. However,
Java permits any number of attributes in a repeatable container
annotation.

In addition, the changes made in conjunction with spring-projectsgh-20279 made the bug
in StandardRepeatableContainers apparent when using the
getMergedRepeatableAnnotations() or findMergedRepeatableAnnotations()
method in AnnotatedElementUtils, resulting in regressions for the
behavior of those two methods.

This commit fixes the regressions and bug by altering the logic in
StandardRepeatableContainers.computeRepeatedAnnotationsMethod() so that
it explicitly looks for the `value()` method and ignores any other
methods declared in a repeatable container annotation candidate.

Closes spring-projectsgh-29685
toneofrain added a commit to toneofrain/spring-framework that referenced this issue Dec 23, 2022
* Upgrade to Reactor 2020.0.25

See spring-projectsgh-29464

* Polish AOT ref docs

* Update testing chapter regarding Servlet 6.0 baseline for mocks

* Document TestSocketUtils in the testing chapter

* Fix Javadoc formatting issue in TestSocketUtils

* Revert "Ignore HttpComponents Javadoc"

This reverts commit f50b472.

HttpComponents Javadoc is available again.

See spring-projectsgh-29479
See https://issues.apache.org/jira/browse/HTTPCLIENT-2227

* Fix section formatting in the testing chapter

* Document AOT support in the TestContext framework

Closes spring-projectsgh-29482

* Assert fixed in DefaultErrorResponseBuilder

Fixed assert on wrong constructor fields

* Polish

* Align javadoc of DefaultParameterNameDiscoverer with its behavior

* Polishing deprecated methods

Added since and forRemoval to Deprecated methods.

* Add milestone repo for optional Netty 5 support

Closes spring-projectsgh-29498

* Next development version (v6.0.1-SNAPSHOT)

* Suppress "removal" warnings in CronSequenceGeneratorTests

* Polishing

* Fix Javadoc formatting issues for headings

Headings in method-level Javadoc must be h4 or higher in recent versions
of Java.

* Update Jackson-based decoders to reflect 2.14 baseline

See spring-projectsgh-29508

* Refactor Asciidoctor attributes in reference docs

This commit reorganizes the asciidoctor attributes for the reference
documentation. Instead of being contributed partially by the build and
individual documents, attributes are now shared in common files that are
included in top sections.

* Polishing

* Add callouts to Kotlin examples for parity

* Add missing callouts

* Work around code example callout bug

This commit adds callouts to two sets of Java/Kotlin code examples in
the @ModelAttribute section for Web MVC in order to work around the
"Code example has callout from a different code example" bug.

This also aligns the Web MVC examples with the WebFlux examples.

As a side note, the bug can also be seen in the WebFlux documentation
if the callouts are removed from the first Java/Kotlin examples in the
@ModelAttribute section for WebFlux. Thus it appears to be a general
issue related to examples within a given section of the documentation
when some examples have callouts and others do not, likely due to a bug
in the Javascript that provides this feature.

See spring-projectsgh-29505

* Polishing

* Generalize Jackson version numbers

This commit removes specific version info from Jackson codecs and
converters, in favor of generic info or removing the version information
all together.

See spring-projectsgh-29508

* Use lambda expression for Callable example in ref docs

* Document GraalVM substitutions upcoming removal

* Update documentation to mention Java 17+ baseline

Closes spring-projectsgh-29514

* Fix link to WebFlux section

Closes spring-projectsgh-29513

* Set error status in Observation Servlet filter

Prior to this commit, the Observation Servlet filter would record
unhandled exceptions on the observation context but would leave the
default HTTP response status as is.
Servlet containers do set the response status in that case to 500 by
default. Not doing that at the Servlet filter level results in invalid
observations, stating that the HTTP response status is 200 (because the
error status hasn't been set yet by the container) and as a result, the
outcome is SUCCESS.

This commit ensures that the error status is set in those cases,
aligning the behavior with Servlet containers.

Fixes spring-projectsgh-29512

* Polish AbstractAutowireCapableBeanFactory and use instanceof pattern matching

Closes spring-projectsgh-29499

* Polish contribution

* Polishing

* Polish asciidoc attributes

* Reorganize and modularize the Testing chapter in the reference manual

Closes spring-projectsgh-29522

* Document RuntimeHints testing strategies

Closes spring-projectsgh-29523

* Disable checkstyle for reference docs code snippets

* Fix broken link to Web MVC Testing section

* Remove TODOs in WebFlux ref docs

* Polishing

* Fix link to WebFlux section in reference manual

Closes spring-projectsgh-29525

* Introduce appendix in Testing chapter in the reference manual

This commit moves the Annotations and Further Resources sections to the
new Appendix.

See spring-projectsgh-29522

* Reinstate `chapter` asciidoc attribute for Web MVC

* Polish asciidoc attributes

* Ensure source code in framework-docs is compiled in the build

This also ensures that the source code can be properly imported into an
IDE.

* Polish ref docs

- stop referring to Java Config as new
- stop referring to Struts 2.x as if it were new
- polish AOT documentation
- etc.

* Polish ref docs

* Ensure code listing callouts are displayed incorrectly in core-beans.adoc

Closes spring-projectsgh-29457

* Fix a syntax error in an XML listing by adding a missing double-quote

Closes spring-projectsgh-29456

* Update LogAdapter to allow build-time code removal

Allow for example to remove those classes and 90 related methods when Logback is used:
- org.apache.commons.logging.LogAdapter$JavaUtilAdapter
- org.apache.commons.logging.LogAdapter$JavaUtilLog
- org.apache.commons.logging.LogAdapter$LocationResolvingLogRecord
- org.apache.commons.logging.LogAdapter$Log4jAdapter
- org.apache.commons.logging.LogAdapter$Log4jLog
- org.apache.commons.logging.LogAdapter$LogApi
- org.apache.logging.log4j.message.ObjectMessage
- org.apache.logging.log4j.message.ReusableObjectMessage
- org.apache.logging.log4j.simple.SimpleLoggerContext
- org.apache.logging.log4j.simple.SimpleLoggerContextFactory

Closes spring-projectsgh-29506

* Do not use LocalVariableTableParameterNameDiscoverer in AOT mode

Closes spring-projectsgh-29531

* Revert "Ensure source code in framework-docs is compiled in the build"

This reverts commit c45f8b7.

* Make GeneratorStrategy.generate unreachable on native

This change provides also more information to the user
about the missing generated class when that happens.

Closes spring-projectsgh-29521

* Apply 'instanceof pattern matching' in spring-web

Closes spring-projectsgh-29530

* Polish contribution

See spring-projectsgh-29530

* Apply additional 'instanceof pattern matching' in spring-web

See spring-projectsgh-29530

* Use Set.of() for constant sets where appropriate

* Fix link to Bean Utils Light Library in BeanUtils Javadoc

The URL for the BULL library has changed (not sure when, probably way back).

This updates it to the correct location.

Closes spring-projectsgh-29534

* Make SourceHttpMessageConverter optional

As a follow-up to spring-projectsgh-29277, and since the JAXB support is now
triggered by the classpath presence of a JAXB implementation,
it makes sense to make SourceHttpMessageConverter, previously
configured unconditionally, optional.

That makes a big difference on native (1M of RSS reduction
with current typical Spring Boot 3 arrangement, 3.4M when
other usages of XML are not reachable).

It also brings more consistency between Spring MVC
and Spring WebFlux, and means that XML support for
Spring web applications now needs to be enabled explicitly.

As a consequence, Spring web applications using
javax.xml.transform.Source now needs to configure
SourceHttpMessageConverter explicitly in RestTemplate or
Spring MVC.

Closes spring-projectsgh-29535

* Upgrade to Jackson 2.14.1

Fix an important memory consumption regression, see
FasterXML/jackson-databind#3665
for more details.

Closes spring-projectsgh-29539

* Fix some typos in Kotlin WebClient example code

Closes spring-projectsgh-29538

* Upgrade to Kotlin 1.7.21

Closes spring-projectsgh-29543

* Refine LogAdapter#isPresent

Align LogAdapter#isPresent with ClassUtils#isPresent in order
to catch NoClassDefFoundError and other errors.

Closes spring-projectsgh-29506

* Fix Javadoc link text in BindingResult

Closes spring-projectsgh-29551

* Polishing

* Polish ServletWebRequest and DefaultServerWebExchange

- The return values of ServletWebRequest.validateIfUnmodifiedSince and
  DefaultServerWebExchange.validateIfUnmodifiedSince are not used. So I
  think that it is better to remove the return statements.

- Add missing @nullable declarations to eTag method parameters.

- Simplify if statements

Closes spring-projectsgh-29460

* Polish contribution

See spring-projectsgh-29460

* Apply 'instanceof pattern matching'

* Exclude LocalVariableTableParameterNameDiscoverer based on native image check

See spring-projectsgh-29531

* Apply 'instanceof pattern matching'

* Polishing

* Use AssertJ's hasSize() for collections and maps

Achieved via a global search-and-replace.

* User AssertJ's hasSize() for arrays

Achieved via global search-and-replace.

* Use AssertJ's isEmpty() instead of hasSize(0)

Achieved via global search-and-replace.

* Temporarily re-enable ReactorNetty2StompBrokerRelayIntegrationTests

To see if it still fails on the CI server as it doesn't fail locally
for me, and if it does to get details to investigate.

See spring-projectsgh-29287

* 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 spring-projectsgh-29531

* Add since attribute to Deprecated annotation

Also retaining standard Java parameter names for Spring's AspectJ sources now.

See spring-projectsgh-29531

* Increase logging for spring-messaging tests

See spring-projectsgh-29287

* Fix javadoc link in AOP extensibility documentation

Closes spring-projectsgh-29554

* Retain default LocalVariableTableParameterNameDiscoverer with warn log entries

For a transition period, LocalVariableTableParameterNameDiscoverer logs a warning for each successful resolution attempt now, suggesting that -parameters was missed.

See spring-projectsgh-29531
See spring-projectsgh-29559

* Next development version (v6.0.2-SNAPSHOT)

* Log connection info in StompBrokerRelayMessageHandler

See spring-projectsgh-29287

* Document removal of CommonsMultipartResolver in MVC setup documentation

Closes spring-projectsgh-29562

* Reduce deprecation warn logging to one entry per introspected class

Closes spring-projectsgh-29563

* Rely on standard parameter name resolution in Bean Validation 3.0

Just configuring additional Kotlin reflection if Kotlin is present.

Closes spring-projectsgh-29566

* ResponseStatusException sets detail from reason again

Closes spring-projectsgh-29567

* Additional documentation notes on Java/Kotlin parameter name retention

See spring-projectsgh-29563

* Next development version (v6.0.3-SNAPSHOT)

* Early support for Jetty 12 (developed against 12.0.0.alpha2)

Reflective getHeaders calls to be revisited; see GitHub issue spring-projects#8938 in Jetty project.
HttpOutput optimization commented out still in order to avoid alpha build dependency.

See spring-projectsgh-29575

* Deprecate JettyWebSocketClient in favor of StandardWebSocketClient

JettyWebSocketClient only supported on Jetty 11, to be phased out.

Closes spring-projectsgh-29576

* Consistent documentation references to Jakarta WebSocket (2.1)

Closes spring-projectsgh-29581

* Reinstate checkstyle for reference docs code snippets

This commit also ensures that checks are performed before the
application is rendered to get early feedback on errors.

* Fix unrendered titles in websocket section

This commit fixes the rendering of titles in the websocket section of
the reference documentation.

Fixes spring-projectsgh-29569

* Split integration chapter in smaller documents

This commit splits the integration chapter of the reference
documentation in smaller documents for easier maintenance.

* Document Observability support in reference docs

Closes spring-projectsgh-29524

* Upgrade to Gradle 7.6

Closes spring-projectsgh-29583

* Upgrade Gradle wrapper

See spring-projectsgh-29583

* Consistently register CGLIB hints for lazy resolution proxy classes

Core JDK/CGLIB proxy registration code extracted to ClassHintUtils.

Closes spring-projectsgh-29584

* Remove erroneous Javadoc link

* Improve logging in TestContextManager

* Forbid loading of test ApplicationContext in AOT mode if AOT processing failed

Prior to this commit, if AOT processing of a test's ApplicationContext
failed, the TestContext Framework (TCF) still attempted to load the
context via standard (JVM) mechanisms when running in AOT mode.

For example, if a test class uses Spring Boot's @MockBean, AOT
processing of that test's context will fail with a WARN log message,
and there will no mapping from that test class to an AOT-generated
ApplicationContextInitializer (ACI). Consequently, when the test suite
is run in AOT mode that particular test class will currently fail with
a confusing stack trace due to the fact that Spring Boot's
SpringApplication attempts to locate a "main" ACI instead of the
missing "test" ACI (missing because it was not generated during AOT
processing).

In general, the TCF should not attempt to load an ApplicationContext in
"JVM mode" while running in "AOT mode".

This commit therefore reworks the logic in
DefaultCacheAwareContextLoaderDelegate to fail fast (with a meaningful
error message) if an AOT-generated ACI cannot be found while running in
AOT mode. This avoids the aforementioned confusion when @MockBean tests
fail in AOT mode (on the JVM or within a native image), and it also
helps to diagnose build problems if AOT processing has not yet been
performed for the project's test suite.

Closes spring-projectsgh-29579

* Polish TestContextManager internals

* Use JUnit Jupiter annotations as examples in TestContextManager JavaDoc

* Update Javadoc regarding JUnit versions

* Add MessageSource getters

See spring-projectsgh-29574

* Polish Testing chapter

* Fix errors in Testing chapter

- group code example callouts to ensure callouts are displayed for the
  correct examples

- add missing callouts

- fix syntax, annotation attribute names, etc.

* Fix typo in observability documentation

Closes spring-projectsgh-29590

* Add title to SockJS iFrames for accessibility compliance

Closes spring-projectsgh-29594

* Polish contribution

See spring-projectsgh-29594

* Polishing

* Fix broken tests in SockJsServiceTests

See spring-projectsgh-29594

* Avoid deprecation warnings in tests

* Rename to AbstractReactiveWebSocketIntegrationTests to avoid duplicate class names

* Polishing

* Polishing

* Add "missing" callout for parity

* Fix code example callouts in reference manual

* Add missing callout

* Apply project formatting rules for ternary operator

Discovered via RegEx: ^\s+\?

* Apply "instanceof pattern matching"

* Introduce update_copyright_headers.sh shell script

In order to automate maintenance of copyright headers in our source
code (especially when merging PRs from external contributors), this
commit introduces an update_copyright_headers.sh script (tested on
mac OS) that will update the copyright headers of all Java, Kotlin,
and Groovy source files that have been added or modified this year
(or at least as far back as the git log history supports it).

For example, running this script currently outputs the following.

Updating copyright headers in Java, Kotlin, and Groovy source code for year 2022
warning: log for 'main' only goes back to Tue, 16 Aug 2022 16:24:55 +0200

* Update copyright headers for source code changed since August 2022

The changes in this commit were performed using the newly introduced
update_copyright_headers.sh script.

* Update Javadoc for MBeanTestUtils

* Apply update_copyright_headers.sh to staged files as well

* Avoid unnecessary parameter name inspection for constructor-arg resolution

Closes spring-projectsgh-29612

* Add equals/hashCode methods to ProblemDetail

Closes spring-projectsgh-29606

* Polishing

* Polish

Closes spring-projectsgh-29619

* Use resolved factory method return type for supplier code generation

Closes spring-projectsgh-29598

* Polishing

* Revised support for Jetty 12 (tested against 12.0.0.alpha2)

Avoids HttpFields optimization completely, relying on Servlet header access instead.
ServletServerHttpResponse provides applyHeaders/adaptHeaders split for better reuse.

See spring-projectsgh-29575

* ResponseStatusException delegates to protected constructor

This ensures that by default the reason is used to set the "detail"
field. It's a follow-up fix to a27f2e9
which resolved the issue partially.

Closes spring-projectsgh-29608

* Deprecate GraphQL media type in favor of new one

This commit deprecates the `"application/graphql+json"` media type in
favor of the new `"application/graphql-response+json"`, since the former
has been removed in graphql/graphql-over-http#215.

Closes spring-projectsgh-29617

* Fix URI override for HttpExchange

Closes spring-projectsgh-29624

* Upgrade to Apache HttpClient 5.2

Includes JRuby 9.4, Groovy 4.0.6, Hibernate ORM 5.6.14, HSQLDB 2.7.1, SLF4J 2.0.5, Caffeine 3.1.2, Gson 2.10, POI 5.2.3, Protobuf 3.21.10, WebJars Locator 0.52, HtmlUnit 2.67, Mockito 4.9, Checkstyle 10.5

Closes spring-projectsgh-29627

* Fix ErrorResponse#type documentation

Closes spring-projectsgh-29632

* Apply "instanceof pattern matching"

* Polish Javadoc for ErrorResponse etc.

* Reinstate test for JmxUtils.locateMBeanServer()

* Update copyright headers

* Polish overview for consistency

* Do not refer to HTML ref docs from HTML ref docs

* Revise PDF ref docs to include TOC, authors, and legal sections

* Polish ref docs build

* Upgrade JMH build plugins

This commit upgrades the Gradle JMH plugin to 0.6.8 and the companion
JMH version to 1.36.

* Reduce heap memory usage in ConcurrentLruCache

Prior to this commit, the `ConcurrentLruCache` implementation would use
arrays of `AtomicReference` as operation buffers, and the buffer count
would be calculated with the nearest power of two for the CPU count.

This can result in significant heap memory usage as each
`AtomicReference` buffer entry adds to the memory pressure. As seen in
FasterXML/jackson-databind#3665, this can add a significant overhead for
no real added benefit for the current use case.

This commit changes the current implementation to use
`AtomicReferenceArray` as buffers and reduce the number of buffers.
JMH benchmarks results are within the error margin so we can assume that
this does not change the performance characteristics for the typical use
case in Spring Framework.

Fixes spring-projectsgh-29520

* Improve invalid Content-Type handling in WebFlux

Closes spring-projectsgh-29565

* Simplify form data handling in HttpRequestValues

Closes spring-projectsgh-29615

* Improve Netty code sample

See spring-projectsgh-29622

* Polishing contribution

Closes spring-projectsgh-29622

* Fix canWrite of PartHttpMessageWriter

See spring-projectsgh-29631

* Push canWrite down into MultipartHttpMessageWriter

The implementation in the base class only matches the
MultipartHttpMessageWriter subclass. The other two override it anyway.

Closes spring-projectsgh-29631

* Polishing, suppression of deprecation warnings, copyright headers, etc.

* Enable backport bot for pull requests

* Correct event name in backport bot config

* Add write permission in backport bot config

* Correct permissions key in backport bot config

* Correct (again) permissions key in backport bot config

* Fall back to JdkClientHttpConnector as ClientHttpConnector

* Fix issue with getHeaders in NoHandlerFoundException

Closes spring-projectsgh-29626

* Add convenience methods for binding error messages

Closes spring-projectsgh-29574

* Apply "instanceof pattern matching" in spring-webflux

Closes spring-projectsgh-29635

* Polishing

* Rename MultipartWebClientIntegrationTests classes to avoid duplicate names

* Polishing

* Reintroduce component index support for Jakarta annotations

Spring Framework 6.0 GA introduced a regression in the component index
support for Jakarta annotations such as @nAmed and @ManagedBean.

Prior to this commit, @nAmed and @ManagedBean components were
registered in the component index at build time; however, component
scanning failed to find those component at run time.

This commit updates ClassPathScanningCandidateComponentProvider so that
`jakarta.*` annotation types are once again supported for component
scanning via the component index at run time.

Closes spring-projectsgh-29641

* Polish var-args declarations

Closes spring-projectsgh-29640

* Fix InputStream violation in DataBufferInputStream

This commit fixes an issue in DataBufferInputStream::mark, which before
did not follow the contract defined by InputStream.

Closes spring-projectsgh-29642

* Fix BindingReflectionHintsRegistrar anonymous classes support

This commit ensures that giving an anonymous class for reflection hints
registration does not result in a NullPointerException, since the
canonical name of anonymous classes is null.

Fixes spring-projectsgh-29657

* Update copyright headers

* Improve Javadoc for SqlLobValue

* Introduce @suite classes for individual modules

* Polishing

* Fix SpEL support for quotes within String literals

Prior to this commit, there were two bugs in the support for quotes
within String literals in SpEL expressions.

- Two double quotes ("") or two single quotes ('') were always replaced
  with one double quote or one single quote, respectively, regardless
  of which quote character was used to enclose the original String
  literal. This resulted in the loss of one of the double quotes when
  the String literal was enclosed in single quotes, and vice versa. For
  example, 'x "" y' became 'x " y'.

- A single quote which was properly escaped in a String literal
  enclosed within single quotes was not escaped in the AST string
  representation of the expression. For example, 'x '' y' became 'x ' y'.

This commit fixes both of these related issues in StringLiteral and
overhauls the structure of ParsingTests.

Closes spring-projectsgh-29604, spring-projectsgh-28356

* Apply 'instanceof pattern matching' in spring-jdbc

* Apply 'instanceof pattern matching' in spring-expression

* Polishing

* Support arrays in AST string representations of SpEL expressions

Prior to this commit, SpEL's ConstructorReference did not provide
support for arrays when generating a string representation of the
internal AST. For example, 'new String[3]' was represented as 'new
String()' instead of 'new String[3]'.

This commit introduces support for standard array construction and array
construction with initializers in ConstructorReference's toStringAST()
implementation.

Closes spring-projectsgh-29665

* Polishing

- primarily automated "clean up" using Eclipse IDE

* Polish CGLIB fork

- primarily automated "clean up" using Eclipse IDE

* Remove top-level permissions from backport-bot.yml

* Optimize object creation PartialMatchHelper

See spring-projectsgh-29634

* Polishing contribution

Closes spring-projectsgh-29634

* Restore top-level read permission for backport bot

* Apply 'instanceof pattern matching' in spring-test and Servlet mocks

* Polish tests in spring-test

* Use URI#create instead of URI constructor where feasible in spring-test

* Use URI#create instead of URI constructor where feasible in spring-web

* Use URI#create instead of URI constructor where feasible in spring-webflux

* Use URI#create instead of URI constructor where feasible in spring-webmvc

* Use URI#create instead of URI constructor where feasible in spring-websocket

* Introduce additional constructors in MockClientHttp[Request|Response]

This commit introduces additional constructors in MockClientHttpRequest
and MockClientHttpResponse that were previously only present in the
internal "test fixtures" in spring-web.

This commit also aligns the mocks in spring-test with the test fixtures
in spring-web to simplify continued maintenance of the mocks and test
fixtures.

Closes spring-projectsgh-29670

* Remove dead code in MockClientHttpRequest

* Support properties on records in BindingReflectionHintsRegistrar

Closes spring-projectsgh-29571

* Refine BindingReflectionHintsRegistrar Kotlin support

Closes spring-projectsgh-29593

* Make @ModelAttribute and @InitBinder reflective

Closes spring-projectsgh-29572

* Upgrade to Micrometer 1.10.2

Closes spring-projectsgh-29678

* Start building against Reactor 2022.0.1

See spring-projectsgh-29679

* Upgrade optional dependencies

* Use consistent visibility for ResponseEntityExceptionHandler.getMessageSource()

See spring-projectsgh-29574
Closes spring-projectsgh-29676

* Clean up Javadoc and source code regarding " ." typos

* Align multipart codecs on client and server

This commit ensures that the same multipart codecs are registered on
both client and server. Previously, only the client enabled only sending
 multipart, and the server only receiving.

Closes spring-projectsgh-29630

* Detect SQL state 23505/40001 as DuplicateKeyException/CannotAcquireLockException

Favors PessimisticLockingFailureException over plain ConcurrencyFailureException.
Deprecates CannotSerializeTransactionException and DeadlockLoserDataAccessException.

Closes spring-projectsgh-29511
Closes spring-projectsgh-29675

* Avoid NPE on BeanDescriptor access with SimpleBeanInfoFactory

Closes spring-projectsgh-29681

* Polishing

* Polish Javadoc

* Update copyright date

* Add missing Javadoc

See spring-projectsgh-29574

* Revise RepeatableContainersTests

* Support repeatable annotation containers with multiple attributes

Prior to this commit, there was a bug in the implementation of
StandardRepeatableContainers.computeRepeatedAnnotationsMethod() which
has existed since Spring Framework 5.2 (when
StandardRepeatableContainers was introduced). Specifically,
StandardRepeatableContainers ignored any repeatable container
annotation if it declared attributes other than `value()`. However,
Java permits any number of attributes in a repeatable container
annotation.

In addition, the changes made in conjunction with spring-projectsgh-20279 made the bug
in StandardRepeatableContainers apparent when using the
getMergedRepeatableAnnotations() or findMergedRepeatableAnnotations()
method in AnnotatedElementUtils, resulting in regressions for the
behavior of those two methods.

This commit fixes the regressions and bug by altering the logic in
StandardRepeatableContainers.computeRepeatedAnnotationsMethod() so that
it explicitly looks for the `value()` method and ignores any other
methods declared in a repeatable container annotation candidate.

Closes spring-projectsgh-29685

* Remove obsolete AttributeMethods.hasOnlyValueAttribute() method

See spring-projectsgh-29685

* Upgrade to Reactor 2022.0.1

Closes spring-projectsgh-29679

* Support non-standard HTTP methods in FrameworkServlet

This commit ensures that HTTP methods not supported by HttpServlet, for
instance WebDAV methods, are still supported in FrameworkServlet.

Closes spring-projectsgh-29689

* Remove duplicated test code

* Improve Javadoc for RepeatableContainers

* Next development version (v6.0.4-SNAPSHOT)

* Fix manipulating property sources example in Javadoc for ConfigurableEnvironment

The "manipulating property sources" example in the Javadoc for
`ConfigurableEnvironment` states that `MutablePropertySources`
expect a `Map<String,String>`; whereas it expects a
`Map<String,Object>`.

Closes spring-projectsgh-29693

* Polishing

* Polishing

* Improve documentation for literals in SpEL expressions

Closes spring-projectsgh-29700

* Extract ResourceEntityResolver HTTPS schema resolution fallback

This commit extracts the DTD/XSD remote lookup fallback from the
resolveEntity() method into a protected method.

A WARN-level logging statement is added to the extracted fallback in
order to make it clear that remote lookup happened.

Overriding the protected method would allow users to avoid this
fallback entirely if it isn't desirable, without the need to duplicate
the local resolution code.

Closes spring-projectsgh-29697

* Polish contribution

See spring-projectsgh-29697

* Fix typos in reference manual

Closes spring-projectsgh-29694

* Fix link to Jakarta Mail

Closes spring-projectsgh-29694

* Remove ref to JOTM, inactive since 2009

Closes spring-projectsgh-29694

* Remove statement that users could be on Java < 5

Closes spring-projectsgh-29694

* Rework linking to Spring MVC Async support vs WebFlux section

The link was previously named "Compared to WebFlux", which is easy to
mix up with the various links to equivalent sections in the WebFlux
chapter. Here the links point to a small section comparing the Servlet
Async API to the WebFlux stack from a high perspective.

In this commit we eliminate most of these links, except at the
beginning of the Asynchronous section. We also add a small mention of
the Servlet configuration in the comparison paragraphs, since the
Configuring section is the one furthest from the comparison paragraphs
that used to have a link to it.

Closes spring-projectsgh-29694

* Fix subsection style in WebFlux Concurrency Model

The block title style previously used was not rendered in HTML and the
title couldn't be differentiated from the text. Though, it was in the
PDF, as italics.

Introducing delimited blocks in the open (`--`) style did introduce
styling, but the vertical alignment isn't great.

This commit turns these block titles to actual (deep) section titles.
In the final HTML, at this depth there is no numbering but bold styling
is there. The PDF rendering has also been verified to have relevant
style.

Closes spring-projectsgh-29694

* Change plain 'WebFlux' links to 'See equivalent in the Reactive stack'

Closes spring-projectsgh-29694

* Change plain 'WebMVC' links to 'See equivalent in the Servlet stack'

Closes spring-projectsgh-29694

* Cross reference WebTestClient section

* Update Jakarta Mail info in ref docs

Closes spring-projectsgh-29707

* Remove duplicate words in reference manual

Found using regular expression: \b(\w+)\s+\1\b

* Remove duplicated words in Javadoc

* Fix typos in reference manual

* Fix formatting in examples

* Fix typos in anchors

* Polishing

* Update copyright headers

* Apply "instanceof pattern matching" (spring-projects#29710)

* Polishing

* Update Trigger & TriggerContext reference documentation

Closes spring-projectsgh-29702

* Revert incorrect change to ParamAware Javadoc

* Apply "instanceof pattern matching" in spring-aop

* Fix path within mapping when pattern contains ".*"

Prior to this commit, extracting the path within handler mapping would
result in "" if the matching path element would be a Regex and contain
".*". This could cause issues with resource handling if the handler
mapping pattern was similar to `"/folder/file.*.extension"`.

This commit introduces a new `isLiteral()` method in the `PathElement`
abstract class that expresses whether the path element can be compared
as a String for path matching or if it requires a more elaborate
matching process.

Using this method for extracting the path within handler mapping avoids
relying on wildcard count or other properties.

Fixes spring-projectsgh-29712

* Apply update_copyright_headers.sh

Co-authored-by: Juergen Hoeller <hoellerj@vmware.com>
Co-authored-by: Sam Brannen <sam@sambrannen.com>
Co-authored-by: Andriy <ophiuhus@ukr.net>
Co-authored-by: Stephane Nicoll <snicoll@vmware.com>
Co-authored-by: Andy Wilkinson <wilkinsona@vmware.com>
Co-authored-by: Arjen Poutsma <poutsmaa@vmware.com>
Co-authored-by: Spring Builds <spring-builds@users.noreply.github.com>
Co-authored-by: Brian Clozel <bclozel@vmware.com>
Co-authored-by: Sébastien Deleuze <sdeleuze@vmware.com>
Co-authored-by: wizard <925553434@qq.com>
Co-authored-by: divcon <sungjinpark.08@gmail.com>
Co-authored-by: David Costanzo <david_costanzo@yahoo.com>
Co-authored-by: Marten Deinum <mdeinum@gmail.com>
Co-authored-by: André Gasser <andre.gasser@protonmail.com>
Co-authored-by: jiangying <krivergo3@gmail.com>
Co-authored-by: rstoyanchev <rstoyanchev@vmware.com>
Co-authored-by: Yanming Zhou <zhouyanming@gmail.com>
Co-authored-by: Aashay Chapatwala <49100046+Aashay-Chapatwala@users.noreply.github.com>
Co-authored-by: Johnny Lim <izeye@naver.com>
Co-authored-by: Baljit Singh <baljit.singh@verizon.com>
Co-authored-by: Spark61 <ytspark61@gmail.com>
Co-authored-by: CoderYellow <Pf19890604@>
Co-authored-by: Moritz Halbritter <mkammerer@vmware.com>
Co-authored-by: divcon <sungjin.park08@gmail.com>
Co-authored-by: Sam Brannen <sbrannen@vmware.com>
Co-authored-by: ShenFeng312 <49786112+ShenFeng312@users.noreply.github.com>
Co-authored-by: koo.taejin <koo.taejin@toss.im>
Co-authored-by: Carlos Belizón <carlos.belizon.ibanez@gmail.com>
Co-authored-by: Simon Baslé <sbasle@vmware.com>
Co-authored-by: diguage <leejun119@gmail.com>
mdeinum pushed a commit to mdeinum/spring-framework that referenced this issue Jun 29, 2023
Prior to this commit, there was a bug in the implementation of
StandardRepeatableContainers.computeRepeatedAnnotationsMethod() which
has existed since Spring Framework 5.2 (when
StandardRepeatableContainers was introduced). Specifically,
StandardRepeatableContainers ignored any repeatable container
annotation if it declared attributes other than `value()`. However,
Java permits any number of attributes in a repeatable container
annotation.

In addition, the changes made in conjunction with spring-projectsgh-20279 made the bug
in StandardRepeatableContainers apparent when using the
getMergedRepeatableAnnotations() or findMergedRepeatableAnnotations()
method in AnnotatedElementUtils, resulting in regressions for the
behavior of those two methods.

This commit fixes the regressions and bug by altering the logic in
StandardRepeatableContainers.computeRepeatedAnnotationsMethod() so that
it explicitly looks for the `value()` method and ignores any other
methods declared in a repeatable container annotation candidate.

Closes spring-projectsgh-29685
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants