Compare commits

...

932 Commits

Author SHA1 Message Date
Spring Builds 707a24c48b Release v5.3.18 2022-03-31 08:48:28 +00:00
Brian Clozel 002546b3e4 Refine PropertyDescriptor filtering
Restrict property paths under `Class` and properties of types
`ClassLoader` or `ProtectionDomain`.
2022-03-31 10:21:30 +02:00
Stephane Nicoll 1627f57f1f Disable flaky integration tests for now 2022-03-31 09:46:36 +02:00
Sam Brannen 3811cd4c0a Introduce warnings in documentation of SerializationUtils
Closes gh-28246
2022-03-29 15:22:30 +02:00
Sam Brannen d927e37364 Add "Testing ORM entity lifecycle callbacks" note to Testing chapter
Closes gh-28228
2022-03-27 17:46:06 +02:00
Sam Brannen 1d302bf384 Introduce tests for gh-28228 2022-03-27 16:29:45 +02:00
Stephane Nicoll 4b150fd451 Update copyright date in reference manual
Closes gh-28237
2022-03-27 09:59:12 +02:00
Stephane Nicoll 3a6016d356 Merge pull request #28238 from izeye
* pr/28238:
  Update copyright year of EvaluationTests

Closes gh-28238
2022-03-27 09:56:45 +02:00
izeye 135506f672 Update copyright year of EvaluationTests
See gh-28238
2022-03-27 09:55:58 +02:00
Juergen Hoeller cb36ca31f6 Upgrade to ASM master 2022-03-25 18:07:12 +01:00
Juergen Hoeller edd66d96dd Fix accidental use of deprecated setFlushMode method
Closes gh-28234
2022-03-25 18:06:39 +01:00
Juergen Hoeller 35610a535d Expose cancel(mayInterruptIfRunning) variant in ScheduledTask
Closes gh-28233
2022-03-25 18:06:31 +01:00
Yanming Zhou acf2955b96 Ban jetbrains annotations imports
Closes gh-28226
2022-03-24 13:31:36 +01:00
Sam Brannen 8fc744f4f4 Improve Javadoc for BeanExpressionResolver 2022-03-21 16:57:27 +01:00
Sam Brannen 9a5891e6e6 Explicitly close ApplicationContexts and clean up warnings in tests
This commit also ensures that various test methods actually test
something now.
2022-03-20 12:34:56 +01:00
Sam Brannen 64b64d9ba0 Stop referring to features as "Java 5" features
With a Java 8 baseline in place for quite some time now, it no longer
makes sense to refer to features such as annotations as "Java 5
annotations".

This commit also removes old `Tiger*Tests` classes, thereby avoiding
duplicate execution of various tests.
2022-03-18 16:32:30 +01:00
Sam Brannen 1419172fbd Polish Javadoc for JMX support 2022-03-18 15:25:35 +01:00
Spring Builds 420e0ba25f Next development version (v5.3.18-SNAPSHOT) 2022-03-17 10:51:02 +00:00
Sam Brannen 29d98285be Add warning to "enclosing classes" search strategy for MergedAnnotations
This commit adds a warning to the Javadoc for the
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy in
MergedAnnotations with regard to the scope of the search
algorithm.

See gh-28079
2022-03-16 19:23:27 +01:00
Sam Brannen ad708780ed Polish Javadoc for MergedAnnotations 2022-03-16 19:23:27 +01:00
Stephane Nicoll 8789b34ef8 Upgrade to Tomcat 9.0.60 2022-03-16 18:07:38 +01:00
Sam Brannen c9cd53f469 Revert "Deprecate "enclosing classes" search strategy for MergedAnnotations"
This reverts commit 5689395678.

See gh-28079
2022-03-16 15:27:52 +01:00
Sam Brannen c462fe30ed Use Named arguments in parameterized tests 2022-03-16 14:45:47 +01:00
Sam Brannen 8a0c4caff6 Polish Javadoc 2022-03-16 14:33:52 +01:00
Juergen Hoeller 46363c337b Avoid confusing debug log entries with DataClassRowMapper
Closes gh-28179
2022-03-16 11:21:43 +01:00
Juergen Hoeller c1261f2860 Fix accidental exclusion of BeanMapEmitter class
Closes gh-28110
2022-03-16 11:20:49 +01:00
Juergen Hoeller c4c124b16d Upgrade to Log4J 2.17.2, SLF4J 1.7.36, Netty 4.1.75, SmallRye Mutiny 1.4, Hibernate Validator 6.2.3, Mockito 4.4, HtmlUnit 2.59 2022-03-16 11:19:57 +01:00
rstoyanchev ee7f60000e Polishing contribution
Closes gh-28105
2022-03-16 05:56:47 +00:00
azzureman f1fdc11fab Support custom HTTP status in MockClientHttpResponse
See gh-28105
2022-03-16 05:56:23 +00:00
rstoyanchev 21d61316be Unwrap MappingJacksonValue before selecting ObjectMapper
See gh-28045
2022-03-16 05:55:58 +00:00
rstoyanchev cb39b07088 Polishing Jackson encoder tests 2022-03-16 05:55:23 +00:00
danthonywalker 50771237cc Fix ListableBeanFactory#findAnnotationOnBean extension return type
Closes gh-26908
2022-03-15 18:33:35 +01:00
Sam Brannen 9fbf5dc945 Use String#lastIndexOf(int) where possible 2022-03-15 17:03:20 +01:00
Stephane Nicoll a683e9e81b Upgrade to Reactor 2020.0.17
Closes gh-28064
2022-03-15 16:00:48 +01:00
Sam Brannen 6e2e45d18f Apply @SafeVarargs to ManagedMap.ofEntries(...) 2022-03-14 20:24:57 +01:00
Sam Brannen 887389d341 Clarify behavior for generics support in BeanUtils.copyProperties()
Since Spring Framework 5.3, BeanUtils.copyProperties() honors generics
in the source and target property types (see gh-24187); however, this
refinement of the contract was not properly documented prior to this
commit. In addition, the refinement can be a breaking change for users
who were relying on the previous unreliable behavior.

This commit therefore clarifies the behavior for generics support in
BeanUtils.copyProperties() and introduces a table of example matches
and mismatches when generics are involved.

Closes gh-27259
2022-03-12 18:12:23 +01:00
Sam Brannen d9c22e657f Document the effect of @DirtiesContext on test execution events
See gh-27757
2022-03-12 16:05:14 +01:00
Lee, Kyutae 8a510db00d Polish Javadoc for Environment
Closes gh-28170
2022-03-12 14:02:26 +01:00
Stephane Nicoll 9eec6d0834 Start building against Reactor 2020.0.17 snapshots
See gh-28064
2022-03-11 16:18:28 +01:00
Arjen Poutsma a3e23cd5fc Fix unwrapping logic for ResponseEntity<Flux>
This commit makes sure that the response returned by coroutine handler
methods that return ResponseEntity<Flux> is unwrapped correctly.

Closes gh-27809
2022-03-11 11:56:13 +01:00
Sam Brannen af977c0891 Improve documentation for @EnabledIf and @DisabledIf test support
Closes gh-28157
2022-03-10 19:27:41 +01:00
Stephane Nicoll 1bbcd706be Upgrade Ubuntu version in CI image 2022-03-10 10:09:55 +01:00
Sam Brannen 83ac659158 Improve diagnostics in SpEL for large array creation
Attempting to create a large array in a SpEL expression can result in
an OutOfMemoryError. Although the JVM recovers from that, the error
message is not very helpful to the user.

This commit improves the diagnostics in SpEL for large array creation
by throwing a SpelEvaluationException with a meaningful error message
in order to improve diagnostics for the user.

Closes gh-28145
2022-03-09 11:07:45 +01:00
Sam Brannen a2f02dbfc0 Improve documentation for TestContext events
This commit improves the documentation for test execution events,
especially with regard to the fact that, by default, a
BeforeTestClassEvent is not published for the first test class using a
particular ApplicationContext.

This commit also introduces tests that verify the default behavior and
the ability to change the default behavior with a custom
TestExecutionListener that eagerly loads the context.

Closes gh-27757
2022-03-06 17:51:49 +01:00
Sam Brannen 8cbb188455 Fix links to Spring Security in the reference guide
Closes gh-28135
2022-03-05 14:53:52 +01:00
Sam Brannen bc973d7001 Fix broken link to "CORS WebFilter" in ref docs 2022-03-05 14:36:52 +01:00
Sam Brannen fa3130d716 Document that TX rollback rules may result in unintentional matches
Closes gh-28125
2022-03-04 16:39:11 +01:00
Sam Brannen b3e5f86277 Polish rollback rule support 2022-03-03 16:20:13 +01:00
Sam Brannen 340f41af6d Suppress warnings in Gradle build 2022-03-02 17:28:45 +01:00
Sam Brannen 25aa295c2c Rename test class to adhere to conventions 2022-03-02 17:25:37 +01:00
Sam Brannen 67b91b2390 Polish RollbackRuleTests
See gh-28098
2022-03-01 19:10:33 +01:00
Sam Brannen d67034f99b Document semantics for externally managed init/destroy methods
This commit introduces Javadoc to explain the difference between
init/destroy method names when such methods are private, namely that a
private method is registered via its qualified method name; whereas, a
non-private method is registered via its simple name.

See gh-28083
2022-03-01 16:18:46 +01:00
Sam Brannen dcdea986f6 Polish init/destroy lifecycle method tests
See gh-28083
2022-03-01 15:43:25 +01:00
Sam Brannen a524857bd5 Fix init/destroy lifecycle method tests
See gh-28083
2022-03-01 15:23:15 +01:00
Vikey Chen af14eea1ef Introduce tests for gh-28083 2022-03-01 15:22:51 +01:00
Sam Brannen f96872404d Ensure private init/destroy method is invoked only once
Closes gh-28083
2022-03-01 15:03:10 +01:00
Sam Brannen a7d5fbfbea Fix log messages for init/destroy method registration 2022-03-01 15:03:10 +01:00
Sam Brannen 84de100fc6 Polishing 2022-02-28 17:15:43 +01:00
Sam Brannen beab8ab4e7 Test claims regarding SpEL support for T(Character)
See gh-28112
2022-02-28 17:15:43 +01:00
Brian Clozel 6f41180cc5 Align AsyncRestTemplate error logging with RestTemplate
Prior to this commit, `AsyncRestTemplate` would log errors (including
simple 404s) with WARN level. Such errors are quite common and should
not clutter logs.

This commit aligns the logging strategy with RestTemplate, using the
DEBUG level for such cases.

Fixes gh-28049
2022-02-28 16:37:07 +01:00
Arjen Poutsma 7e2106b850 Refactor roll forward in CronField
Before this commit, CronField.Type::rollForward added temporal units
to reach the higher order field. This caused issues with DST, where
the added amount of hours was either too small or too large.

This commit refactors the implementation so that it now adds one to the
higher order field, and reset the current field to the minimum value.

Closes gh-28095
2022-02-24 14:47:02 +01:00
Stephane Nicoll 453c6d41f7 Fix Objenesis version
See gh-28100
2022-02-24 10:54:52 +01:00
Sam Brannen 84b4cebb39 Fix (@)since tag in SpelMessage
See gh-28043
2022-02-19 16:54:16 +01:00
Sam Brannen 5689395678 Deprecate "enclosing classes" search strategy for MergedAnnotations
The TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy for
MergedAnnotations was originally introduced to support @Nested test
classes in JUnit Jupiter (see #23378).

However, while implementing #19930, we determined that the
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy unfortunately
could not be used since it does not allow the user to control when to
recurse up the enclosing class hierarchy. For example, this search
strategy will automatically search on enclosing classes for static
nested classes as well as for inner classes, when the user probably
only wants one such category of "enclosing class" to be searched.
Consequently, TestContextAnnotationUtils was introduced in the Spring
TestContext Framework to address the shortcomings of the
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES search strategy.

Since this search strategy is unlikely to be useful to general users,
the team has decided to deprecate this search strategy in Spring
Framework 5.3.x and remove it in 6.0.

Closes gh-28079
2022-02-19 16:51:00 +01:00
Sam Brannen 071c2988d5 Suppress deprecation warnings in tests in build 2022-02-18 16:18:13 +01:00
Sam Brannen 94af2ca06b Recover from error during SpEL MIXED mode compilation
Prior to this commit, SpEL was able to recover from an error that
occurred while running a CompiledExpression; however, SpEL was not able
to recover from an error that occurred while compiling the expression
(such as a java.lang.VerifyError). The latter can occur when multiple
threads concurrently change types involved in the expression, such as
the concrete type of a custom variable registered via
EvaluationContext.setVariable(...), which can result in SpEL generating
invalid bytecode.

This commit addresses this issue by catching exceptions thrown while
compiling an expression and updating the `failedAttempts` and
`interpretedCount` counters accordingly. If an exception is caught
while operating in SpelCompilerMode.IMMEDIATE mode, the exception will
be propagated via a SpelEvaluationException with a new
SpelMessage.EXCEPTION_COMPILING_EXPRESSION error category.

Closes gh-28043
2022-02-18 15:31:59 +01:00
Arjen Poutsma ff20a06876 Added .sdkmanrc file
This commit adds a .sdkmanrc file, so that we can automatically switch
to JDK 8 when building the 5.3. branch.
2022-02-17 11:51:14 +01:00
Stephane Nicoll 2ffefbb211 Downgrade to concourse-release-scripts 0.3.2
This commit reverts partially "0ab054c7b943d65bb9034d1d7987f556e9d54d05"
as 0.3.3 is breaking promition.
2022-02-17 09:44:22 +01:00
Spring Builds 4571626839 Next development version (v5.3.17-SNAPSHOT) 2022-02-17 07:45:38 +00:00
Juergen Hoeller f8a59c267f Polishing 2022-02-16 20:04:51 +01:00
Juergen Hoeller 1166577d2c Upgrade to Netty 4.1.74, Jetty 9.4.45, Undertow 2.2.16, Hibernate Validator 6.2.2, Apache Johnzon 1.2.16, EclipseLink 2.7.10 2022-02-16 20:04:27 +01:00
Phillip Webb 36dc4e4c5f Add mavenCentral() to pluginManagement repositories
Update the pluginManagement repositories used by Grade to include
`mavenCentral()` since `gradlePluginPortal()` has been suffering
from timeouts recently.
2022-02-16 14:35:50 +01:00
Sam Brannen 3ac60147f3 Improve documentation for uri(URI) method in WebTestClient
Prior to this commit, it was not clear that a configured base URI would
not be applied when invoking uri(URI).

This commit adds a note to the Javadoc to clarify that behavior.

Closes gh-28058
2022-02-16 12:11:33 +01:00
Sam Brannen e3ceb9b23d Polish @Target declarations for stereotype annotations 2022-02-16 12:01:14 +01:00
Arjen Poutsma 5ab966fbde Polish contribution
See gh-28038
2022-02-16 11:16:38 +01:00
vikey 7276752e7c Fix CronExpression issue with DST
This commit fixes an issue with CronExpression fails to calculate next
execution on the day of daylight saving time.

Closes gh-28038
2022-02-16 11:16:38 +01:00
Sam Brannen 685a195ba1 Deprecate SocketUtils
SocketUtils was introduced in Spring Framework 4.0, primarily to assist
in writing integration tests which start an external server on an
available random port. However, these utilities make no guarantee about
the subsequent availability of a given port and are therefore
unreliable. Instead of using SocketUtils to find an available local
port for a server, it is recommended that users rely on a server's
ability to start on a random port that it selects or is assigned by the
operating system. To interact with that server, the user should query
the server for the port it is currently using.

SocketUtils is now deprecated in 5.3.16 and will be removed in 6.0.

Closes gh-28052
2022-02-15 14:28:58 +01:00
Sam Brannen 3188c0f7db Ensure fix for gh-28012 is actually tested
In 3ec612aaf8, I accidentally removed tests that verified support for
non-synthesizable merged annotations for recursive annotations in
Kotlin.

This commit reinstates those non-synthesizable tests while retaining
the synthesizable tests.
2022-02-15 13:47:03 +01:00
Stephane Nicoll 3ea540adbc Upgrade to Reactor 2020.0.16
Closes gh-28039
2022-02-15 13:37:08 +01:00
rstoyanchev ec03e8830e Remove path variables from pathWithinMapping
Closes gh-27913
2022-02-14 20:51:02 +00:00
rstoyanchev 11cb938232 Polishing contribution
Closes gh-28000
2022-02-14 20:51:02 +00:00
Ivan Zbykovskyi f004bb1b64 Add formatting for SockJS GoAway frame
Prevents infinite loop for xhr-polling and xhr-streaming transports.

See gh-28000
2022-02-14 20:51:02 +00:00
Brian Clozel 88f73bffa0 Make assertion message lazy in ServletRequestPathUtils
Closes gh-27946
2022-02-14 16:21:41 +01:00
Brian Clozel 0ab054c7b9 Upgrade concourse-release-scripts in CI
This commit also reverts the change of resource type for the publication
of the CI image and fixes a bug in the CI image setup with available
JDKs.
2022-02-14 10:55:07 +01:00
Sébastien Deleuze 8eb618b480 Make Kotlin functions accessible in CoroutinesUtils
In order to allow using private classes like in Java
for example.

Closes gh-23840
2022-02-14 10:43:31 +01:00
Brian Clozel 2f78abd56e Upgrade CI pipeline
This commit upgrades the CI pipeline with the following:

* replace JDK16 with JDK17 as build variant
* upgrade all JDK versions
* replace docker-image with registry-image resource for CI image
2022-02-14 10:29:45 +01:00
Sam Brannen 3ec612aaf8 Support recursive annotations in merged annotations
Although Java does not allow the definition of recursive annotations,
Kotlin does, and prior to this commit an attempt to synthesize a
merged annotation using the MergedAnnotation API resulted in a
StackOverflowError if there was a recursive cycle in the annotation
definitions.

This commit addresses this issue by tracking which annotations have
already been visited and short circuits the recursive algorithm if a
cycle is detected.

Closes gh-28012
2022-02-12 23:42:57 +01:00
Sam Brannen 4eaee1e738 Short circuit if-conditions in AttributeMethods 2022-02-11 20:41:23 +01:00
Sébastien Deleuze eca755ec88 Upgrade to Dokka 1.6.10
Closes gh-28040
2022-02-11 17:42:06 +01:00
Stephane Nicoll 4201479546 Start building against Reactor 2020.0.16 snapshots
See gh-28039
2022-02-11 15:41:49 +01:00
Sam Brannen b60340b102 Simplify tests for synthesized annotation toString()
See gh-28015
2022-02-11 15:33:14 +01:00
Sam Brannen 2fd39839f8 Improve toString() for synthesized annotations
Although the initial report in gh-28015 only covered inconsistencies
for arrays and strings in the toString() implementations for
annotations between the JDK (after Java 9) and Spring, it has since
come to our attention that there was further room for improvement.

This commit therefore addresses the following in toString() output for
synthesized annotations.

- characters are now wrapped in single quotes.

- bytes are now properly formatted as "(byte) 0x##".

- long, float, and double values are now appended with "L", "f", and
  "d", respectively. The use of lowercase for "f" and "d" is solely to
  align with the choice made by the JDK team.

However, this commit does not address the following issues which we may
choose to address at a later point in time.

- non-ASCII, non-visible, and non-printable characters within a
  character or String literal are not escaped.

- formatting for float and double values does not take into account
  whether a value is not a number (NaN) or infinite.

Closes gh-28015
2022-02-10 17:14:37 +01:00
Sam Brannen ce87285be5 Use canonical names for types in synthesized annotation toString
My proposal for the same change in the JDK is currently targeted for
JDK 19.

- https://bugs.openjdk.java.net/browse/JDK-8281462
- https://bugs.openjdk.java.net/browse/JDK-8281568
- https://github.com/openjdk/jdk/pull/7418

See gh-28015
2022-02-10 16:59:00 +01:00
Sam Brannen 97582fd0a1 Update Eclipse template to @since 5.3.16 2022-02-10 13:43:02 +01:00
Stephane Nicoll d2c7dfb79e Add convenience factory method for Managed[List|Set|Map]
Closes gh-28026
2022-02-10 12:37:19 +01:00
Sam Brannen 7139a877f4 Ensure toString() for synthesized annotations is source code compatible
Since the introduction of synthesized annotation support in Spring
Framework 4.2 (a.k.a., merged annotations), the toString()
implementation attempted to align with the formatting used by the JDK
itself. However, Class annotation attributes were formatted using
Class#getName in Spring; whereas, the JDK used Class#toString up until
JDK 9.

In addition, JDK 9 introduced new formatting for toString() for
annotations, apparently intended to align with the syntax used in the
source code declaration of the annotation. However, JDK 9+ formats enum
annotation attributes using Enum#toString instead of Enum#name, which
can lead to issues if toString() is overridden in an enum.

This commit updates the formatting used for synthesized annotations by
ensuring that toString() generates a string that is compatible with the
syntax of the originating source code, going beyond the changes made in
JDK 9 by using Enum#name instead of Enum#toString.

Closes gh-28015
2022-02-08 14:10:36 +01:00
Sam Brannen 669b05dc1d Allow AutowiredAnnotationBeanPostProcessor to compile on JDK 11 2022-02-08 14:06:27 +01:00
Sam Brannen 038b88e2a1 Polishing 2022-02-05 20:23:45 +01:00
Sam Brannen eb84c84373 Polish contribution
See gh-27993
2022-02-05 20:15:30 +01:00
Gleidson Leopoldo 920be8e1b2 Add support for strict JSON comparison in WebTestClient
Prior to this commit, WebTestClient only supported "lenient" comparison
of the expected JSON body.

This commit introduces an overloaded variant of `json()` in the
BodyContentSpec that accepts an additional boolean flag to specify
whether a "strict" comparison should be performed.

This new feature is analogous to the existing support in MockMvc.

Closes gh-27993
2022-02-05 20:15:30 +01:00
Sam Brannen a13ad3e969 Polishing 2022-02-05 20:15:30 +01:00
Stephane Nicoll 874432b38a Merge pull request #28010 from izeye
* pr/28010:
  Fix Javadoc since for AopProxyUtils.isLambda()

Closes gh-28010
2022-02-05 13:59:33 +01:00
izeye 4ab03fede8 Fix Javadoc since for AopProxyUtils.isLambda()
See gh-28010
2022-02-05 13:59:01 +01:00
Juergen Hoeller 5bbdd36e19 Upgrade to Checkstyle 9.3, HtmlUnit 2.58, Apache HttpClient 5.1.3 2022-02-04 23:51:23 +01:00
Juergen Hoeller a22feac803 Update license header for https (nohttp rule)
See gh-27802
2022-02-04 23:51:05 +01:00
Juergen Hoeller bc9cd9a687 Find interface method even for late-bound interface declaration in subclass
Closes gh-27995
2022-02-04 23:21:27 +01:00
Juergen Hoeller a71a45e719 Deprecate AsyncTaskExecutor.execute(Runnable task, long startTimeout)
Closes gh-27959
2022-02-04 23:21:00 +01:00
Juergen Hoeller 132d8c7f45 Support for CGLIB BeanMap utility on JDK 17
Closes gh-27802
2022-02-04 23:19:06 +01:00
Sam Brannen 5d7a632965 Ensure Spring AOP generates JDK dynamic proxies for lambdas
Prior to this commit, if AOP proxy generation was configured with
proxyTargetClass=true (which is the default behavior in recent versions
of Spring Boot), beans implemented as lambda expressions or method
references could not be proxied with CGLIB on Java 16 or higher without
specifying `--add-opens java.base/java.lang=ALL-UNNAMED`.

This commit addresses this shortcoming by ensuring that beans
implemented as lambda expressions or method references are always
proxied using a JDK dynamic proxy even if proxyTargetClass=true.

Closes gh-27971
2022-02-04 19:59:35 +01:00
Stephane Nicoll 6bc7d41734 Merge pull request #28004 from An1s9n
* pr/28004:
  Polish reference to ManagedBean annotation

Closes gh-28004
2022-02-04 09:24:30 +01:00
Pavel Anisimov 05d3e820f9 Polish reference to ManagedBean annotation
See gh-28004
2022-02-04 09:23:32 +01:00
Sam Brannen f8a5a8d7be Use modern language features in tests 2022-02-03 14:50:10 +01:00
Stephane Nicoll 82a2544918 Upgrade to spring javaformat 0.0.31 2022-02-03 08:49:16 +01:00
Stephane Nicoll e702c22da4 Upgrade Ubuntu version in CI image 2022-02-03 08:48:52 +01:00
rstoyanchev c4e362500b Polishing tests 2022-02-02 17:09:04 +00:00
rstoyanchev 8d5a6520ce Ensure all converters don't close InputStream
Closes gh-27969
2022-02-02 15:55:13 +00:00
rstoyanchev 4effca35b5 Ignore Content-Type that is invalid (not concrete)
Closes gh-27957
2022-02-02 15:55:07 +00:00
Arjen Poutsma 8f9a1cdc0c Consider current date in "1W" cron expressions
Prior to this commit, the QuartzCronField::weekdayNearestTo would elapse
until the next month before checking if the current day matched.

After this commit, the current day is checked before we elapse until
the next month.

Closes gh-27966
2022-02-01 13:51:40 +01:00
Stephane Nicoll 136bd2002e Upgrade to spring javaformat 0.0.30 2022-01-31 09:34:12 +01:00
Sam Brannen a749a6bf54 Stop applying Groovy plugin for the root Gradle project
The root project does not rely on the Groovy plugin.

See gh-27945
2022-01-30 15:49:59 +01:00
Sam Brannen 7072aab53b Improve log message when searching for default executor for async processing
Closes gh-27983
2022-01-30 15:44:40 +01:00
Sam Brannen dbeae27d3c Reduce build time by reducing shutdown wait period for Jetty tests 2022-01-29 12:41:39 +01:00
Sam Brannen fb312d0ed5 Improve Javadoc for DatabasePopulator
See gh-27008
2022-01-28 16:40:35 +01:00
Sam Brannen 0e670b1c15 Polish contribution
See gh-27984
2022-01-28 16:15:21 +01:00
wkwkhautbois fadfcf4e43 Fix ServletUriComponentsBuilder examples in ref docs
Closes gh-27984
2022-01-28 16:10:54 +01:00
Arjen Poutsma caa13690e8 Support multiple boundary buffers in MultipartParser
In a small minority of cases, the multipart boundary can spread across
three incoming buffers.

Prior to this commit, MultipartParser.BodyState only supported two
buffers. If the boundary is spread across three buffers, the first
buffer of the three is sent as a whole, even though it contains the
first bytes of the boundary.

This commit fixes this bug, by enqueuing all prior buffers in a queue,
and emitting the ones that cannot contain boundary bytes.

Closes gh-27939
2022-01-28 13:42:24 +01:00
Sam Brannen 6647023151 Document how to register annotated classes in a GenericWebApplicationContext
Closes gh-27778
2022-01-27 16:08:16 +01:00
Sam Brannen e32f94bf8c Polish GenericWebApplicationContext and AnnotationConfigWebApplicationContext 2022-01-27 16:08:07 +01:00
Stephane Nicoll bd6d697395 Upgrade Java versions in CI image 2022-01-27 09:52:25 +01:00
Sam Brannen 7f65e17ff2 Improve documentation for implementing AspectJ around advice
Closes gh-27980
2022-01-26 17:32:48 +01:00
Sam Brannen 9095f1d584 Polish AspectJ documentation 2022-01-26 17:32:48 +01:00
Stephane Nicoll 4f16d5b5b2 Merge pull request #27826 from Drezir
* pr/27826:
  Polish "Add CacheErrorHandler implementation that logs exceptions"
  Add CacheErrorHandler implementation that logs exceptions

Closes gh-27826
2022-01-26 14:12:13 +01:00
Stephane Nicoll 6a6c7df824 Polish "Add CacheErrorHandler implementation that logs exceptions"
See gh-27826
2022-01-26 14:10:49 +01:00
Adam Ostrožlík 5c9fbcc23c Add CacheErrorHandler implementation that logs exceptions
See gh-27826
2022-01-26 14:10:49 +01:00
Sam Brannen f4f5cee76c Polish AOP namespace tests 2022-01-26 12:29:30 +01:00
Sam Brannen bf1cf549b1 Delete unused XML config in AOP namespace tests
See gh-22246
2022-01-26 12:15:10 +01:00
Juergen Hoeller 1272cd557d Upgrade to SmallRye Mutiny 1.3.1, Aalto 1.3.1, Woodstox 6.2.8 2022-01-26 00:02:12 +01:00
Juergen Hoeller 993b6d1351 Upgrade to Tomcat 9.0.58, Protobuf 3.19.3, Rome 1.18, H2 2.1.210, SLF4J 1.7.35, Mockito 4.3.1, HtmlUnit 2.57, XMLUnit 2.9, Checkstyle 9.2.1 2022-01-25 23:51:22 +01:00
Juergen Hoeller 0a92d84778 Check open status before close call (aligned with EntityManagerFactoryUtils)
Closes gh-27972
2022-01-25 23:50:45 +01:00
Sam Brannen 652c13a6ea Enable ReflectionUtilsTests.findMethodWithVarArgs()
See gh-13286
2022-01-25 09:58:57 +01:00
Sam Brannen cb3fa89946 Polish ReflectionUtilsTests 2022-01-25 09:57:36 +01:00
Sam Brannen d01dca14e9 Filter methods in Object in ReflectionUtils.USER_DECLARED_METHODS
Prior to this commit, the USER_DECLARED_METHODS MethodFilter in
ReflectionUtils did not actually filter methods declared in
java.lang.Object as stated in its Javadoc.

Consequently, if ReflectionUtils.doWithMethods was invoked with
USER_DECLARED_METHODS and Object.class as the class to introspect, all
non-bridge non-synthetic methods declared in java.lang.Object were
passed to the supplied MethodCallback, which breaks the contract of
USER_DECLARED_METHODS.

In addition, if USER_DECLARED_METHODS was composed with a custom
MethodFilter using `USER_DECLARED_METHODS.and(<custom MethodFilter>)`,
that composed method filter allowed all non-bridge non-synthetic
methods declared in java.lang.Object to be passed to the supplied
MethodCallback, which also breaks the contract of
USER_DECLARED_METHODS. This behavior resulted in regressions in code
that had previously used USER_DECLARED_METHODS by itself and then began
using USER_DECLARED_METHODS in a composed filter. For example, since
commit c419ea7ba7 ReflectiveAspectJAdvisorFactory has incorrectly
processed methods in java.lang.Object as candidates for advice methods.

This commit fixes this bug and associated regressions by ensuring that
USER_DECLARED_METHODS actually filters methods declared in
java.lang.Object. In addition, ReflectionUtils.doWithMethods now aborts
its search algorithm early if invoked with the USER_DECLARED_METHODS
filter and Object.class as the class to introspect.

Closes gh-27970
2022-01-24 20:09:22 +01:00
Sam Brannen d698446f7c Polish ReflectionUtils[Tests] 2022-01-24 19:46:40 +01:00
Stephane Nicoll 5ef023afd2 Merge pull request #27967 from arey
* pr/27967:
  Fix CaffeineCacheManager configuration example in reference doc

Closes gh-27967
2022-01-22 10:42:08 +01:00
Antoine Rey 316764cad0 Fix CaffeineCacheManager configuration example in reference doc
See gh-27967
2022-01-22 10:40:47 +01:00
Sam Brannen a681d6af22 Fix Javadoc links to JSR 305 annotations where feasible
Prior to this commit, we only (indirectly) configured external Javadoc
links for types in the javax.annotation package for JSR 250, since
those types are part of Java 8 SE. However, an external Javadoc link
for types from JSR 305 was not configured.

To address this issue, this commit now configures an external Javadoc
link for JSR 305 types. However, the external Javadoc link for JSR 305
must be configured last to ensure that types from JSR 250 (such as
@PostConstruct) are still supported. This is due to the fact that JSR
250 and JSR 305 both define types in javax.annotation, which results in
a split package, and the javadoc tool does not support split packages
across multiple external Javadoc sites. Instead, the Javadoc tool
iterates over all external links, and the first external site that
claims to support a given package (via the package-list file) wins.

This means:

- Javadoc for JSR 250 annotations is fully supported.
- Javadoc for JSR 305 annotations in the javax.annotation package will
  continue to result in a 404 (page not found) error.
- Javadoc for JSR 305 annotations in the javax.annotation.meta package
  is fully supported.

For Spring Framework 6.0, the Javadoc for JSR 250 types in
jakarta.annotation package is served from the JBoss Application Server
Javadoc site instead of from Oracle's Java SE documentation site, since
JSR 250 annotations are no longer included in Java SE.

Closes gh-27904
2022-01-21 16:07:55 +01:00
shirohoo 7211912057 Polish tests in spring-web
This PR polishes trivial things in tests in spring-web.

Closes gh-27958
2022-01-20 15:44:24 +01:00
Juergen Hoeller 148eac0200 Upgrade to SLF4J 1.7.33, Netty 4.1.73, R2DBC Arabba-SR12 2022-01-19 13:54:22 +01:00
Juergen Hoeller 86be03945b Polishing 2022-01-19 13:54:03 +01:00
Juergen Hoeller 537aced28b Avoid message listener recovery in case of persistence exceptions on commit
Closes gh-1807
2022-01-19 13:53:38 +01:00
Sam Brannen 5c76ff5ef6 Ensure unresolvable placeholders can be ignored with @Value
Prior to this commit, if a PropertySourcesPlaceholderConfigurer bean
was configured with its ignoreUnresolvablePlaceholders flag set to
true, unresolvable placeholders in an @Value annotation were not
ignored, resulting in a BeanCreationException for the bean using @Value.

For example, given a property declared as `my.app.var = ${var}` without
a corresponding `var` property declared, an attempt to resolve
`@Value("${my.app.var}")` resulted in the following exception.

java.lang.IllegalArgumentException: Could not resolve placeholder 'var' in value "${var}"

This commit fixes this by modifying
PropertySourcesPlaceholderConfigurer's postProcessBeanFactory(...)
method so that a local PropertyResolver is created if the
ignoreUnresolvablePlaceholders flag is set to true. The local
PropertyResolver then enforces that flag, since the Environment in the
ApplicationContext is most likely not configured with
ignoreUnresolvablePlaceholders set to true.

Closes gh-27947
2022-01-18 16:00:55 +01:00
Sam Brannen d02d5adb54 Download gradle-enterprise-conventions plugin from "release" repo
See gh-27942
2022-01-17 18:03:27 +01:00
Jerome Prinet 71f7469578 Upgrade to Gradle Enterprise 3.8.1
Closes gh-27942
2022-01-17 17:59:38 +01:00
Sam Brannen 420c4f3df3 Explicitly test BeanPropertyRowMapper.underscoreName(String)
See gh-27929
2022-01-17 16:54:03 +01:00
Sam Brannen 420ff46b2a Polishing 2022-01-17 16:54:03 +01:00
Marten Deinum 261bc2ad6a Fix regression in BeanPropertyRowMapper.underscoreName(String)
Commit 6316a35 introduced a regression for property names starting with
multiple uppercase letters (such as setEMail(...)).

This commit fixes that regression and includes an additional test to
cover this case.

See gh-27929
Closes gh-27941
2022-01-17 16:53:36 +01:00
Sam Brannen c92b9bc7fe Properly abort transferTo test for Undertow
Instead of simply returning prematurely and allowing the tests to be
marked as SUCCESS, this commit uses a failed assumption to abort the
the trasferTo tests for Undertow, resulting in the parameterized test
invocation properly being marked as ABORTED.

See gh-25310
2022-01-13 17:55:37 +01:00
Sam Brannen 4b1b25496b Improve comment parsing in DTD/XSD detection algorithm
Prior to this commit, XmlValidationModeDetector did not properly parse
all categories of comments (described below). When such categories of
comments were encountered XmlValidationModeDetector may have
incorrectly detected that an XML file used a DTD when it used an XSD,
or vice versa.

This commit revises the parsing algorithm in XmlValidationModeDetector
so that multi-line comments and multiple comments on a single line are
properly recognized.

Specifically, with this commit the following categories of comments are
now handled properly.

- Multiple comments on a single line
- Multi-line comment: beginning on one line and then ending on another
  line with an additional comment following on that same line.
- Multi-line comment: beginning at the end of XML content on one line
  and then spanning multiple lines.

Closes gh-27915
2022-01-13 16:11:15 +01:00
Sam Brannen 9e8b6feb54 Polishing 2022-01-13 14:56:14 +01:00
Spring Builds 3631d2f36e Next development version (v5.3.16-SNAPSHOT) 2022-01-13 11:22:39 +00:00
Stephane Nicoll cfefcee788 Polishing
See gh-27926
2022-01-13 08:28:54 +01:00
Sam Brannen 5fb58e51e5 Infer UTF-8 encoding for JSON response with MockMvc's andDo(print(...))
Prior to this commit, the PrintingResultHandler in MockMvc -- typically
invoked via .andDo(print()) -- printed an `application/json` response
body using the default encoding (ISO-8859-1), which resulted in UTF-8
characters being garbled.

Since an `application/json` response is implicitly encoded using UTF-8,
the PrintingResultHandler now infers UTF-8 encoding for such response
bodies.

Closes gh-27926
2022-01-12 17:07:45 +01:00
Juergen Hoeller 67c4b4182f Upgrade to Hibernate ORM 5.4.33, Hibernate Validator 6.2.1, Mockito 4.2, AssertJ 3.22, HtmlUnit 2.56, XMLUnit 2.8.4 2022-01-12 16:36:18 +01:00
Juergen Hoeller 6b3052200a Skip "data:" lines without content
Closes gh-27923
2022-01-12 16:35:42 +01:00
Juergen Hoeller cf5b86369d Explicitly close InputStream after resolution in RequestPartMethodArgumentResolver
Closes gh-27773
2022-01-12 16:31:39 +01:00
rstoyanchev 7067461d71 Fix exception in Jetty10RequestUpgradeStrategy
Closes gh-27899
2022-01-12 15:04:05 +00:00
rstoyanchev 34cb5df859 Consistent id for ReactorServerHttpRequest
Closes gh-27885
2022-01-12 08:55:32 +00:00
rstoyanchev 01231fe923 Minor refactoring in STOMP documentation
Closes gh-27906
2022-01-12 08:55:32 +00:00
rstoyanchev 7665424ea8 Polishing contribution
Closes gh-27888
2022-01-12 08:55:32 +00:00
Max Demydenko f63a106c85 clear() method also clears argument resolver cache
See gh-27888
2022-01-12 08:55:32 +00:00
rstoyanchev caaf48d4ec Add missing overrides to ServerHttpResponseDecorator
Closes gh-27889
2022-01-12 08:55:32 +00:00
Stephane Nicoll e52fc2176d Upgrade to Reactor 2020.0.15
Closes gh-27897
2022-01-12 09:39:09 +01:00
rstoyanchev e8e7fbba94 Polishing contribution and fix failing test
The failing test is for Apache HttpComponents where we cannot apply the
Content-Length together with other headers, and must pass it instead
explicitly to ReactiveEntityProducer when writing at which point it gets
set in the native headers.

Closes gh-27768
2022-01-11 17:07:26 +00:00
sokomishalov bd1f34e174 Apply adapters to client request headers after committed
See gh-27768
2022-01-11 15:30:03 +00:00
Arjen Poutsma a490723f02 NettyHeadersAdapter::putAll does not overwrite headers
Similar to 4078b73cec, but for the
client-side NettyHeadersAdapter::putAll.

See gh-27887
2022-01-11 13:33:15 +01:00
Sam Brannen df263d01b9 Use idiomatic AssertJ assertions for true, false, and null 2022-01-10 14:15:55 +01:00
kuanghc1 2a80b64d40 Add tests for StringUtils matchesCharacter() method
Closes gh-27909
2022-01-10 13:27:15 +01:00
kuanghc1 e24043ab90 Simplify HashMap declaration in test fixture 2022-01-10 13:27:15 +01:00
Arjen Poutsma 4078b73cec NettyHeadersAdapter::putAll does not overwrite headers
NettyHeadersAdapter::putAll uses HttpHeaders::add, which does not
overwrite existing headers. putAll should use HttpHeaders::set instead,
just like NettyHeadersAdapter::put does.

Closes gh-27887
2022-01-10 10:54:04 +01:00
Stephane Nicoll dca155e438 Reintroduce references to JBoss AS Javadoc
Closes gh-27860
2022-01-10 10:12:05 +01:00
waahhh edabde8a11 Fix syntax in WebFlux Validation example
Closes gh-27907
2022-01-09 17:26:11 +01:00
Sam Brannen 8087eb69bf Improve error message in ResolvableType.forClassWithGenerics()
Prior to this commit, the error message generated for a mismatched
number of generics did not include the information about the class in
question.

This commit improves the error message by providing more context,
specifically the result of invoking toGenericString() on the class.

For example, instead of throwing an IllegalArgumentException with the
error message "Mismatched number of generics specified", the error
message would now be "Mismatched number of generics specified for
public abstract interface java.util.Map<K,V>".

Closes gh-27847
2022-01-09 17:05:07 +01:00
Sam Brannen e41d865193 Polishing 2022-01-09 17:05:07 +01:00
Sam Brannen d68bb4eecd Simplify StreamConverterTests 2022-01-09 16:15:32 +01:00
Sam Brannen 730ad4436f Polish contribution 2022-01-09 16:15:32 +01:00
kth496 23ab9ca8ca Refactor tests to use lambda expressions & method references
Closes gh-27386
2022-01-09 15:37:54 +01:00
Sam Brannen 51d263bd06 Simplify H2SequenceMaxValueIncrementerTests
@hpoettker made me aware of the ModeEnum in H2 that allows the
parameterized test to be simplified, which was the primary impetus for
this commit.

See gh-27870
2022-01-08 17:24:19 +01:00
Sam Brannen 518dc6df65 Polishing 2022-01-08 17:06:25 +01:00
Sam Brannen 59c6b7e445 Fix SpEL withTypedRootObject() test 2022-01-08 17:06:25 +01:00
justlikeliuen 3e75ec73ab Fix SpEL withRootObject test
The test case is intended to be for the method 'withRootObject()', but
actually it's copied from the previous test method that does not use
'withRootObject()'.

This commit fixes the propertyReadWriteWithRootObject() test method in
PropertyAccessTests.

Closes gh-27905
2022-01-08 17:06:25 +01:00
Sam Brannen 709a41fd43 Fix broken links to WebSocket support in Spring Security & Spring Session 2022-01-08 16:35:58 +01:00
Sam Brannen 90072d06fb Test H2SequenceMaxValueIncrementer against all H2 2.0.x compatibility modes
See gh-27870
2022-01-07 16:17:11 +01:00
Sam Brannen 54bdab4553 Partially upgrade to H2 database 2.0.206
Commit ed4e2289cd introduced support for H2 2.0.x but did not upgrade
the H2 dependency.

This commit upgrades the H2 dependency to version 2.0.206 but also
adds an explicit test dependency on version 1.4.200 in spring-r2dbc,
since r2dbc-h2 does not yet support H2 2.0.x.

Once https://github.com/r2dbc/r2dbc-h2/pull/204 has been included in a
released version of r2dbc-h2 we will be able to upgrade spring-r2dbc's
test dependency on the H2 database to 2.0.x as well.

See gh-27870
See gh-27902
2022-01-07 15:50:44 +01:00
Sam Brannen 75e1811470 Ensure H2SequenceMaxValueIncrementer works with all H2 compatibility modes
See gh-27870
2022-01-07 14:29:17 +01:00
Sam Brannen 18781e58ac Polish contribution
See gh-27870
2022-01-07 10:09:45 +01:00
Henning Poettker ed4e2289cd Support H2 1.4 & 2.0 in H2SequenceMaxValueIncrementer
Prior to this commit, H2SequenceMaxValueIncrementer only supported H2
database 1.4.

This commit updates H2SequenceMaxValueIncrementer's getSequenceQuery()
method so that the syntax used supports version 1.4 and 2.0 of the H2
database.

This commit also updates several test schemas so that they work with H2
1.4 and 2.0 as well as HSQL.

Closes gh-27870
2022-01-07 10:09:27 +01:00
Stephane Nicoll ccf95413ed Start building against Reactor 2020.0.15 snapshots
See gh-27897
2022-01-06 16:48:15 +01:00
Johannes Wengert fdd6e50721 Correct not compiling example code in Data Access docs
The EntityManager interface does not implement AutoCloseable until
JPA 3.1.

This commit therefore partially reverts 189e1afc6e so that the
example code compiles with the supported JPA version.

See gh-22269
Closes gh-27886
2022-01-04 16:50:23 +01:00
Sam Brannen c04fa858fc Partially revert e1200f34e7
Syntax for this try-with-resources use case only permitted on Java 9+.
2022-01-04 16:20:55 +01:00
Sam Brannen c3ce4f0f90 Polish contribution
See gh-27823
2022-01-04 15:12:29 +01:00
Marten Deinum e1200f34e7 Use try-with-resources for AutoClosables where feasible
Where unfeasible, this commit adds inline comments to explain why
try-with-resources must not be used in certain scenarios. The purpose
of the comments is to avoid accidental conversion to try-with-resources
at a later date.

Closes gh-27823
2022-01-04 15:12:29 +01:00
Stephane Nicoll 999376f9f9 Temporarily remove references to JBoss AS Javadoc
See gh-27860
2022-01-04 15:00:44 +01:00
Sam Brannen c942d789c3 Ignore unsupported @SuppressWarnings tokens in Eclipse IDE
This helps to reduce noise in the "Problems" view by not displaying
warnings resulting from @SuppressWarnings tokens that Eclipse does not
understand -- for example, tokens supported by IntelliJ IDEA or other
tools.
2022-01-04 14:52:23 +01:00
Sam Brannen 03668f9c10 Replace remaining use of StringBuffer with StringBuilder
Although this commit only applies to test classes, it serves to reduce
the noise when searching for undesirable usage of StringBuffer in
production code.
2022-01-04 14:06:13 +01:00
Sam Brannen 3e14cdbc69 Polish tests 2022-01-04 14:02:32 +01:00
Sam Brannen f04e9a8366 Deprecate getBeanFactory() method in AbstractBeanDefinitionReader
The getBeanFactory() method has been obsolete for more than 13 years
since it was superseded by the getRegistry() method in the
BeanDefinitionReader interface.

Closes gh-27875
2022-01-04 12:45:11 +01:00
Sam Brannen c1606c5a5e Polishing 2022-01-04 12:39:28 +01:00
Sam Brannen 95fac2589f Upgrade to Log4j2 2.17.1 2022-01-03 11:50:37 +01:00
Spring Builds 41c8bb4fe1 Next development version (v5.3.15-SNAPSHOT) 2021-12-16 08:46:23 +00:00
Juergen Hoeller 31a4c274b7 Upgrade to SnakeYAML 1.30, MockK 1.12.1, Jetty Reactive HttpClient 1.1.10 2021-12-15 21:51:05 +01:00
Juergen Hoeller d665977787 Polishing 2021-12-15 21:50:30 +01:00
Juergen Hoeller 0b6a54dcc7 Upgrade to R2DBC Arabba-SR11, Kotlin 1.5.32, Jackson 2.12.6 2021-12-15 17:58:59 +01:00
Juergen Hoeller 1885ab3e07 Polishing 2021-12-15 17:58:28 +01:00
Stephane Nicoll de10bb69cb Stop resolving AsyncConfigurer instances eagerly
Closes gh-27808
2021-12-15 10:53:09 +01:00
Stephane Nicoll c7642422c3 Stop resolving CachingConfigurer instances eagerly
Closes gh-27751
2021-12-15 10:52:09 +01:00
Stephane Nicoll 4c2e0ee5ff Upgrade to Log4j2 2.16.0 2021-12-15 09:49:57 +01:00
Juergen Hoeller 79804d92c2 Upgrade to Protobuf 3.19.1, Gson 2.8.9, Woodstox 6.2.7, Apache Johnzon 1.2.15, Caffeine 2.9.3 2021-12-14 18:36:05 +01:00
Juergen Hoeller f191cf4eb3 Revised comment on explicit LocalDataSourceJobStore configuration
See gh-27709
2021-12-14 18:32:32 +01:00
Juergen Hoeller 0ebb1c5baa Upgrade to Tomcat 9.0.56, Undertow 2.2.14, Apache HttpClient 5.1.2 & HttpAsyncClient 4.1.5, Mockito 4.1 2021-12-14 16:48:40 +01:00
Juergen Hoeller 4b7d9b1f9c Avoid compilation warning for test class with serializable base class 2021-12-14 16:48:07 +01:00
Juergen Hoeller ca84559588 Provide findAnnotationOnBean variant with allowFactoryBeanInit flag
Closes gh-27796
2021-12-14 16:47:12 +01:00
Juergen Hoeller 1af21bb451 Declare serialVersionUID on DefaultAopProxyFactory
Closes gh-27784
2021-12-14 16:46:59 +01:00
Juergen Hoeller ac581bed92 Avoid NPE against null value from toString call
Closes gh-27782
2021-12-14 16:46:42 +01:00
Juergen Hoeller 0802581aff Unit test for identifying type variable argument
See gh-27748
2021-12-14 16:46:26 +01:00
Juergen Hoeller d7b9270672 Clarify SchedulerFactoryBean's LocalDataSourceJobStore overriding
Includes clarification of interface-level cache annotations for target-class proxies.

Closes gh-27709
See gh-27726
2021-12-14 16:46:13 +01:00
Juergen Hoeller c44447f622 Avoid early initialization of empty interceptor names
Closes gh-12238
2021-12-14 16:46:01 +01:00
Stephane Nicoll 8b80d38c33 Upgrade to Reactor 2020.0.14
Closes gh-27793
2021-12-14 15:33:55 +01:00
Stephane Nicoll b06d267232 Remove references to AsyncConfigurerSupport
Closes gh-27812
2021-12-14 13:59:05 +01:00
Stephane Nicoll 8422d9d22f Add default methods to CachingConfigurer
This commit adds default methods to CachingConfigurer and
JCacheConfigurer and removes the reference to their respective support
classes as they are now irrelevant.

Closes gh-27811
2021-12-14 13:49:57 +01:00
Stephane Nicoll c50a5096a0 Upgrade to Netty 4.1.72.Final 2021-12-13 16:18:25 +01:00
Stephane Nicoll c25c550113 Merge pull request #27804 from aoyvx
* pr/27804:
  Polish "Fix javadoc reference to ThrowsAdvice"
  Update copyright year of changed file
  Fix javadoc reference to ThrowsAdvice

Closes gh-27804
2021-12-12 16:33:45 +01:00
Stephane Nicoll 9e09d6cde4 Polish "Fix javadoc reference to ThrowsAdvice"
See gh-27804
2021-12-12 16:32:35 +01:00
Stephane Nicoll 31b8587ce6 Update copyright year of changed file
See gh-27804
2021-12-12 16:30:06 +01:00
xay 00375df4e8 Fix javadoc reference to ThrowsAdvice
See gh-27804
2021-12-12 16:27:28 +01:00
Stephane Nicoll b1352e1833 Upgrade to Log4j2 2.15.0 2021-12-10 15:05:56 +01:00
Sam Brannen b2e94f611f Convert single null argument to Optional.empty() in SpEL varargs expression
Prior to this commit, if a single null value was passed to a method with
a varargs array of type java.util.Optional, that null value was passed
unmodified. On the contrary, a null passed with additional values to
such a method resulted in the null being converted to Optional.empty().

This commit ensures that a single null value is also converted to
Optional.empty() for such SpEL expressions.

Closes gh-27795
2021-12-10 13:53:28 +01:00
Sam Brannen ad7cdc5ce9 Fix regression for null varargs in SpEL expressions
A regression was introduced in gh-27582. Specifically, when null is
supplied as the single argument for a varargs parameter in a method or
function in a SpEL expression, ReflectionHelper currently throws a
NullPointerException instead of leaving the null value unchanged.

This commit fixes this regression.

Closes gh-27719
2021-12-10 13:12:44 +01:00
Stephane Nicoll 6cc9538ab9 Start building against Reactor 2020.0.14 snapshots
See gh-27793
2021-12-10 07:55:44 +01:00
Rossen Stoyanchev e9083d7d20 Apply LogFormatUtils in more places 2021-12-09 14:53:52 +00:00
Stephane Nicoll 98ce171b30 Revert "Mention explicitly that @EventListener should be put on public methods"
This reverts commit 57a5370eec.

See gh-27777
2021-12-09 15:18:56 +01:00
Stephane Nicoll 57a5370eec Mention explicitly that @EventListener should be put on public methods
Closes gh-27777
2021-12-09 14:43:00 +01:00
Rossen Stoyanchev 99c7608ffe Replace both EOL and control characters 2021-12-08 11:25:38 +00:00
Arjen Poutsma c0f79ee00a Merge pull request #25092 from jkatada:fix-ModelAndView-status-for-redirect
* gh-25092:
  Fix for ModelAndView.status not working with RedirectView
2021-12-07 13:56:19 +01:00
Katada, Junya 9261766677 Fix for ModelAndView.status not working with RedirectView 2021-12-07 13:39:57 +01:00
Juergen Hoeller 14f24f43d7 Polishing 2021-12-03 22:36:31 +01:00
Juergen Hoeller d7e0eed8d2 Clarify getBeanProvider(ResolvableType) semantics for unresolved generics
Closes gh-27727
2021-12-03 22:33:50 +01:00
Juergen Hoeller 7c834d98c2 Upgrade to ASM master (including early support for Java 19 bytecode)
Closes gh-27740
2021-12-03 22:32:26 +01:00
Juergen Hoeller 70974e006e Upgrade to Tomcat 9.0.55, Undertow 2.2.13, RxJava 3.1.3, SmallRye Mutiny 1.2, Joda-Time 2.10.13, JRuby 9.2.20.1, HtmlUnit 2.55, Checkstyle 9.2 2021-12-03 22:32:00 +01:00
Arjen Poutsma 2f557d9583 Merge pull request #25358 from ivd-git:router-function-handler-not-found-to-exception-pr
* gh-25358:
  Polish "Throw 404 ResponseStatusException when no routes found"
  Throw 404 ResponseStatusException when no routes found
2021-12-03 12:51:44 +01:00
Arjen Poutsma b84fe99d07 Polish "Throw 404 ResponseStatusException when no routes found"
See gh-25358
2021-12-03 12:01:49 +01:00
Ingmar van Dijk 69df27a99f Throw 404 ResponseStatusException when no routes found
This commit makes it possible to customize 404 responses generated by
RouterFunctionWebHandler, by throwing an ResponseStatusException
instead of returning a standard 404 response.

See gh-25358
2021-12-03 12:01:49 +01:00
Rossen Stoyanchev 5649a6f8ef Update exchangeToMono Javadoc
This time showing a more representative example.

See gh-27645
2021-12-03 09:21:21 +00:00
Arjen Poutsma be6eeafe78 Revert change createException to createError
createError is not available in 5.3.

See gh-27645
2021-12-02 15:59:51 +01:00
Arjen Poutsma b77b45434f Change createException to createError
See gh-27645
2021-12-02 15:11:15 +01:00
Rossen Stoyanchev 6582787678 Apply resources after application HttpClient mapper
Closes gh-27749
2021-12-02 12:28:36 +00:00
Rossen Stoyanchev 8b89128c7b Update createException example for WebClient
Closes gh-27645
2021-12-02 11:53:43 +00:00
Arjen Poutsma 2a5713f389 Always copy ServerResponse headers
Prior to this commit, ServerResponse headers would only be written if
there were no existing headers with the same name, thus making it
impossible to overwrite existing headers.

With the changes in this commit, headers are always written.

Closes gh-27741
2021-11-30 13:38:16 +01:00
Sam Brannen 40d2058b97 Upgrade to JUnit 5.8.2
Closes gh-27744
2021-11-30 12:22:31 +01:00
Rossen Stoyanchev 0d478ca8dd Add link to WebSocket scope from the Spring Core section
Closes gh-25172
2021-11-29 17:37:37 +00:00
Rossen Stoyanchev 445c0def0c Update docs on heartbeats with simple broker
Closes gh-27746
2021-11-29 17:13:57 +00:00
Stephane Nicoll ef696c787b Merge pull request #22246 from diguage
* pr/22246:
  Polish "Fix reference to CountingBeforeAdvice"
  Fix reference to CountingBeforeAdvice

Closes gh-22246
2021-11-28 10:53:15 +01:00
Stephane Nicoll 27257fb82e Polish "Fix reference to CountingBeforeAdvice"
See gh-22246
2021-11-28 10:52:16 +01:00
diguage e209a460ca Fix reference to CountingBeforeAdvice
See gh-22246
2021-11-28 10:44:48 +01:00
Brian Clozel d019c1f82b Polish
See gh-2030
2021-11-24 21:34:23 +01:00
Stephane Nicoll 82d6e07090 Merge pull request #2030 from matips
* pr/2030:
  Polish "Clarify behaviour of AnnotationBeanNameGenerator with acronyms"
  Clarify behaviour of AnnotationBeanNameGenerator with acronyms

Closes gh-2030
2021-11-24 16:29:45 +01:00
Stephane Nicoll a1b2695c3a Polish "Clarify behaviour of AnnotationBeanNameGenerator with acronyms"
See gh-2030
2021-11-24 16:29:13 +01:00
Mateusz 341f4882ed Clarify behaviour of AnnotationBeanNameGenerator with acronyms
Name transformation is delegated to Introspector#decapitalize, which
states "but in the (unusual) special case when there is more than one
character and both the first and second characters are upper case, we
leave it alone.". This commit clarifies this behavior.

See gh-2030
2021-11-24 16:00:22 +01:00
Rossen Stoyanchev 829bed03af Polishing contribution
Closes gh-27723
2021-11-24 13:05:05 +00:00
Andreas Grub ce0aed216b Add getter for RequestMappingInfo.BuilderConfiguration
This improves support for programmatic registration of mappings to
use the same config as that of the RequestMappingHandlerMapping.

See gh-27723
2021-11-24 13:05:05 +00:00
Rossen Stoyanchev 0d7c562693 Polishing contribution
Closes gh-910
2021-11-24 13:05:05 +00:00
/usr/local/ΕΨΗΕΛΩΝ 913cc079af TagWriter can write empty attribute
See gh-910
2021-11-24 13:05:05 +00:00
Rossen Stoyanchev 3f7dec0b0d Polishing contribution
Closes gh-699
2021-11-24 13:05:05 +00:00
Marco Krikke 830cc3450f Improved DataBinder Javadoc for xxx*yyy pattern matching
The default documentation does not mention xxx*yyy pattern matching,
which is, however, supported by PatternMatchUtils. Such a pattern
can be useful for matching nested properties in all elements of a
collection, e.g. property[*].nestedProperty.

See gh-699
2021-11-24 13:05:05 +00:00
Stephane Nicoll 6f6d27f50f Merge pull request #1246 from fededonna
* pr/1246:
  Polish "Expose prestartAllCoreThreads on ExecutorService"
  Expose prestartAllCoreThreads on ExecutorService

Closes gh-1246
2021-11-24 14:02:48 +01:00
Stephane Nicoll 19a8b94b21 Polish "Expose prestartAllCoreThreads on ExecutorService"
See gh-1246
2021-11-23 17:17:22 +01:00
Federico Donnarumma 2c53e9e308 Expose prestartAllCoreThreads on ExecutorService
See gh-1246
2021-11-23 16:14:39 +01:00
Arjen Poutsma 2271b6078e Polishing contribution
See gh-1607
2021-11-23 10:44:45 +01:00
qxo e8eeb99ac8 Repect StaxDriver in XStreamMarshaller::marshalXmlStreamWriter
This commit makes sure that namespaces configured via the streamDriver
property are respected.
2021-11-23 10:41:04 +01:00
Stephane Nicoll b67e97d388 Polish 2021-11-22 16:13:37 +01:00
Stephane Nicoll 656f0591c6 Merge pull request #1330 from kazuki43zoo
* pr/1330:
  Polish "Add tests for AbstractRoutingDataSource"
  Add tests for AbstractRoutingDataSource

Closes gh-1330
2021-11-22 13:46:29 +01:00
Stephane Nicoll 23babe27bb Polish "Add tests for AbstractRoutingDataSource"
See gh-1330
2021-11-22 13:43:08 +01:00
Kazuki Shimizu bcb9f159ca Add tests for AbstractRoutingDataSource
See gh-1330
2021-11-22 13:43:08 +01:00
Stephane Nicoll 8ca9187938 Merge pull request #1025 from julianladisch
* pr/1025:
  Fix simple data format in appendix

Closes gh-1025
2021-11-22 13:27:56 +01:00
julianladisch 1e0bdf95d0 Fix simple data format in appendix
See gh-1025
2021-11-22 13:26:57 +01:00
Stephane Nicoll 44da9451c4 Merge pull request #1000 from awgtek
* pr/1000:
  Polish "Refine StoredProcedure#declareParameter Javadoc"
  Refine StoredProcedure#declareParameter Javadoc

Closes gh-1000
2021-11-22 13:21:00 +01:00
Stephane Nicoll 544f357661 Polish "Refine StoredProcedure#declareParameter Javadoc"
See gh-1000
2021-11-22 13:20:16 +01:00
awgtek ca4f338d75 Refine StoredProcedure#declareParameter Javadoc
See gh-1000
2021-11-22 13:18:24 +01:00
Stephane Nicoll 8e8c88ea5c Merge pull request #767 from thomasdarimont
* pr/767:
  Document @Bean definitions via default methods

Closes gh-767
2021-11-22 12:55:38 +01:00
Thomas Darimont 767299c6dd Document @Bean definitions via default methods
See gh-767

Co-authored-by: Stephane Nicoll <snicoll@vmware.com>
2021-11-22 12:55:22 +01:00
Stephane Nicoll 3290495222 Merge pull request #27699 from quaff
* pr/27699:
  Fix typo

Closes gh-27699
2021-11-22 10:31:13 +01:00
Yanming Zhou b4b3c2ead6 Fix typo
See gh-27699
2021-11-22 10:30:45 +01:00
Jerome Prinet dfd5374f02 Upgrade Gradle enterprise plugin to 3.7.2
Closes gh-27704
2021-11-19 15:06:27 +01:00
Arjen Poutsma 722ab25f27 Support empty file names in UriUtils::extractFileExtension
Closes gh-27639
2021-11-19 12:37:00 +01:00
Sam Brannen c37d6c30a0 Fix nullability declarations in MergedContextConfiguration 2021-11-18 19:23:28 +01:00
Arjen Poutsma 5fbdd6dcfe Throw exception using capturing patterns in AntPathMatcher
Closes gh-27688
2021-11-17 16:52:17 +01:00
d4ksn 29572600dc Ensure that references > MAX_REFERENCE_SIZE are not processed
This commit ensures that only HTML references of length <
MAX_REFERENCE_SIZE are considered as potential references. This check is
possible because reference longer than 10 digits are out of bounds for
Integers.

Closes gh-1249
2021-11-16 15:04:08 +01:00
Spring Builds aaf626a537 Next development version (v5.3.14-SNAPSHOT) 2021-11-11 07:42:44 +00:00
Arjen Poutsma 9197f15a30 Use ByteArrayDecoder in DefaultClientResponse::createException
This commit changes DefaultClientResponse::createException to use
the ByteArrayDecoder, instead of converting to DataBuffers and
turning these into a byte array.

Closes gh-27666
2021-11-10 16:24:49 +01:00
Juergen Hoeller 15a6373fed Avoid nullability warnings 2021-11-10 14:22:06 +01:00
Juergen Hoeller 2a268701c4 Introduce optimizeLocations flag for resource location filtering on startup
This flag is off by default since it requires jar files with directory entries.

Closes gh-27624
2021-11-10 14:21:48 +01:00
Juergen Hoeller 11a0df3fd1 Upgrade to Tomcat 9.0.54, Netty 4.1.70, HtmlUnit 2.54, XMLUnit 2.8.3 2021-11-09 22:36:11 +01:00
Juergen Hoeller b167e1a93f Remove unnecessary final declarations (for consistency) 2021-11-09 22:35:24 +01:00
Juergen Hoeller 8d735e6e60 Note on PersistenceExceptionTranslator sorting and non-singleton retrieval
Closes gh-26412
2021-11-09 22:30:44 +01:00
Juergen Hoeller 9bc09631d6 Recommend ObjectProvider as alternative to @Lazy for optional dependencies
Closes gh-27649
2021-11-09 22:29:56 +01:00
Stephane Nicoll 39be572a7a Upgrade to Reactor 2020.0.13
Closes gh-27636
2021-11-09 19:38:10 +01:00
Abdullah Khan 6ac780d595 Fix grammar in webflux-webclient.adoc
Closes gh-27657
2021-11-09 14:22:50 +01:00
Rossen Stoyanchev c6ce65ef56 Polishing contribution
Closes gh-27623
2021-11-09 09:47:02 +00:00
happyWilliam0 b5743966d6 Improve efficiency of UrlPathHelper#getSanitizedPath
See gh-27623
2021-11-09 09:47:02 +00:00
Rossen Stoyanchev c5de5c9939 Update Javadoc of LogFormatUtils
Closes gh-27632
2021-11-08 21:21:54 +00:00
Sam Brannen ff1485fd8d Fix log message formatting in CandidateComponentsIndexLoader 2021-11-05 10:31:10 +01:00
Stephane Nicoll 1b4438caac Start building against Reactor 2020.0.13 snapshots
See gh-27636
2021-11-04 14:47:37 +01:00
Arjen Poutsma 0c7e000250 Refactor Contents to DefaultParts
This commit moves the Contents abstraction into DefaultParts

See gh-27613
2021-11-03 15:02:12 +01:00
Arjen Poutsma 694db2273f Add Part::delete method
This commit introduces the Part::delete method, that deletes its
underlying storage.

Closes gh-27612
2021-11-02 16:15:44 +01:00
Stephane Nicoll 47d3819eab Merge pull request #27604 from Xjzon
* pr/27604:
  Polish "Add support for custom expression parsing"
  Add support for custom expression parsing

Closes gh-27604
2021-10-28 14:21:29 +02:00
Stephane Nicoll f295c8b2fb Polish "Add support for custom expression parsing"
See gh-27604
2021-10-28 14:20:15 +02:00
Xjzon 40d84c297b Add support for custom expression parsing
See gh-27604
2021-10-28 13:57:15 +02:00
Arjen Poutsma 0416168d0e Fix bug in max header calculation in DefaultPartHttpMessageReader
This commit fixes a bug in the DefaultPartHttpMessageReader, in the
check for exceeding the maximum header size. Before this commit, the
entire buffer size was considered, thus triggering an exception even
though the max header limit was not exceeded. After this commit, we only
consider the size up until the end-of-header mark (CRLFCRLF).

Furthermore, this commit increases the default maximum header size to
10k, the same default as Commons File upload.

Closes gh-27612
2021-10-27 16:28:32 +02:00
Sam Brannen c4c3d59d07 Remove unused code in FormattingConversionServiceTests 2021-10-25 17:02:58 +02:00
Сергей Цыпанов 0268e76298 Improve mapping function in ExtendedEntityManagerCreator.createProxy()
Closes gh-27456
2021-10-25 16:30:26 +02:00
Kenzo Spaulding 4ec8ae42f4 Add test cases to SpEL's MapAccessorTests
Closes gh-26981
2021-10-23 17:45:37 +02:00
Sam Brannen 995aaa6159 Polishing 2021-10-23 16:08:00 +02:00
Sam Brannen 2c89ff934d Update copyright date
See gh-27560
2021-10-23 15:59:46 +02:00
Daniil Pozdeev c58853f5e5 Use LocalDataSourceJobStore only if one is not set via Quartz properties
Prior to this commit, Spring's SchedulerFactoryBean always set the
"org.quartz.jobStore.class" property to LocalDataSourceJobStore even if
the user had already specified a custom JobStore implementation via the
Quartz properties file or Properties object, thereby effectively
ignoring the user configuration.

This commit addresses this by configuring Quartz to use Spring's
LocalDataSourceJobStore only if a JobStore has not already been
specified via user configuration.

Closes gh-27560
2021-10-23 15:22:42 +02:00
xxpain 66826ac960 Fix typo in Javadoc in HeaderAssertions
Closes gh-27589
2021-10-22 15:28:27 +02:00
Sam Brannen a603779f33 Return previous value in UndertowHeadersAdapter's remove() method
Prior to this commit, UndertowHeadersAdapter's remove() method violated
the java.util.Map contract by always returning null.

This commit fixes this by returning the previous list stored under the
specified key, and otherwise returning null if no previous value was
present.

Closes gh-27592
2021-10-22 14:57:12 +02:00
Сергей Цыпанов e5475d698a Iterate over Map's entrySet() instead of keySet() in PropertyEditorRegistrySupport
Closes gh-27591
2021-10-22 14:15:33 +02:00
Sam Brannen b728b4640b Add explicit tests for SpEL functions for fix for gh-27582 2021-10-22 13:46:11 +02:00
Sam Brannen bc657eb4d5 Fix SpEL vararg method invocation for strings containing commas
Prior to this commit, if a SpEL expression invoked a method or
registered function that declares a String varargs argument, there were
sometimes issues with converting the input arguments into the varargs
array argument. Specifically, if the expression supplied a single
String argument containing a comma for the varargs (such as "a,b"),
SpEL's ReflectionHelper.convertArguments() method incorrectly converted
that single String to an array via the ConversionService, which
indirectly converted that String using the StringToArrayConverter,
which converts a comma-delimited String to an array. Thus, "a,b"
effectively got converted to a two-dimensional array ["a", "b"] instead
of simply ["a,b"].

This commit fixes this bug by avoiding use of the TypeConverter and
ConversionService for single arguments supplied as varargs when the
single argument's type matches the varargs array component type.

Closes gh-27582
2021-10-22 13:13:13 +02:00
Sam Brannen 9b967775ed Polish Spel's ReflectionHelper.setupArgumentsForVarargsInvocation() 2021-10-22 11:08:45 +02:00
Sam Brannen 9af11ad5ce Fix Javadoc formatting issues 2021-10-22 11:08:45 +02:00
Sam Brannen 7a54ff2d21 Extract public TypeFilterUtils from ComponentScanAnnotationParser
Prior to this commit, third parties using @ComponentScan's @Filter
annotation had to implement their own parsing for @Filter
AnnotationAttributes as well as instantiation of the corresponding
TypeFilters. In such cases the various *Aware callbacks
(BeanFactoryAware, EnvironmentAware, etc.) should also be supported.

This commit therefore extracts a new public TypeFilterUtils class from
ComponentScanAnnotationParser so that third parties can benefit from
consistent TypeFilter creation from @ComponentScan @Filter annotations.

Closes gh-27553
2021-10-21 14:15:38 +02:00
Sam Brannen ec3f857bda Polish contribution
See gh-27586
2021-10-21 12:40:10 +02:00
no-brand b3eb1a2ad7 Improve example in Javadoc for HttpEntity
Closes gh-27586
2021-10-21 12:35:59 +02:00
Spring Builds bce850aa12 Next development version (v5.3.13-SNAPSHOT) 2021-10-21 05:57:00 +00:00
Sam Brannen 3d6d8a947a Update "Reporting a Vulnerability" link 2021-10-20 14:48:51 +02:00
Sam Brannen 6fa6bfe421 Fix link to Spring Framework project page in Javadoc overview 2021-10-19 16:46:01 +02:00
Rossen Stoyanchev 05ea991d62 Removing locations logging in ResourceHttpRequestHandler
See gh-27575
2021-10-19 12:25:33 +01:00
Arjen Poutsma a248a52575 Revert transitive MediaType comparators
The fix made for gh-27488 resulted in a change of the default order
of codecs. This commit reverts these changes, so that the previous
order is restored.

Closes gh-27573
2021-10-19 11:53:22 +02:00
Arjen Poutsma 2a3c9e403f Revert "Polishing"
This reverts commit bfa01b35df.
2021-10-19 10:16:27 +02:00
Rossen Stoyanchev bad87be306 Fix checkstyle warning
See gh-27569
2021-10-18 17:04:11 +01:00
Rossen Stoyanchev 346b755802 Fix assertion message in DefaultDataBuffer
Closes gh-27567
2021-10-18 16:54:24 +01:00
Smile 4978eeff7f Update Javadoc in DefaultResponseErrorHandler
Closes gh-27569
2021-10-18 16:26:48 +01:00
Sam Brannen 052ed50f48 Fix copy-and-paste error in Javadoc 2021-10-17 19:33:42 +02:00
Rossen Stoyanchev 76c9306dda Adjust logging of resource locations 2021-10-14 17:18:34 +01:00
Sam Brannen 0853baaa3f Fix Javadoc in [NamedParameter]JdbcOperations.queryForObject methods
This commit fixes the Javadoc in all queryForObject(...) methods in
JdbcOperations and NamedParameterJdbcOperations regarding what kinds of
exceptions are thrown under which conditions.

Closes gh-27559
2021-10-14 15:15:23 +02:00
Spring Builds bf461ba0b2 Next development version (v5.3.12-SNAPSHOT) 2021-10-14 09:35:45 +00:00
Rossen Stoyanchev 0705454ce0 Fix typo in Javadoc
See gh-27484
2021-10-14 09:42:40 +01:00
Rossen Stoyanchev a178bbe86f DefaultResponseErrorHandler shows full error details
Closes gh-27552
2021-10-13 20:51:34 +01:00
Sam Brannen fcf4315e02 Indent with tabs instead of spaces 2021-10-13 20:04:40 +02:00
Sam Brannen 89c7797ffb Commit in DatabasePopulatorUtils if Connection has auto-commit=false
Prior to this commit, DatabasePopulatorUtils.execute(...) did not
perform a commit for the current Connection. This works for most use
cases; however, when DatabasePopulatorUtils is used to execute
initialization scripts without a managed transaction -- for example,
via a DataSourceInitializer configured as a bean in the
ApplicationContext or via Spring Boot configuration in
application.properties -- if the underlying database is configured with
auto-commit=false, the results of executing the SQL scripts are not
committed to the database which can lead to data being silently lost.

This commit addresses this issue by committing the Connection for the
supplied DataSource if the connection is not configured for auto-commit
and is not transactional. Existing use cases running with a managed
transaction should therefore not be affected by this change.

Closes gh-27008
2021-10-13 19:10:09 +02:00
Rossen Stoyanchev 4dac8339ff Filter non-existing static resource locations
Same as a2c52a97ba, on the WebFlux side.

See gh-27538
2021-10-13 14:40:34 +01:00
Rossen Stoyanchev 0436dd04bf Correctly handle coroutine with ResponseEntity
ResponseEntityResultHandler nests correctly, only once for the ResponseEntity,
when there is a Mono adapted from a Kotlin Continuation.

Closes gh-27292
2021-10-13 14:40:34 +01:00
Hantsy Bai 1e3996ea78 Upgrade SmallRye Mutiny to 1.1.1
Closes gh-27555
2021-10-13 15:27:02 +02:00
Koen Punt 50b92118a9 Include correct keyword in CookieAssertions failure messages
Closes gh-27550
2021-10-13 14:02:55 +02:00
Juergen Hoeller b1c7f7d127 Polishing 2021-10-13 12:48:47 +02:00
Juergen Hoeller 0f36569d75 Remove dead fallback code 2021-10-13 12:38:39 +02:00
Juergen Hoeller 2cbba0923b Upgrade to Netty 4.1.69, Jetty 9.4.44, Kotlin 1.5.31 2021-10-13 12:38:06 +02:00
Rossen Stoyanchev 800922266a Upgrade to Reactor 2021.0.12
Closes gh-27527
2021-10-12 16:23:18 +01:00
Juergen Hoeller eda3ca5fbc Remove unnecessary final declarations at method level 2021-10-12 15:17:44 +02:00
Juergen Hoeller e4934a90eb Use TriggerContext's Clock instead of new Date()
Closes gh-27546
2021-10-12 15:17:18 +02:00
Juergen Hoeller 715f300fa1 Avoid expensive isReadable() check during classpath scan
Closes gh-25741
See gh-21372
2021-10-12 15:15:51 +02:00
Juergen Hoeller b53275f2d2 Add efficient existence check to ClassPathResource.isReadable()
Includes reduced isReadable() check in PathResourceLookupFunction, aligned with PathResourceResolver.

Closes gh-27538
See gh-21372
2021-10-12 15:13:05 +02:00
Juergen Hoeller 1490d27d75 Decouple urlResourceWithCharset test from existence of tmp directory
See gh-25738
2021-10-12 15:10:19 +02:00
Rossen Stoyanchev a2c52a97ba Filter non-existing static resource locations
See gh-27538
2021-10-12 11:59:55 +01:00
Sam Brannen 5bd90538b3 Introduce test for gh-27499 and polish contribution 2021-10-12 12:22:24 +02:00
Nick 50ccb1bfcd Avoid duplicate JCacheOperationSource bean registration in <cache:annotation-driven />
In our application we use XML context and <cache:annotation-driven />
declaration. Also we disable bean definition duplication by setting
GenericApplicationContext.setAllowBeanDefinitionOverriding(false) in an
ApplicationContextInitializer. This combination leads to a
BeanDefinitionOverrideException because the
DefaultJCacheOperationSource bean is registered twice.

 - once for: parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
 - once for: parserContext.registerBeanComponent(new BeanComponentDefinition(sourceDef, sourceName));

This commit refactors JCacheCachingConfigurer.registerCacheAspect(...)
so that the JCacheOperationSource bean is registered only once.

Closes gh-27499
2021-10-12 12:05:30 +02:00
Stephane Nicoll 83eac9af18 Upgrade CI to github-release resource 1.5.5
Closes gh-27459
2021-10-11 16:18:35 +02:00
Sam Brannen eb07dea795 Polish contribution
See gh-27544
2021-10-11 15:31:40 +02:00
Сергей Цыпанов 114fa47171 Use Arrays.hashCode() in ByteArrayResource.hashCode() 2021-10-11 15:28:50 +02:00
Sam Brannen 63fac1b7c8 Allow default CacheAwareContextLoaderDelegate configuration via system property
Prior to this commit, the default CacheAwareContextLoaderDelegate could
be configured by extending AbstractTestContextBootstrapper and
overriding getCacheAwareContextLoaderDelegate(); however, this required
that the user configure the custom TestContextBootstrapper via
@BootstrapWith.

This commit introduces a new
"spring.test.context.default.CacheAwareContextLoaderDelegate" property
that can be configured via a JVM system property or via the
SpringProperties mechanism. BootstrapUtils uses this new property to
load the default CacheAwareContextLoaderDelegate. If the property is
not defined, BootstrapUtils will fall back to creating a
DefaultCacheAwareContextLoaderDelegate as it did previously.

This allows third parties to configure the default
CacheAwareContextLoaderDelegate transparently for the user -- for
example, to intercept context loading in order to load the context in a
different manner -- for example, to make use of ahead of time (AOT)
techniques for implementing a different type of ApplicationContext at
build time.

Closes gh-27540
2021-10-11 14:59:09 +02:00
Rossen Stoyanchev e8f6cd10a5 Apply value formatting to resolved exceptions 2021-10-11 11:14:02 +01:00
Sam Brannen 47b8e8d528 Upgrade to Mockito 4 2021-10-10 23:26:07 +02:00
Sam Brannen bdfd983bb4 Fix example code formatting in @EnableWebMvc 2021-10-08 21:30:39 +02:00
Juergen Hoeller 87aaf5049b Polishing 2021-10-08 20:41:51 +02:00
Juergen Hoeller 4b01370f54 UriTemplateRequestEntity overrides equals/hashCode
Closes gh-27531
2021-10-08 20:41:18 +02:00
Rossen Stoyanchev b6111d04a5 Ensure WebClientResponseException for malformed response
Closes gh-27262
2021-10-07 16:50:53 +01:00
Ashley Scopes 9bd989f1bb WebClient tests for socket and response format issues
Added test case for malformed response chunk, which is
now failing as expected.

See gh-27262
2021-10-07 16:50:53 +01:00
Stephane Nicoll d5597a75a6 Start building against Reactor 2020.0.12 snapshots
See gh-27527
2021-10-07 08:51:32 +02:00
Rossen Stoyanchev 90fdcf88d8 Generalize formatValue
Provide an overload for additional control and compact output.
2021-10-06 21:27:56 +01:00
Sam Brannen 5d3b16cd3a Indent with tabs instead of spaces 2021-10-06 15:42:52 +02:00
Sam Brannen 41ae9632d1 Upgrade to Checkstyle 9.0 and spring-javaformat 0.0.29
This commit upgrades the Gradle build to use Checkstyle 9.0 and
spring-javaformat 0.0.29 (which internally uses Checkstyle 8.45.1).

Closes gh-27520
2021-10-06 12:11:19 +02:00
Sam Brannen 47b0da6b25 Polishing 2021-10-06 11:48:30 +02:00
Arjen Poutsma c99210c01f Propagate Reactor Context when using FluxSink
This commit makes sure that the Reactor context from a given mono or
flux is propagated to the Flux returned by a FluxSink. This change
affects both DataBufferUtils::write and internal classes used by the
DefaultPartHttpMessageReader.

Closes gh-27517
2021-10-05 16:30:49 +02:00
Rossen Stoyanchev 7b9848a352 Replace deprecated Reactor Context related methods 2021-10-05 14:33:52 +01:00
Sam Brannen 0e83466023 Reference Hamcrest Javadoc via javadoc.io
Due to an SSL/TLS issue with hamcrest.org, the Dokka task fails with the
following.

> Failed to download package-list from https://hamcrest.org/JavaHamcrest/javadoc/2.1/package-list,
> this might suggest that remote resource is not available, module is
> empty or dokka output got corrupted

See: https://github.com/hamcrest/JavaHamcrest/issues/280

As a workaround, this commit switches to javadoc.io to reference the
Hamcrest Javadoc APIs.
2021-10-05 15:23:44 +02:00
Sam Brannen 48a507a993 Clean up warnings 2021-10-05 14:35:32 +02:00
Sam Brannen be3bc4c164 Comment out unused fudgeFactor 2021-10-05 14:24:18 +02:00
Rossen Stoyanchev e68219c1ac ResponseStatusExceptionHandler logs exception message only
No need to log the full exception for a resolved exception, and as the
comment suggests that it mirrors Spring MVC equivalent, which also
logs the message only.
2021-10-05 12:12:17 +01:00
Stephane Nicoll 151852b164 Upgrade to GitHub Changelog Generator 0.0.7 in CI
Closes gh-27512
2021-10-03 07:09:24 +02:00
Juergen Hoeller 49427b0c3c Upgrade to Apache Johnzon 1.2.14, Vavr 0.10.4, WebJars Locator 0.48, HtmlUnit 2.53 2021-10-02 12:08:09 +02:00
Juergen Hoeller bf373c5065 Skip all flaky StopWatch time assertions 2021-10-02 12:04:13 +02:00
Sam Brannen 678fd8344e Polishing 2021-10-01 14:37:07 +02:00
Juergen Hoeller f632165dec Invoke bean-derived (Auto)Closeable.close() method directly
Closes gh-27504
2021-10-01 13:26:25 +02:00
Sam Brannen fd11789db9 Polish JSR-107 caching ref docs 2021-10-01 12:51:52 +02:00
Jens Schauder d6ec6f0fe9 Remove remark about missing caching API. 2021-10-01 11:56:36 +02:00
Sam Brannen 7311ae19be Fix build by disabling linking to JUnit 5.8.1 Javadoc
The `package-list` file no longer exists at
https://junit.org/junit5/docs/5.8.1/api/, due to the following commit.

https://github.com/junit-team/junit5/commit/67ad4e545518b0ce2b0e7c96df31a669866d5003
2021-10-01 11:09:59 +02:00
Sam Brannen f0aa4f4857 Escape closing curly braces in regular expressions for Android support
PR gh-24470 introduced a regression for Android users by no longer
escaping closing curly braces in regular expressions.

This commit therefore partially reverts the changes made in 273812f9c5
for closing curly braces (`}`).

Closes gh27467
2021-10-01 10:35:28 +02:00
Juergen Hoeller f64f07049d Upgrade to SLF4J 1.7.32 2021-09-30 18:12:10 +02:00
Juergen Hoeller 24bcb52b2f Polishing 2021-09-30 18:09:07 +02:00
Juergen Hoeller 4f44ae3f28 Polishing 2021-09-30 17:34:22 +02:00
Juergen Hoeller a295a28e4b Defensively handle fast class generation failure for individual methods
Includes rethrowing of last actual defineClass exception encountered.

Closes gh-27490
2021-09-30 17:33:58 +02:00
Arjen Poutsma bfa01b35df Polishing
See gh-27488
2021-09-30 17:09:03 +02:00
Arjen Poutsma 388c8e4aa5 Make sure that MediaType comparators are transitive
Previous to this commit, the specificity and quality comparators
(used by MediaType::sortByQualityValue and MediaType::sortBySpecificity)
could result in IllegalArgumentExceptions when used for sorting.
The underlying reason was that the comparators were not transitive, and
both media types with the same type, and types with the same amount of
parameters, would be considered identical by the comparator (result 0).

This commit ensures that the comparators are transitive.

Closes gh-27488
2021-09-30 16:15:38 +02:00
Sam Brannen 96e4d3a530 Fail Gradle build for Javadoc warnings
In order to catch Javadoc errors in the build, we now enable the
`Xwerror` flag for the `javadoc` tool. In addition, we now use
`Xdoclint:syntax` instead of `Xdoclint:none` in order to validate
syntax within our Javadoc.

This commit fixes all resulting Javadoc errors and warnings.

This commit also upgrades to Undertow 2.2.12.Final and fixes the
artifact names for exclusions for the Servlet and annotations APIs.

The incorrect exclusion of the Servlet API resulted in the Servlet API
being on the classpath twice for the javadoc task, which resulted in the
following warnings in previous builds.

javadoc: warning - Multiple sources of package comments found for package "javax.servlet"
javadoc: warning - Multiple sources of package comments found for package "javax.servlet.http"
javadoc: warning - Multiple sources of package comments found for package "javax.servlet.descriptor"
javadoc: warning - Multiple sources of package comments found for package "javax.servlet.annotation"

Closes gh-27480
2021-09-29 14:02:37 +02:00
Juergen Hoeller 040445612f Polishing 2021-09-28 18:15:56 +02:00
Juergen Hoeller 86b010a6b2 Defensive reference to JNDI API for JDK 9+ (optional java.naming module)
Closes gh-27483
2021-09-28 18:15:22 +02:00
Juergen Hoeller 2feedb98cc Remove lineSeparator LF requirement (accept LF/CR/CRLF by default)
See gh-27481
2021-09-28 18:15:00 +02:00
Arjen Poutsma 3be2b32e21 Remove only leading space for SSE data
Prior to this commit, all white space was trimmed from Server Sent Event
data. After this commit, only a leading space is removed (if present).

Closes gh-27473
2021-09-28 14:56:39 +02:00
Sam Brannen 85bdea6f47 Fix code formatting in Javadoc
See gh-27480
2021-09-28 13:41:25 +02:00
Sam Brannen bfdc99ab79 Fix Javadoc errors
See gh-27480
2021-09-28 11:44:12 +02:00
Sam Brannen 2567b20949 Upgrade to spring-javaformat 0.0.28 and downgrade to Checkstyle 8.41
In order to be able to use text blocks and other new Java language
features, we are upgrading to a recent version of Checkstyle.

The latest version of spring-javaformat-checkstyle (0.0.28) is built
against Checkstyle 8.32 which does not include support for language
features such as text blocks. Support for text blocks was added in
Checkstyle 8.36.

In addition, there is a binary compatibility issue between
spring-javaformat-checkstyle 0.0.28 and Checkstyle 8.42. Thus we cannot
use Checkstyle 8.42 or higher.

In this commit, we therefore upgrade to spring-javaformat-checkstyle
0.0.28 and downgrade to Checkstyle 8.41.

This change is being applied to `5.3.x` as well as `main` in order to
benefit from the enhanced checking provided in more recent versions of
Checkstyle.

Closes gh-27481
2021-09-28 10:29:31 +02:00
Juergen Hoeller 119c78b1c9 Skip flaky StopWatch time assertions 2021-09-27 17:11:12 +02:00
Juergen Hoeller d8e18f56e1 Upgrade to Protobuf 3.18, Rome 1.16, BlockHound 1.0.6, Caffeine 2.9.2, Groovy 3.0.9, Tomcat 9.0.53 2021-09-27 17:01:18 +02:00
Juergen Hoeller 211f0bbf88 Fix invalid characters in source files
Closes gh-27475
2021-09-27 16:57:54 +02:00
Juergen Hoeller b0c424b376 Deprecate RxJava 2 in favor of RxJava 3
Closes gh-27474
2021-09-27 16:56:28 +02:00
Juergen Hoeller 9ff0d717f2 Restore lenient fallback in case of several non-public constructors
See gh-27437
2021-09-27 16:52:11 +02:00
Rossen Stoyanchev 93f8706dd3 Update docs for ControllerAdvice
In 5.3 it became possible to handle exceptions from any handler through
ExceptionHandler's in a ControllerAdvice class, but this is not
mentioned in the docs

See gh-22619, gh-27338
2021-09-24 15:57:15 +01:00
Juergen Hoeller e29cfa3501 Polishing 2021-09-23 15:57:43 +02:00
Juergen Hoeller 208fafa4a3 Fix contract violations in ConcurrentReferenceHashMap's EntrySet/Iterator
Closes gh-27454
2021-09-23 15:56:49 +02:00
Juergen Hoeller 5cbc972a0d Log rejected listener container tasks at warn level
Closes gh-27451
2021-09-23 15:56:06 +02:00
Juergen Hoeller 58898de542 Provide accessors for externallyManagedConfigMembers and Init/DestroyMethods
Closes gh-27449
2021-09-23 15:54:40 +02:00
Juergen Hoeller f9d63e7bb1 BeanUtils.getResolvableConstructor falls back to single non-public constructor
Closes gh-27437
2021-09-23 15:53:54 +02:00
Sam Brannen 134c0e2916 Upgrade to JUnit 5.8.1
Closes gh-27450
2021-09-22 22:08:38 +02:00
Juergen Hoeller 1f8c233dfc Polishing 2021-09-21 17:43:03 +02:00
Juergen Hoeller 0dc5d2794f Avoid early ConversionService determination in StandardBeanExpressionResolver
Closes gh-27446
2021-09-21 17:42:50 +02:00
Juergen Hoeller 49d003857d Skip CGLIB class validation in case of optimize flag
Closes gh-27439
2021-09-21 17:42:19 +02:00
Juergen Hoeller eabe946a53 Skip readStream optimization for compatibility with misbehaving InputStreams
Closes gh-27429
2021-09-21 17:41:56 +02:00
Sam Brannen 09a1b87d37 About notes about AJDT and Kotlin not supported in Eclipse 4.21
See gh-27407
2021-09-21 14:23:02 +02:00
Sam Brannen 34abc8f577 The Kotlin plugin is no longer required for development in Eclipse
As documented, it's only required if you with to run Kotlin tests or
develop Kotlin extensions.

See gh-27407
2021-09-21 13:04:29 +02:00
Sam Brannen b0dceb484a Remove Eclipse Web Tools Platform (WTP) configuration
Since the team no longer needs the ability to treat Eclipse projects as
WTP modules, this commit removes the obsolete custom WTP configuration
for importing projects into Eclipse IDE.

See gh-27407
2021-09-21 12:37:51 +02:00
Sam Brannen 65c1eac115 Fix formatting in Eclipse/STS Project Import Guide
See gh-27407
2021-09-21 12:16:06 +02:00
Sam Brannen a37dde9a1c Revise Eclipse/STS Project Import Guide based on status quo
See gh-27407
2021-09-21 12:11:27 +02:00
Sam Brannen 28496059bc Make TestNG test methods public due to bug in TestNG TestEngine
This commit makes all test methods in our TestNG test classes public
due to the following bug in the TestNG engine for the JUnit Platform.

https://github.com/junit-team/testng-engine/issues/16

See gh-27407
2021-09-21 10:35:34 +02:00
Sam Brannen 40c51efee8 Introduce @Suite for TestNG tests
In order to allow developers to execute TestNG tests in Eclipse IDE
without installing the TestNG plugin for Eclipse, this commit introduces
a JUnit Platform @Suite class that can be executed within the IDE.

See gh-27407
2021-09-21 10:33:25 +02:00
Sam Brannen e439d6f64d Upgrade to AssertJ 3.21.0 2021-09-20 14:54:25 +02:00
Marc Philipp e29867b96e Exclude TestCase classes in spring-test build
When not excluded, TestNG will pick up nested TestCase classes and run
them.

This commit therefore filters out `*TestCase` test classes from the
build since these are not intended to be executed with the build.

See gh-27406
2021-09-20 14:02:06 +02:00
Sam Brannen 0b552a3534 Migrate to TestNG Engine for the JUnit Platform in spring-test
Prior to this commit, we had configured separate test tasks for JUnit
and TestNG. In addition, we configured a standard `test` task that
depended on the `junit` and `testNG` tasks, and we had an additional
`aggregateTestReports` task that aggregated the reports from the JUnit
and TestNG test tasks.

Thanks to the introduction of the "TestNG Engine for the JUnit
Platform", this commit simplifies our Gradle build in the spring-test
module by running JUnit 4, JUnit Jupiter, and TestNG tests on the JUnit
Platform in a single Gradle `test` task.

See gh-27406
2021-09-20 14:02:06 +02:00
Brian Clozel a50537fbaf Polish "Fix collectionToDelimitedString failure for null elements."
Fixes gh-27419
2021-09-17 15:15:51 +02:00
Koy 0d6cc12274 Fix collectionToDelimitedString failure for null elements.
Prior to this commit, calling `StringUtils#collectionToDelimitedString`
would fail with an NPE if the collection contains null elements.

This commit ensures that null elements are converted as `"null"` in the
resulting String without failure.

See gh-27419
2021-09-17 15:15:26 +02:00
Sam Brannen 008aa48d5c Fix formatting for SQL IN clause example in ref docs
See gh-27388
2021-09-16 14:10:54 +02:00
Brian Clozel 00eef79e5c Upgrade to JApicmp Gradle Plugin 0.3.0
Fixes gh-27414
2021-09-15 14:40:42 +02:00
Brian Clozel 7907478d36 Watch 5.3.x branch in the CI pipeline
Main branch has moved to the 6.0.x line, so this commit updates this CI
pipeline to the new 5.3.x maintenance branch.
2021-09-15 12:17:07 +02:00
Spring Builds c7cca2e879 Next development version (v5.3.11-SNAPSHOT) 2021-09-15 07:24:10 +00:00
Stephane Nicoll aa14c24899 Migrate to Spring Builds account 2021-09-15 09:06:44 +02:00
Stephane Nicoll 4c720eaa38 Fix GitHub credentials to use token rather than password
Closes gh-27402
2021-09-15 08:41:10 +02:00
Sam Brannen 2d65bce18e Polish Eclipse IDE support 2021-09-14 21:59:32 +02:00
Juergen Hoeller b8b85a6a59 Defensive handling of dimensions nullability 2021-09-14 21:49:23 +02:00
Juergen Hoeller 3baacedfd9 Alignment with other abstract utils classes 2021-09-14 21:49:12 +02:00
Sam Brannen 4322ee1944 Polish Eclipse IDE support 2021-09-14 21:42:00 +02:00
Sam Brannen 3faf445603 Re-enable import into Eclipse IDE
The migration to Gradle 7.2 resulted in a regression for our Eclipse
IDE support: several projects ended up with recursive classpath entries
in their generated .classpath files which prevent those projects from
being built within Eclipse.

This commit addresses this issue with a solution that may well be a
"hack". Nonetheless, a working hack is better than not being able to
import into Eclipse at all.

See gh-26870
2021-09-14 21:05:57 +02:00
Sam Brannen 9e986c031b Polish ide.gradle 2021-09-14 20:51:59 +02:00
Sam Brannen f07e6a1b9d Support char primitive default values in BeanUtils.instantiateClass()
Closes gh-27390
2021-09-14 16:12:21 +02:00
Sam Brannen 5cc09849ce Introduce test for gh-27390 2021-09-14 16:05:41 +02:00
takeaction21 92cd680a2c Support float and double primitive default values in BeanUtils.instantiateClass()
See gh-27390
2021-09-14 16:05:41 +02:00
Rossen Stoyanchev caf88ff2cc Improve HandlerMethod#bridgedMethod initialization
Ensure makeAccessible is called once when the bridgedMethod is
initialized.

Closes gh-19795
2021-09-14 14:58:11 +01:00
Sam Brannen 813dbbce58 Polish contribution
See gh-27388
2021-09-14 15:06:37 +02:00
Dmitriy Bogdanov c46cc666d6 Fix some typos and mistakes in ref docs
Closes gh-27388
2021-09-14 15:06:19 +02:00
Rossen Stoyanchev 674dc2f203 Do not log request parameters for multipart requests
Closes gh-27350
2021-09-14 13:40:44 +01:00
Brian Clozel 8adf28763b Upgrade to Reactor 2020.0.11
Closes gh-27399
2021-09-14 14:24:47 +02:00
Sam Brannen b1a4d3033b Avoid usage of deprecated Gradle API in spring-oxm.gradle
This upgrade avoids the warning about the following on Gradle 7.1+.

- The SourceDirectorySet.outputDir property has been deprecated.

Closes gh-26870
2021-09-14 11:35:12 +02:00
Sam Brannen 8c14251a1a Upgrade to nohttp 0.0.10
This upgrade avoids warnings about the following on Gradle 7.1+.

- The Report.destination property has been deprecated.
- The JavaExec.main property has been deprecated.

See gh-26870
2021-09-14 11:24:28 +02:00
Sam Brannen 18ee308e4e Delete obsolete Assume test utility 2021-09-14 10:58:38 +02:00
Juergen Hoeller 6540e87ac0 Upgrade to Netty 4.1.68, Jackson 2.12.5, Mockito 3.12.4, MockK 1.12, JsonPath 2.6 2021-09-13 18:14:05 +02:00
Juergen Hoeller 6c17e9375b Reduce log statement for non-unique JavaBean property to debug level
Closes gh-27372
2021-09-13 18:13:41 +02:00
yokotaso 0a776a76d1 Fix memory leak on AOP Proxy class definition cache 2021-09-13 18:08:01 +02:00
Phillip Webb 52b03e3326 Migrate CoroutinesUtils to Java
Migrate `CoroutinesUtils` from Kotlin code to Java and drop the
`kotlin-coroutines` module.

This update removes the need for Kotlin tooling IDE plugins to be
installed.

Closes gh-27379
2021-09-13 17:39:45 +02:00
Sam Brannen d55cbf8b4d Avoid use of deprecated API in aggregateTestReports task
See gh-26870
2021-09-13 16:52:00 +02:00
Sam Brannen 04e6b233ca Upgrade to JUnit 5.8
Closes gh-27392
2021-09-13 16:38:30 +02:00
Mustafa Ulu db424d0bc5 Replace word "request" with "response" 2021-09-13 11:35:21 +01:00
Mustafa Ulu a087d13aea Fix wording in Javadoc of ClientResponse.mutate()
Removed an extra "the".
2021-09-13 11:35:21 +01:00
Brian Clozel c02ae7bcb8 Fix noHttp failure 2021-09-13 10:14:58 +02:00
Brian Clozel ca34d0cce8 Polish Gradle upgrade
Closes gh-26870
2021-09-13 10:06:27 +02:00
Sébastien Deleuze ab41db474e Update dokka to 1.5.0
See gh-26870
2021-09-13 09:40:32 +02:00
Brian Clozel cecc0849a8 Upgrade to Gradle 7.2
This commit upgrades Gradle to 7.2.
Gradle configuration names are updated accordingly.
This also upgrades Gradle build plugins.

See gh-26870
2021-09-13 09:37:35 +02:00
Stephane Nicoll 2db1e6daad Merge pull request #27387 from crlikcngroup
* pr/27387:
  Fix misplaced comma in AOP doc

Closes gh-27387
2021-09-12 08:52:22 +02:00
Radek Crlik 78dd219787 Fix misplaced comma in AOP doc
See gh-27387
2021-09-12 08:52:07 +02:00
Stephane Nicoll bb45a7ae5e Fix bug fix icon in changelog configuration
Closes gh-27384
2021-09-11 00:00:57 +02:00
Sam Brannen c3e424c29a Polishing 2021-09-10 16:01:23 +02:00
Rossen Stoyanchev c23f0cd070 Polishing contribution
See gh-27374
2021-09-10 11:22:01 +01:00
Ruslan Stelmachenko 63ffa710d6 Include all bytes of body in UnknownContentTypeException
HttpMessageConverterExtractor uses MessageBodyClientHttpResponseWrapper
which may read the first byte of the response stream to check if there
is content. After that it is necessary to use the wrapper to get the
full body.

This commit ensures that when UnknownContentTypeException is raised
it gets the body through the wrapper, or otherwise the first byte is
missed if the InputStream is not markable.

Closes gh-27374
2021-09-10 10:42:08 +01:00
Rossen Stoyanchev b6037d0d07 Correctly format class name in default package
Closes gh-27247
2021-09-10 10:38:48 +01:00
Rossen Stoyanchev 41ab268733 Polishing contribution
See gh-27331
2021-09-09 17:00:00 +01:00
hantsy 1dc128361f Add SmallRye Mutiny adapters
Closes gh-26222
2021-09-09 16:43:08 +01:00
Grant Fleming 8f33450df2 Fix typo in core-beans.adoc
Closes gh-27377
2021-09-09 13:26:44 +02:00
Sébastien Deleuze 55b3e064e9 Upgrade to Kotlin 1.5.30
Also upgrades related libraries:
- Coroutines upgraded to 1.5.2
- Serialization upgraded to 1.2.2

Closes gh-27371
2021-09-08 09:32:50 +02:00
Rossen Stoyanchev a3655c4858 Add tip related to user destinations in STOMP
See gh-26986
2021-09-07 16:33:54 +01:00
Sébastien Deleuze 3f66ef7aee Compile with parameter names
Compiled code should contain parameter names to avoid the need
for class resources to be included in native image builds.

Closes gh-27369
2021-09-07 15:08:44 +02:00
Sam Brannen d8191b4808 Polish contribution
See gh-26984
2021-09-07 14:24:57 +02:00
Yin-Jui 417bce8be5 Add tests for MessageBodyClientHttpResponseWrapper
Closes gh-26984
2021-09-07 14:24:57 +02:00
Sam Brannen 19283c9245 Avoid accidental dependency on older version of Byte Buddy
This commit allows Mockito-based tests in spring-test to work again
in Eclipse IDE.

This problem was uncovered while fixing gh-27365
2021-09-07 11:33:32 +02:00
Sam Brannen d7ea4d230f Remove Eclipse-specific code from OptionalDependenciesPlugin
To support the recent changes to our `optional` dependencies plugin,
this commit removes the Eclipse-specific code which no longer appears
to be necessary.

Closes gh-27365
2021-09-07 10:49:48 +02:00
Sam Brannen e7b499f7b6 Upgrade to JMH 1.32 and avoid accidental dependency on jopt-simple 4.6
JMH is now implicitly configured to use jopt-simple 5.0.4 instead of 4.6.

This problem was uncovered while fixing gh-27365
2021-09-07 10:45:44 +02:00
Brian Clozel 77a6dce1b5 Review Servlet API version in Spring OXM tests
This commit ensures that Servlet 4.0+ is used in the Spring OXM test
suite, as Servlet 4 specific APIs are used in the tests.

This problem was uncovered while fixing gh-27365
2021-09-06 19:18:28 +02:00
Andy Wilkinson d23afea168 Extend optional rather than adding it to existing classpath
This allows the attributes configured on compileClasspath and
runtimeClasspath to independently influence the variant selection when
resolving the optional configuration, allowing it to contribute compile
dependencies (JAVA_API) to the former and runtime dependencies
(JAVA_RUNTIME) to the latter.

Fixes gh-27365
2021-09-06 19:18:16 +02:00
Andy Wilkinson 0ec4be37d5 Configure optional configuration to consume its dependencies' API
Previously, the optional configuration had no usage attribute. This
resulted in it using the default, JAVA_RUNTIME, which caused it to
only consume the runtime produced by its dependencies and not the
API. Given that the optional configuration is added to the compile
classpath, this was incorrect.

This commit updates the optional configuration to be configured to
consume the Java API of its dependencies. The configuration has
also been marked as not being for consumption. This prevents other
projects attempting to consume the optional variant of a project
that has the optional dependencies plugin applied and further
aligns it with Gradle's built-in configurations of a similar nature.

See gh-27365
2021-09-06 19:16:57 +02:00
Brian Clozel 532b4b636d Update CI pipeline with JDK16
This commit replaces the JDK15 build with a JDK16 variant.
This also updates the CI image with a new OS version and updated
JDK versions.
2021-09-06 18:13:41 +02:00
Sam Brannen d1a00b4301 Polishing
See gh-27230
2021-09-06 16:58:32 +02:00
Sam Brannen 87d3d1bbd1 Throw UnsupportedOperationException in defaultResponseCharacterEncoding()
This commit updates the defaultResponseCharacterEncoding() `default`
method in ConfigurableMockMvcBuilder so that it throws an
UnsupportedOperationException instead of silently ignoring the user's
request to set the default response character encoding.

Note, however, that AbstractMockMvcBuilder already overrides the
default method with a concrete implementation which is used by default
in MockMvc.

See gh-27230
2021-09-06 16:55:11 +02:00
Rossen Stoyanchev 1b3fd9edff Ensure one time logging for request details
Closes gh-26969
2021-09-06 13:56:54 +01:00
Rossen Stoyanchev 5ea7592d70 Polishing in ExchangeResult 2021-09-06 13:56:54 +01:00
Manish 9cf8cca96d Minor language corrections. 2021-09-06 09:57:35 +01:00
Sam Brannen b2a17a8d86 Fix typo 2021-09-03 18:44:42 +02:00
Rossen Stoyanchev bec0bb0c53 Revert "Add doOnDiscard hook for streaming mode"
This reverts commit 77a562dfee.

As per findings under
https://github.com/reactor/reactor-netty/issues/1746 it looks this
wasn't the issue and isn't required.
2021-09-03 14:32:54 +01:00
Leeseojune 434cbab6a7 Update copyright date in tests in spring-test
Closes gh-27354
2021-09-03 10:50:50 +02:00
Juergen Hoeller b2eaa7c1c3 Polishing 2021-09-02 22:59:33 +02:00
Juergen Hoeller 2f60392fe3 Upgrade to Netty 4.1.67, RxJava 3.1.1, Gson 2.8.8, XStream 1.4.18 2021-09-02 22:22:37 +02:00
Juergen Hoeller b6c2c11805 Polishing 2021-09-02 22:21:27 +02:00
Juergen Hoeller 837301fdb3 Convenient configuration of type permissions for XStream 1.4.18
Closes gh-27343
2021-09-02 22:20:52 +02:00
Juergen Hoeller 164dcef6ae Tracking ASM master
See gh-27069
2021-09-02 22:19:57 +02:00
Sam Brannen 310bdbb1b2 Fix error in ApplicationEvents example 2021-09-01 10:34:16 +02:00
Sam Brannen 88af24c1cb Update copyright date 2021-08-31 09:46:10 +02:00
Inmord 871e378ed0 Polish AbstractAspectJAdvisorFactory
Closes gh-27340
2021-08-31 09:43:54 +02:00
Georgi Ushev e5a5f8b20b Remove unnecessary brace in websocket documenation
Closes gh-#27339
2021-08-31 09:37:29 +02:00
Brian Clozel cc026fcb8a Polish "Optimize allocation in StringUtils#cleanPath"
This commit also introduces JMH benchmarks related to the code
optimizations.

Closes gh-2631
2021-08-30 18:26:51 +02:00
Daniel Knittl-Frank 8d3e8ca3a2 Optimize allocation in StringUtils#cleanPath
This commit applies several optimizations to StringUtils#cleanPath and
related methods:

* pre-size pathElements deque in StringUtils#cleanPath with
  pathElements.length elements, since this this is the maximum size and
  the most likely case.
* optimize StringUtils#collectionToDelimitedString to calculate the size
  of the resulting String and avoid array auto-resizing in the
  StringBuilder.
* If the path did not contain any components that required cleaning,
  return the (normalized) path as-is. No need to concatenate the prefix
  and the trailing path.

See gh-26316
2021-08-30 18:09:52 +02:00
Sam Brannen ae56f2ac09 Polish contribution
See gh-27336
2021-08-30 16:54:16 +02:00
Philippe Marschall debf61b948 Remove unused private loggers
Closes gh-27336
2021-08-30 16:51:59 +02:00
Steve Wei b120e0b8f4 Fix Kotlin example for filtering handler functions
Closes gh-#27337
2021-08-30 16:47:31 +02:00
Sam Brannen c27ec00ae9 Polish scheduling Javadoc 2021-08-26 14:09:23 +02:00
Sam Brannen 9a7fb7022d Fix typo in @Scheduled
See gh-27309
2021-08-26 13:43:48 +02:00
Sam Brannen bd72e4498b Revise and document TimeUnit support in @Scheduled
This commit also fixes a bug introduced in commit e99b43b91e, where
java.time.Duration strings were converted to milliseconds and then
converted again using the configured TimeUnit.

See gh-27309
2021-08-25 20:55:55 +02:00
Axzial e99b43b91e Support TimeUnit in the @Scheduled annotation
This commit introduces a new `timeUnit` attribute in the @Scheduled
annotation to allow the user to specify a time unit other than
milliseconds.

Closes gh-27309
2021-08-25 20:50:37 +02:00
Sam Brannen 3c2dfebf4e Polish soft assertion support for WebTestClient
See gh-26969
2021-08-23 19:09:34 +02:00
Michal Rowicki 25dca40413 Introduce soft assertions for WebTestClient
It happens very often that WebTestClient is used in heavyweight
integration tests, and it's a hindrance to developer productivity to
fix one failed assertion after another. Soft assertions help a lot by
checking all conditions at once even if one of them fails.

This commit introduces a new expectAllSoftly(..) method in
WebTestClient to address this issue.

client.get().uri("/hello")
	.exchange()
	.expectAllSoftly(
		spec -> spec.expectStatus().isOk(),
		spec -> spec.expectBody(String.class).isEqualTo("Hello, World")
	);

Closes gh-26969
2021-08-23 19:09:23 +02:00
Sam Brannen dd9b99e13d Introduce ResultActions.andExpectAll() for soft assertions in MockMvc
Closes gh-26917
2021-08-23 15:27:07 +02:00
Sam Brannen cd078eaad8 Use ExceptionCollector for soft assertions in MockMvc
See gh-26917
2021-08-23 15:22:54 +02:00
Sam Brannen 5f47d3be22 Polish soft assertions for MockMvc
See gh-26917
2021-08-23 15:22:44 +02:00
Michal Rowicki 35bec8102b Introduce soft assertions for MockMvc
It happens very often that MockMvc is used in heavyweight integration
tests. It's no use to waste time to check if another condition has been
fixed or not. Soft assertions help a lot by checking all conditions at
once even if one of them fails.

See gh-26917

Co-authored-by: Sach Nguyen <sachnbbkhn@gmail.com>
2021-08-23 15:22:35 +02:00
Sam Brannen 4c153b80ee Make ExceptionCollector.Executable public
See gh-27316
2021-08-23 11:57:54 +02:00
Sam Brannen 81a6ba42a3 Introduce ExceptionCollector testing utility
This commit introduces a new ExceptionCollector testing utility in order
to support "soft assertion" use cases.

Closes gh-27316
2021-08-23 11:44:25 +02:00
Sam Brannen 8a7c4fc10d Support HtmlFileInput.setData() with HtmlUnit and MockMvc
Prior to this commit, if the user tested file upload support with
HtmlUnit and MockMvc by invoking HtmlFileInput.setData() instead of
HtmlFileInput.setFiles(), the in-memory file data was simply ignored.

This commit addresses this issue by creating a MockPart from the
in-memory data in HtmlUnitRequestBuilder.

Closes gh-27199
2021-08-22 17:44:14 +02:00
Sam Brannen 7da7a976e6 Document when prepareTestInstance() is invoked by the SpringMethodRule
Closes gh-27305
2021-08-22 15:56:58 +02:00
Sam Brannen b28f403bf8 Fix Checkstyle violation
See gh-27303
2021-08-22 14:45:55 +02:00
Sam Brannen 6c71cf2f96 Polishing 2021-08-22 14:27:47 +02:00
Sam Brannen 99970a5ddc Polish contribution
See gh-27303
2021-08-22 14:22:51 +02:00
Erik van Paassen 462e19d417 Fix UrlPathHelper#shouldRemoveSemicolonContent() (#27303)
The checkReadOnly() method should only be called from
methods that modify properties to prevent modification
of read-only instances.

Fixes #27256
2021-08-22 14:10:25 +02:00
Sam Brannen 9f7a94058a Update copyright date
See gh-27298
2021-08-19 16:23:38 +02:00
LEE Juchan caf6760ddd Fix grammatical errors in Javadoc
Closes gh-27298
2021-08-19 16:21:15 +02:00
Stephane Nicoll 4a9c7e631c Merge pull request #27291 from benelog
* pr/27291:
  Polish "Fix duplicate "the" in Javadoc and XSD"
  Fix duplicate "the" in Javadoc and XSD

Closes gh-27291
2021-08-19 08:55:22 +02:00
Stephane Nicoll af6fd6c303 Polish "Fix duplicate "the" in Javadoc and XSD"
See gh-27291
2021-08-19 08:54:38 +02:00
Sanghyuk Jung ac72277258 Fix duplicate "the" in Javadoc and XSD
See gh-27291
2021-08-19 08:44:03 +02:00
Sam Brannen 6770e4b3cc Fix and document CompositeUriComponentsContributor#hasContributors()
Prior to this commit, the hasContributors() method incorrectly returned
false if contributors had been configured.

This commit fixes the logic in hasContributors() and documents it.

Closes #27271
2021-08-18 17:33:50 +02:00
Sam Brannen 6177f00a63 Polish PropertyAccessor tests 2021-08-18 17:10:40 +02:00
Juergen Hoeller 9bdc545a95 Upgrade to Tomcat 9.0.52, Undertow 2.2.10, RxJava 3.1, HtmlUnit 2.52, Checkstyle 8.45.1 2021-08-17 17:19:32 +02:00
Juergen Hoeller 44951873f9 Introduce accessors for allowCircularReferences/allowRawInjectionDespiteWrapping
Closes gh-27289
2021-08-17 17:19:21 +02:00
Rossen Stoyanchev 77a562dfee Add doOnDiscard hook for streaming mode
Potential fix for issue reported at
https://github.com/reactor/reactor-netty/issues/1746
2021-08-12 19:58:50 +01:00
Stephane Nicoll 7b80f4feeb Upgrade to Reactor 2020.0.10
Closes gh-27250
2021-08-12 09:04:39 +02:00
Stephane Nicoll 98f69c51a1 Merge pull request #27260 from joshua-qa
* pr/27260:
  Fix typo in DefaultPartHttpMessageReader

Closes gh-27260
2021-08-11 16:31:01 +02:00
joshua-qa 3a35d79c72 Fix typo in DefaultPartHttpMessageReader
See gh-27260
2021-08-11 16:23:52 +02:00
Stephane Nicoll 451bcfc832 Start building against Reactor 2020.0.10 snapshots
See gh-27250
2021-08-09 10:00:22 +02:00
Stephane Nicoll d4cd9405dd Merge pull request #27248 from Syuziko
* pr/27248:
  Polish contribution
  Polish tests

Closes gh-27248
2021-08-08 11:40:02 +02:00
Stephane Nicoll 31b651a114 Polish contribution
See gh-27248
2021-08-08 11:33:26 +02:00
Syuziko eaf9deedfd Polish tests
See gh-27248
2021-08-07 18:53:47 +02:00
Rossen Stoyanchev ce6217be85 Polishing contribution
Closes gh-27220
2021-08-04 10:32:16 +01:00
Alexej Timonin e290ae285c Improve Javadoc for ClientRequest#from
See gh-27220
2021-08-04 09:21:43 +01:00
Stephane Nicoll 8670b1c3f0 Merge pull request #27238 from izeye
* pr/27238:
  Polish printMvcResultsToWriterWithFailingGlobalResultMatcher()

Closes gh-27238
2021-08-04 08:29:33 +02:00
izeye 86ef0236e6 Polish printMvcResultsToWriterWithFailingGlobalResultMatcher()
See gh-27238
2021-08-04 08:29:26 +02:00
Sam Brannen ce94f69e52 Polish contribution
See gh-27234
2021-07-31 16:30:39 +02:00
Anton Lyxell 01c8de0111 Simplify getInternalBeanFactoryForBean
This commit simplifies getInternalBeanFactoryForBean() in
AbstractBeanFactoryBasedTargetSourceCreator via
Map::computeIfAbsent.

Closes gh-27234
2021-07-31 16:27:43 +02:00
Sam Brannen bd1f5bd9fc Support Charset for character encoding in MockMvc
To improve the developer experience and avoid the use of String
literals, this commit provides overloaded support via Charset for
character encoding in MockHttpServletRequestBuilder and
ContentResultMatchers.

Closes gh-27231
2021-07-30 15:24:47 +02:00
Sam Brannen 4d115eef91 Polishing 2021-07-30 15:20:44 +02:00
Sam Brannen 0f421f9f86 Support default character encoding for response in MockMvc
Commit e4b9b1fadb introduced support for setting the default character
encoding in MockHttpServletResponse.

This commit introduces support for configuring the default character
encoding in the underlying MockHttpServletResponse used in MockMvc.

Closes gh-27230
2021-07-30 14:42:45 +02:00
Sam Brannen 41fa199178 Polish PrintingResultHandler 2021-07-29 19:43:54 +02:00
Sam Brannen 881fa889fc Apply global ResultHandlers before ResultMatchers in MockMvc
Prior to this commit, MockMvc applied global ResultMatchers before
global ResultHandlers. This lead to unexpected scenarios where a
failing matcher would prevent a handler from being applied.

One concrete use case is `alwaysDo(print(System.err))` which should
print out MockMvc results for debugging purposes. However, if MockMvc is
configured with something like `alwaysExpect(content().string("?"))`
and the expectation fails, the user will never see the expected debug
output to help diagnose the problem.

This commit addresses this issue by applying global ResultHandlers
before ResultMatchers in MockMvc.

Closes gh-27225
2021-07-29 19:18:18 +02:00
Sam Brannen e4b9b1fadb Introduce setDefaultCharacterEncoding() in MockHttpServletResponse
Prior to this commit, it was possible to set the character encoding
in MockHttpServletResponse via setCharacterEncoding() or
setContentType(); however, those methods append "charset=..." to the
Content-Type header which may not be an acceptable side effect.

This commit addresses this shortcoming by introducing a new
setDefaultCharacterEncoding() in MockHttpServletResponse which allows
one to override the previously hard coded value of "ISO-8859-1". In
addition, setDefaultCharacterEncoding() does not modify the Content-Type
header.

The reset() method has also been updated to reset the character encoding
to the configured default character encoding.

Closes gh-27214
2021-07-29 16:02:58 +02:00
Rossen Stoyanchev 55e17ef306 Polishing contribution
Closes gh-27203
2021-07-29 14:49:02 +01:00
Yanming Zhou f2be4e9320 Use MessageSource for @ExceptionHandler methods
Follow-up for commit bb816c123c

See gh-27203
2021-07-29 14:49:02 +01:00
Sam Brannen 5b3f11c543 Add @Nullable to setLocale in MockHttpServletResponse
See gh-26493
2021-07-29 14:47:31 +02:00
Sam Brannen 96ee8a3bc7 Ensure characterEncoding in MockHttpServletResponse is non-null
Closes gh-27219
2021-07-29 14:40:01 +02:00
Sam Brannen 915f1027a5 Update copyright date
See gh-27223
2021-07-29 11:04:59 +02:00
Mateusz Swiatkowski f1b35f1593 Fix reference to Optional.isPresent() in ObjectUtils.isEmpty()
Closes gh-27223
2021-07-29 11:03:26 +02:00
DongHyuk c2f91765b4 Fix typo in Javadoc in AbstractHandlerMapping
Closes gh-27218
2021-07-28 15:19:59 +02:00
Sam Brannen 403e04c0b4 Polish MockHttpServletResponse 2021-07-28 11:27:56 +02:00
Rossen Stoyanchev 6c68419073 Polishing contribution
Closes gh-27216
2021-07-27 17:41:30 +01:00
Moncef AOUDIA a747cc3e91 Fix error message in SynchronossPartHttpMessageReader 2021-07-27 17:25:30 +01:00
Sam Brannen 161c9dc3bd Improve @Cacheable documentation regarding java.util.Optional
This commit improves the documentation for @Cacheable to point out that
`null` will be stored in the cache for an empty `Optional` return value.

Closes gh-27184
2021-07-27 15:05:43 +02:00
Sam Brannen 42edef0bcc Avoid StringIndexOutOfBoundsException in WebSocketMessageBrokerStats
Prior to this commit, if the TaskExecutor configured in
WebSocketMessageBrokerStats for the inboundChannelExecutor or
outboundChannelExecutor was not a ThreadPoolTaskExecutor, a
StringIndexOutOfBoundsException was thrown when attempting to parse the
results of invoking toString() on the executor.

The reason is that ThreadPoolTaskExecutor delegates to a
ThreadPoolExecutor whose toString() implementation generates text
containing "pool size = ...", and WebSocketMessageBrokerStats'
getExecutorStatsInfo() method relied on the presence of "pool" in the
text returned from toString().

This commit fixes this bug by ensuring that the text returned from
toString() contains "pool" before parsing the text. If "pool" is not
present in the text, getExecutorStatsInfo() now returns "unknown"
instead of throwing a StringIndexOutOfBoundsException.

Closes gh-27209
2021-07-25 19:05:02 +02:00
Sam Brannen e94811f1b9 Polish WebSocketMessageBrokerConfigurationSupportTests 2021-07-24 21:45:31 +03:00
Rossen Stoyanchev d034a1f26d Blockhound rule for MediaTypeFactory static initializer
Closes gh-26631
2021-07-23 17:01:28 +01:00
Rossen Stoyanchev 460947651a Minor refactoring in DefaultPathContainer
Closes gh-27204
2021-07-23 16:53:54 +01:00
Juergen Hoeller af67764edb Upgrade to Netty 4.1.66 and Undertow 2.2.9 2021-07-23 12:20:10 +02:00
Juergen Hoeller ba08006d52 ObjectMapper.configure(MapperFeature, boolean) is deprecated as of Jackson 2.13
Closes gh-27206
2021-07-23 12:19:35 +02:00
Juergen Hoeller 2594f4e058 Avoid unnecessary cause initialization in ResponseStatusException
Closes gh-27196
2021-07-23 12:18:15 +02:00
Sam Brannen 9c0825629b Reintroduce left-hand side navigation in ref docs
A side effect of 71995a9087 caused the
dynamic table of contents in the left-hand side navigation to no longer
be displayed, likely due to the missing "details" DIV.

This commit addresses this issue by applying the custom header only to
index.adoc.

Consequently, the TOC is now displayed again on all pages except the
index page, but the customized header is no longer applied to those
pages.

We may revisit this issue if we decide that we want the custom header
on all pages (and not just the index page).

Closes gh-27177
2021-07-17 17:53:43 +03:00
Sam Brannen e0c0e7f878 Fix typo in ref docs 2021-07-17 17:03:51 +03:00
Rossen Stoyanchev 0b1d14cdd9 Follow-up fix, checking also "ws" and port 80 case
See gh-27097
2021-07-16 09:34:12 +01:00
Spring Buildmaster ca262eaa1c Next development version (v5.3.10-SNAPSHOT) 2021-07-14 06:48:14 +00:00
Rossen Stoyanchev bb816c123c Use MessageSource in HandlerMethod for error reason
Closes gh-27156
2021-07-13 19:38:58 +01:00
Juergen Hoeller 33f3aa9b8a Upgrade to AspectJ 1.9.7 and EclipseLink 2.7.9 2021-07-13 18:29:34 +02:00
Rossen Stoyanchev e1f51cbce7 Check both https and wss in forwarded header checks
Closes gh-27097
2021-07-13 16:32:12 +01:00
Stephane Nicoll 6ec7cffc93 Upgrade to Kotlin 1.5.21
Closes gh-27110
2021-07-13 14:55:25 +02:00
Stephane Nicoll 4bc6f40ce8 Upgrade to Reactor 2020.0.9
Closes gh-27158
2021-07-13 14:29:59 +02:00
Arjen Poutsma bf2790498b Document ResourceBundle limitations
This commit adds a note to the documentation saying that ResourceBundle
does not support multiple bundles with the same base name.

Closes gh-27038
2021-07-13 13:45:03 +02:00
Rossen Stoyanchev 95d7f883ae Deprecate LastModified
See gh-27075
2021-07-13 12:11:20 +01:00
Rossen Stoyanchev 25131ebf6f Resource handler initialized only once
Closes gh-27153
2021-07-13 11:44:06 +01:00
Rossen Stoyanchev 0267b00a65 Minor update to Javadoc for HandlerInterceptor#postHandle
Closes gh-27122
2021-07-13 08:44:54 +01:00
Stephane Nicoll c6e644e5c3 Polish "Downcast to InetSocketAddress for Jetty 10"
This commit uses the target type where getRemoteAddress and
getLocalAddress are defined.

See gh-27120
2021-07-13 09:38:37 +02:00
Juergen Hoeller 62e916534f Introduce remaining policy setters from ScheduledThreadPoolExecutor
Closes gh-26719
2021-07-13 09:27:48 +02:00
Juergen Hoeller e1c0f3b067 CommonsMultipartResolver supports configurable HTTP methods
Closes gh-27161
2021-07-12 23:19:08 +02:00
Juergen Hoeller 1ff8da3635 StandardServletMultipartResolver provides strict Servlet compliance option
Closes gh-26826
2021-07-12 23:18:54 +02:00
Juergen Hoeller ed27ea7aa0 Restrict fallback multipart binding to POST requests with multipart/form-data
Closes gh-26999
See gh-26826
2021-07-12 17:55:49 +02:00
Juergen Hoeller 128689e79b Use entrySet iterator in getBodyFromServletRequestParameters
Closes gh-27081
2021-07-12 17:43:19 +02:00
Juergen Hoeller 475396b516 Exclude sealed interfaces from auto-proxying (for JDK 17 compatibility)
Closes gh-27027
2021-07-12 17:42:15 +02:00
Sviatoslav Hryb f3f0bd22c5 Fix content negotiation description 2021-07-12 15:23:35 +01:00
Rossen Stoyanchev 6d01d49b76 Downcast to InetSocketAddress for Jetty 10
Closes gh-27120
2021-07-12 15:04:14 +01:00
Stephane Nicoll a90ed957be Support ResolvableType in BeanDefinitionBuilder
Closes gh-27160
2021-07-12 14:07:25 +02:00
Stephane Nicoll 171b283e49 Start building against Reactor 2020.0.9 snapshots
See gh-27158
2021-07-12 09:36:50 +02:00
Stephane Nicoll 71202d62ed Upgrade to Kotlin Coroutines 1.5.1
Closes gh-27157
2021-07-12 09:11:44 +02:00
Stephane Nicoll ded9c4eb50 Merge pull request #27155 from izeye
* pr/27155:
  Add Javadoc since to BeanDefinitionBuilder.setSynthetic()

Closes gh-27155
2021-07-12 08:22:21 +02:00
Johnny Lim 925edf28fc Add Javadoc since to BeanDefinitionBuilder.setSynthetic()
See gh-27155
2021-07-12 08:22:09 +02:00
Stephane Nicoll 75d4465908 Merge pull request #27151 from HubertWo
* pr/27151:
  Fix link to Javadoc API
  Fix link to Javadoc API

Closes gh-27151
2021-07-11 09:10:17 +02:00
Stephane Nicoll 98685e8be7 Fix link to Javadoc API
See gh-27151
2021-07-11 09:09:46 +02:00
Hubert Wo e719bc2cda Fix link to Javadoc API
See gh-27151
2021-07-11 09:05:20 +02:00
Rossen Stoyanchev f9167c3df5 Improve Javadoc of ContentCachingRequestWrapper
Closes gh-27068
2021-07-09 20:34:22 +01:00
Rossen Stoyanchev fbf4724d78 Replace Jetty 9 only constant with explicit value
Closes gh-27121
2021-07-09 20:16:58 +01:00
Rossen Stoyanchev 39442143b7 Fix and improve docs on {*var} pattern
Closes gh-27132
2021-07-09 20:09:06 +01:00
Juergen Hoeller d3b1c4f62b Code alignment between ThreadPoolTaskExecutor and ThreadPoolTaskScheduler
See gh-26700
2021-07-09 15:19:25 +02:00
Filip Hrisafov 531174258c Apply dynamic changes in ThreadPoolTaskExecutor before setting local value
If the ThreadPoolTaskExecutor is dynamically changed with an invalid value
the state of the ThreadPoolTaskExecutor does no longer correctly represent
the state of the underlying ThreadPoolExecutor
2021-07-09 15:10:55 +02:00
diguage 564c6f7f86 improve the performance of iteration 2021-07-09 15:10:18 +02:00
Juergen Hoeller a07c7865a5 Lazy initialization of transaction UUID (with deprecated getter methods)
Includes removal of trace logging for individual synchronization steps.

Closes gh-26955
2021-07-09 15:07:30 +02:00
Juergen Hoeller 8680fdb8bc Polishing 2021-07-09 13:26:46 +02:00
Juergen Hoeller 4fe3ca1b82 DataClassRowMapper suppresses setter method calls for constructor-bound properties
Closes gh-26569
2021-07-09 13:26:39 +02:00
Juergen Hoeller c45c46dad7 Make proxyTargetClass=true with introduction advice work for JDK proxy targets
Closes gh-27044
2021-07-09 13:23:04 +02:00
Juergen Hoeller 74f91339e2 BeanCreationException message includes declaring class of constructor/factory method
Closes gh-27139
2021-07-09 13:22:50 +02:00
Juergen Hoeller acb2aec3dd Compatibility with HtmlUnit 2.51
Includes upgrade to Tomcat 9.0.50, Jetty 9.4.43, Jackson 2.12.4.

Closes gh-27147
2021-07-09 13:22:34 +02:00
Arjen Poutsma 297880d93e Reinstate abortOnCancel in JettyClientHttpRequest
This commit reinstates abortOnCancel in the ReactiveRequest builder,
which allows a cancel signal to abort the request.

See gh-26287 and gh-27112
2021-07-09 10:58:58 +02:00
Arjen Poutsma 9cbb5af622 Support request/response wrappers in JettyHttpHandlerAdapter
This commit makes JettyServerHttpRequest aware of
HttpServletRequestWrapper, and JettyServerHttpResponse aware of
HttpServletResponseWrapper.

Closes gh-27146
2021-07-08 16:39:35 +02:00
Stephane Nicoll fed1a426b6 Improve BeanDefinitionBuilder to handle the synthetic flag
Closes gh-27141
2021-07-07 16:13:19 +02:00
Stephane Nicoll cf78895ba0 Polish 2021-07-07 16:11:48 +02:00
Arjen Poutsma b9d65eef61 Dropping accidentally inserted copyright notice 2021-07-07 13:54:07 +02:00
Arjen Poutsma 8d747298de Fixing the build 2021-07-07 13:49:10 +02:00
Arjen Poutsma 76b1c0f1fc Various bug fixes in CronExpression
This commit makes various bug fixes in CronExpression and related files.

Closes gh-27136
2021-07-07 10:56:07 +02:00
Arjen Poutsma 94f56a2684 Improve Jetty 10 check on client-side
Before this commit, JettyClientHttpResponse checked for the presence of
a server-side class to determine whether it is running on Jetty 10.
Unfortunately, that class is not necessarily present when just using the
Jetty client.

This commit improves the Jetty 10 check, so that it also works when
the Jetty client is used without the server.

Closes gh-27136
2021-07-06 11:04:06 +02:00
Arjen Poutsma cb251347c3 Do not use internal API in JettyClientHttpConnector
This commit makes sure that we no longer use the internal API in the
Jetty support for the WebClient. With this change, we are able to
support both Jetty 9, 10, and 11.

Closes gh-27112
2021-07-06 11:04:06 +02:00
Stephane Nicoll 048954dc1d Merge pull request #27102 from diguage
* pr/27102:
  Update copyright year of changed file
  Simplify Comparator using method references

Closes gh-27102
2021-07-02 08:12:29 +02:00
Stephane Nicoll 403e1f2505 Update copyright year of changed file
See gh-27102
2021-07-02 08:11:41 +02:00
diguage f39c6d36c7 Simplify Comparator using method references
See gh-27102
2021-07-02 08:10:22 +02:00
Stephane Nicoll 83bcd409fc Merge pull request #27101 from diguage
* pr/27101:
  Update copyright year of changed file
  Delete unnecessary variable

Closes gh-27101
2021-07-02 08:09:37 +02:00
Stephane Nicoll 411745f4cb Update copyright year of changed file
See gh-27101
2021-07-02 08:09:07 +02:00
diguage 01df63b9cd Delete unnecessary variable
See gh-27101
2021-07-02 08:07:49 +02:00
Stephane Nicoll bde622880d Merge pull request #27113 from devorio
* pr/27113:
  Fix typo in core-beans.adoc

Closes gh-27113
2021-06-30 20:28:52 +02:00
devorio 6427a4b5c0 Fix typo in core-beans.adoc
See gh-27113
2021-06-30 20:27:55 +02:00
Sébastien Deleuze 66848cfd59 Revert "Upgrade to Kotlin 1.5.20"
This reverts commit d6df4a6577 because running
gradle generatePomFileForMavenJavaPublication throws a
kotlin.KotlinNullPointerException error with Kotlin 1.5.20.
2021-06-30 11:40:44 +02:00
Sébastien Deleuze 4863b5d4a8 Revert Mockito to 3.11.0
Revert Mockito upgrade done in 5d919dc094 because
Byte Buddy transitive upgrade from 1.11.1 to 1.11.3 seems to break Mockk tests
with java.security.AccessControlException related errors, so probably
better to wait Mockito using Byte buddy 1.11.5+ which seems to refine
this area, see https://github.com/raphw/byte-buddy/releases/tag/byte-buddy-1.11.5.
2021-06-30 11:05:31 +02:00
Sébastien Deleuze d6df4a6577 Upgrade to Kotlin 1.5.20
Closes gh-27110
2021-06-30 11:05:31 +02:00
Sébastien Deleuze dee0108e79 Upgrade to Mockk 1.11.0
Closes gh-27109
2021-06-30 11:05:31 +02:00
Sam Brannen 3ccbf1edeb Increase fudge factor in StopWatchTests 2021-06-30 10:43:52 +02:00
Stephane Nicoll 7f6f184acb Merge pull request #27105 from takumi34
* pr/27105:
  Update copyright year of changed file
  Fix typo in BeanDefinitionDsl.kt

Closes gh-27105
2021-06-29 19:28:16 +02:00
Stephane Nicoll b0f724a597 Update copyright year of changed file
See gh-27105
2021-06-29 19:27:57 +02:00
takumi34 9add04f800 Fix typo in BeanDefinitionDsl.kt
See gh-27105
2021-06-29 19:27:29 +02:00
Juergen Hoeller 5d919dc094 Upgrade to Tomcat 9.0.48, Jetty 9.4.42, Jetty Reactive HttpClient 1.1.9, JRuby 9.2.19, Protobuf 3.17.3, SnakeYAML 1.29, WebJars Locator 0.47, AssertJ 3.20.2, Mockito 3.11.2, Checkstyle 8.44 2021-06-28 14:25:55 +02:00
Sam Brannen a2ef6badc4 Use StringBuilder.append(char) where possible
To slightly improve performance, this commit switches to
StringBuilder.append(char) instead of StringBuilder.append(String)
whenever we append a single character to a StringBuilder.

Closes gh-27098
2021-06-25 10:44:28 +02:00
Sam Brannen ddbb7c1b5b Avoid use of Supplier in MergedAnnotationReadingVisitor.get 2021-06-24 16:41:28 +02:00
Sam Brannen 2bc7a3aa0a Implement equals, hashCode, & toString in BeanMethod and *Metadata types
Prior to this commit, ConfigurationClass implemented equals(),
hashCode(), and toString(), but BeanMethod did not.

This commit introduces equals(), hashCode(), and toString()
implementations in BeanMethod for consistency with ConfigurationClass
to make it possible to use BeanMethod instances to index additional
metadata as well.

In order to properly implement equals() in BeanMethod, the method
argument types are required, but these are not directly available in
BeanMethod. However, they are available via ASM when processing @Bean
methods. This commit therefore implements equals(), hashCode(), and
toString() in SimpleMethodMetadata which BeanMethod delegates to.

For completeness, this commit also implements equals(), hashCode(), and
toString() in StandardClassMetadata, StandardMethodMetadata, and
SimpleAnnotationMetadata.

Closes gh-27076
2021-06-24 16:41:28 +02:00
Sam Brannen 882004fc9b Fix bug in SimpleMethodMetadataReadingVisitor.Source.toString()
Prior to this commit, the toString() implementation did not separate
method argument types with a comma or any form of separator, leading
to results such as:

    org.example.MyClass.myMethod(java.lang.Stringjava.lang.Integer)

instead of:

    org.example.MyClass.myMethod(java.lang.String,java.lang.Integer)

Closes gh-27095
2021-06-24 16:41:28 +02:00
Sam Brannen 1bc236785c Polishing 2021-06-24 15:47:24 +02:00
Rossen Stoyanchev 300fed97c1 Upgrade to Reactor 2020.0.8 2021-06-23 15:34:24 +01:00
Arjen Poutsma 4f770ca860 Synchronoss should create temp directory lazily
The SynchronossPartHttpMessageReader should only create temp directory
when needed, not at startup.

Closes gh-27092
2021-06-23 15:59:46 +02:00
Sam Brannen d469f6215d Polishing 2021-06-22 19:54:05 +02:00
Sam Brannen 3214786757 Define global Asciidoc attributes once
This commit defines the doc-root and api-spring-framework attributes
once in docs.gradle instead of duplicating them in each *.adoc file.

This commit also introduces a new docs-spring-framework global
attribute.
2021-06-22 18:39:33 +02:00
Juergen Hoeller f69152c14e Add javadoc reference to MultipartFile.getResource()
See gh-27089
2021-06-22 15:27:19 +02:00
Juergen Hoeller 4bb88f3b1d Remove logging dependency in BeanUtils
Closes gh-27070
2021-06-22 15:26:48 +02:00
Juergen Hoeller edf0343cfe Upgrade to ASM master (including early support for Java 18 bytecode)
Closes gh-27069
2021-06-22 15:26:35 +02:00
Rossen Stoyanchev eb964542b4 Add doc-root to index.adoc
See gh-27015
2021-06-21 18:09:53 +01:00
Sam Brannen 4e8828dc10 Suppress warnings in ServletAnnotationControllerHandlerMethodTests 2021-06-21 18:55:52 +02:00
Sam Brannen a8102e6a41 Delete unused code in ConfigurationMethod 2021-06-21 18:31:43 +02:00
Sam Brannen 782d7169e4 Polish Javadoc for MethodMetadata 2021-06-21 18:04:37 +02:00
Sam Brannen 71995a9087 Introduce custom header for HTML5 ref docs
This commit disables the automatic header generation from Asciidoc's
default template and replaces it with a custom header that omits the
"Version" label before the revision number. The revision number is also
displayed in a simple span tag in order to reduce the amount of
vertical space taken by the header.
2021-06-21 17:52:18 +02:00
Rossen Stoyanchev f9bcb99040 Minor layout refactoring of index asciidoc page
Closes gh-27015
2021-06-21 16:19:17 +01:00
Jay Bryant 791134c53c Link the HTML to the PDF docs and vice-versa
See gh-27015
2021-06-21 16:19:08 +01:00
Sam Brannen df588e030f Avoid duplicated documentation of validation annotations
See gh-27042, gh-27043, gh-27050
2021-06-15 17:30:41 +02:00
Sam Brannen b677206159 Polish Javadoc 2021-06-15 17:22:11 +02:00
Sviatoslav Hryb e04ca3d671 Improve RequestPartMethodArgumentResolver Javadoc
Closes gh-27043
2021-06-15 17:06:53 +02:00
Sviatoslav Hryb 2fc47d8752 Improve RequestResponseBodyMethodProcessor Javadoc
Closes gh-27042
2021-06-15 17:04:18 +02:00
Sam Brannen 3676084472 Ensure DefaultPathSegment does not allow parameters to be mutated
Prior to this commit, if a PathContainer was created using
Options.MESSAGE_ROUTE, DefaultPathSegment#parameters() returned a
mutable map which would allow the user to modify the contents of the
static, shared EMPTY_PARAMS map in DefaultPathContainer.

This commit prevents corruption of the shared EMPTY_PARAMS map by
ensuring that parameters stored in DefaultPathSegment are always
immutable.

Closes gh-27064
2021-06-15 15:16:20 +02:00
Sam Brannen bcb0580492 Polish DefaultPathContainerTests 2021-06-15 13:35:45 +02:00
duan847 3c8074b669 Fix assertion in XmlBeanFactoryTests
Closes gh-27058
2021-06-14 18:49:55 +02:00
Vasiliy Kudriavtsev 4a13928a27 Avoid creating unnessary wrapper for empty map 2021-06-11 16:36:04 +01:00
Rossen Stoyanchev 20d9a1e844 Upgrade to RSocket 1.1.1 2021-06-09 11:01:53 +01:00
Spring Buildmaster 8b1302bbe2 Next development version (v5.3.9-SNAPSHOT) 2021-06-09 07:50:04 +00:00
Brian Clozel c7c35aff42 Fix missing attribute in reference documentation
This commit adds the missing `spring-framework-main-code` asciidoctor
attribute in the reference documentation.

Fixes gh-27041
2021-06-09 09:21:28 +02:00
Sam Brannen 000b6a7e95 Polish @ResponseStatus javadoc and StatusAssertionTests 2021-06-08 18:55:05 +02:00
Sam Brannen f3db6b996d Polish contribution
See gh-27031
2021-06-08 18:55:05 +02:00
Rossen Stoyanchev a42540e64a Multipart writer detects custom Jackson encoder
Closes gh-27017
2021-06-08 17:41:04 +01:00
Rossen Stoyanchev cc2b980e5c Update MockMvc default for suffixPattern matching
Closes gh-27030
2021-06-08 17:41:04 +01:00
Sviatoslav Hryb aa2bfd4b62 Document that class-level @ResponseStatus is inherited by @ExceptionHandler methods
Closes gh-27031
2021-06-08 18:39:18 +02:00
Sam Brannen 29fa9c1728 Polish contribution
See gh-27034
2021-06-08 17:52:07 +02:00
Beca-se 39660710f6 Cross-ref additional *Aware APIs in BeanFactory Javadoc
Closes gh-27034
2021-06-08 17:47:47 +02:00
Brian Clozel e35fe33b72 Revisit fix for gh-26905 in UriComponentsBuilder
This commit revisits the recently updated `PORT_PATTERN` in
`UriComponentsBuilder`. The fix introduced in gh-26905 fails with
ambiguous URL patterns, especially when the port and path parts of the
pattern are hard to differentiate, for example
"https://localhost:{port}{path}".

This commit reinstates the previous behavior without undoing the actual
fix. The only limitation introduced here is the fact that only a single
pattern variable is allowed for the port pattern part.

Fixes gh-27039
2021-06-08 15:26:13 +02:00
Juergen Hoeller 23f396a231 Nullability refinements 2021-06-08 14:23:06 +02:00
izeye 090e394fb5 Clean up @SuppressWarnings("ConstantConditions") 2021-06-08 13:47:00 +02:00
Sviatoslav Hryb 708e61a7ef Fix WebMvcConfigurationSupport javadoc 2021-06-08 12:50:22 +02:00
Gabriel e24b2e6b5d Add awaitExchangeOrNull extension function to reactive webclient
Closes gh-26778
2021-06-08 12:06:53 +02:00
Sébastien Deleuze aff0d8efe7 Upgrade to Kotlin Serialization 1.2.1 2021-06-08 11:44:03 +02:00
Sébastien Deleuze e3e4e49319 Upgrade to Kotlin 1.5.10
Closes gh-27035
2021-06-08 11:44:03 +02:00
Sébastien Deleuze 5420d7113b Polish Kotlin reference documentation 2021-06-08 11:44:03 +02:00
Sébastien Deleuze 6251222a23 Remove jackson-module-kotlin warning
Closes gh-26962
2021-06-08 11:44:03 +02:00
Brian Clozel 05eca05671 Close resources in HttpComponents client connector
Prior to this commit, the `HttpComponentsClientHttpConnector`
implementation could accept or create a default `HttpClient` instance
but not expose it as part of its API. This effectively prevents
applications from properly closing the associated resources when
disposing of the connector.

This commit implements the `Closeable` interface on the connector to
allow this use case.

Closes gh-27032
2021-06-08 11:22:30 +02:00
izeye 3fa4e4168d Remove redundant Collections.unmodifiableList() 2021-06-08 10:39:23 +02:00
Sam Brannen f0f450a18d Polishing 2021-06-07 13:24:46 +02:00
Juergen Hoeller f854803e18 Upgrade to Hibernate ORM 5.4.32, RxJava 3.0.13, Aalto 1.3, Gson 2.8.7, Protobuf 3.17.2, XStream 1.4.17, ActiveMQ 5.16.2, HSQLDB 2.5.2, JRuby 9.2.17, Mockito 3.11, HtmlUnit 2.50, Checkstyle 8.43 2021-06-07 12:28:38 +02:00
Juergen Hoeller d29d4d45aa Upgrade to ASM master
Closes gh-27023
2021-06-07 12:28:17 +02:00
Sam Brannen 432fdad7d0 Polish contribution
See gh-26982
2021-06-04 15:32:29 +02:00
nhavuong 345d8186d4 Add more test cases for SimpleAliasRegistry
Closes gh-26982
2021-06-04 15:18:46 +02:00
Sam Brannen ad63a534cb Polish @CookieValue Javadoc 2021-06-04 15:14:42 +02:00
Сергей Цыпанов c9d341e9c0 Simplify String construction in StringUtils.changeFirstCharacterCase()
Closes gh-27012
2021-06-04 11:49:59 +02:00
Angel Aguilera 950b183715 Adjust expected IdentityHashMap sizes in ClassUtils
Proposed change aimed to keep coherence between variable declaration 
and static initialization code, which stores 9 values, not 8, in these
two maps.

Closes gh-27016
2021-06-04 10:48:44 +02:00
Rossen Stoyanchev 821ecb4cfd Update Javadoc for CookieValue
See gh-26989
2021-06-02 17:28:28 +01:00
Rossen Stoyanchev 1c17305d7b Check for null in allowedOrigin list
Closes gh-26987
2021-06-02 17:14:28 +01:00
jbotuck 491d1c4c78 issue-26994 add missing ) to kotlin example 2021-06-02 12:51:37 +01:00
Brian Clozel 7dbbf364f7 Make FlightRecorderApplicationStartup thread safe
Prior to this commit, in some cases application context startup steps
could be created concurrently, which could cause issues with the current
implementation tracking the parent/child relationship between steps.

This commit ensures that the flight recorder implementation is using
thread safe collection implementations for that.

Fixes gh-26941
2021-06-01 15:11:23 +02:00
Brian Clozel 5204d736f3 Return static DefaultApplicationStartup step
This commit ensures that `DefaultApplicationStartup` returns a static
step for each call to avoid allocations.

Closes gh-26939
2021-06-01 15:06:19 +02:00
Sam Brannen e0690335fc Polish Javadoc in spring-context-indexer 2021-05-31 16:24:09 +02:00
Arjen Poutsma 5cbbbed377 Use given name in MultipartBodyBuilder::part
Make sure that we use the parameter name in MultipartBodyBuilder::part
when adding a Part, instead of using the name specified in the
'Content-Disposition' header that might have been in the part's headers.

Closes gh-27007
2021-05-31 15:17:12 +02:00
Arjen Poutsma 6f2fe5ddcb (Re)introduce CronExpression::isValidExpression
This commit introduces CronExpression::isValidExpression, which was also
present on the deprecated CronSequenceGenerator.

Closes: gh-26996
2021-05-31 14:28:55 +02:00
Sam Brannen da9ee06e05 Improve @Transactional docs regarding method visibility
Closes gh-27003
2021-05-30 17:10:01 +02:00
Sviatoslav Hryb 4c28266eb6 Fix @Transactional docs regarding method visibility
Closes gh-27001
2021-05-30 13:48:31 +02:00
Juergen Hoeller b3dcb64ff1 Generic bean type resolution for lookup methods
Closes gh-26998
2021-05-28 17:23:52 +02:00
Juergen Hoeller b18f8771c8 Upgrade to R2DBC Arabba-SR10, Netty 4.1.65, Undertow 2.2.8, Jetty 9.4.41, Jetty Reactive HttpClient 1.1.8, Apache HttpClient 5.1 2021-05-28 14:31:15 +02:00
Stephane Nicoll 93244e9f9d Merge pull request #26980 from hunjipo
* pr/26980:
  Fix typo in code example

Closes gh-26980
2021-05-27 08:43:41 +02:00
hunjipo f45a852aca Fix typo in code example
See gh-26980
2021-05-27 08:37:44 +02:00
Arjen Poutsma 4203e90655 Fix CronExpression roll-forward issue
This commit makes sure that BitsCronField rolls the date forward in
cases where we cannot find a next bit to elapse to.

Closes: gh-26964
2021-05-26 16:46:15 +02:00
Sam Brannen 1e2e114e3c Polish contribution
See gh-26871
2021-05-26 14:46:32 +02:00
Michael Edwards 0e73213144 Add ApplicationEvent constructor for specifying timestamp
Closes gh-26871
2021-05-26 14:32:41 +02:00
Sam Brannen 1e1045ba42 Doc tx semantics for @TransactionalEventListener after completion phases
This commit improves the Javadoc regarding transactional semantics for
@TransactionalEventListener methods invoked in the AFTER_COMMIT,
AFTER_ROLLBACK, or AFTER_COMPLETION phase. Specifically, the
documentation now points out that interactions with the underlying
transactional resource will not be committed in those phases.

Closes gh-26974
2021-05-26 14:21:08 +02:00
Rossen Stoyanchev 8d17bcea5b Validate top-level SockJS URL
Closes gh-26933
2021-05-26 11:26:02 +01:00
Stephane Nicoll 597b31b1fc Merge pull request #26973 from dregimbal
* pr/26973:
  Update copyright year of changed file
  Fix typo

Closes gh-26973
2021-05-26 08:50:38 +02:00
Stephane Nicoll 4049951c03 Update copyright year of changed file
See gh-26973
2021-05-26 08:50:15 +02:00
Dillon Regimbal 89441ea006 Fix typo
See gh-26973
2021-05-26 08:49:48 +02:00
Rossen Stoyanchev de1ba79c55 Switch to non-blocking thread after WebSession creation
See gh-26958
2021-05-24 16:27:56 +01:00
Sam Brannen ffbc537835 Polish ConcurrentBeanWrapperTests 2021-05-23 18:50:50 +02:00
Elvys Soares 9295bcc4a4 Refactor ConcurrentBeanWrapperTests to use @RepeatedTest
Closes gh-26968
2021-05-23 18:40:36 +02:00
Sam Brannen 746b1b2fe1 Polishing 2021-05-23 18:27:31 +02:00
izeye ab2c78a9d5 Fix broken Javadoc tags
Closes gh-26967
2021-05-23 18:09:34 +02:00
Brian Clozel ac0e71745b Set best matching pattern attribute in WebMvc.fn
Prior to this commit, the `RouterFunctionMapping` WebFlux.fn variant
would set the `HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE` as an
exchange attribute. This is useful for instrumentation purposes.
The WebMvc.fn variant would not do the same; this would lead to
"UNKNOWN" path metrics tags.

This commit ensures that the `RouterFunctionMapping` WebMvc.fn variant
does set the `BEST_MATCHING_PATTERN_ATTRIBUTE` and
`BEST_MATCHING_HANDLER_ATTRIBUTE` request attributes.

Closes gh-26963
2021-05-21 11:54:06 +02:00
izeye f65cbe0992 Polish PORT_PATTERN in UriComponentsBuilder 2021-05-20 18:20:57 +01:00
Johnny Lim a2e5d9a14f Polishing
Closes gh-26960
2021-05-20 15:49:13 +02:00
Christoph Dreis 360f555e77 Introduce ResponseEntity.internalServerError()
Closes gh-26952
2021-05-18 16:57:20 +02:00
Sam Brannen 7c756027a0 Deprecate internal APIs in ScriptUtils in spring-jdbc
Many of the utility methods in ScriptUtils are public only because they
were once invoked from JdbdTestUtils in spring-test, which is no longer
the case. Consequently, there should no longer be a need for any
external clients to invoke such methods.

To address this, this commit formally deprecates the following methods
in ScriptUtils in spring-jdbc.

- readScript(...)
- containsSqlScriptDelimiters(...)
- splitSqlScript(...)

Closes gh-26947
2021-05-18 15:43:54 +02:00
Sam Brannen 4c642ccdcd Logically reorganize methods in ScriptUtils
See gh-26947
2021-05-18 14:56:49 +02:00
Sam Brannen fab7b1cebe Polish ScriptUtils internals in spring-r2dbc
See gh-26947
2021-05-18 14:29:18 +02:00
Rossen Stoyanchev 101ed17b6f Polishing contribution
Closes gh-26927
2021-05-17 17:28:16 +01:00
Ruslan Akhundov 66588bae92 CorsConfiguration supports port pattern and port lists
See gh-26927
2021-05-17 17:28:16 +01:00
Sam Brannen d33545bdce Avoid duplicate comment processing in ScriptUtils in spring-r2dbc
See gh-26947
2021-05-17 13:15:44 +02:00
Sam Brannen e8e157ebf8 Polish ScriptUtils in spring-r2dbc 2021-05-17 12:49:46 +02:00
Sam Brannen 7f5904c68b Remove internal APIs from ScriptUtils in spring-r2dbc
Prior to this commit, many of the utility methods in ScriptUtils in
spring-r2dbc were public by accident: they were copied from ScriptUtils
in spring-jdbc without changing the visibility when spring-r2dbc was
introduced in Spring Framework. 5.3 GA.

This commit corrects this mistake by removing internal APIs from
ScriptUtils in spring-r2dbc from the public contract.

See gh-26947
2021-05-17 12:15:30 +02:00
Sam Brannen 66e488850b Ignore comments when searching for statement delimiter in ScriptUtils
This commit picks up where 569ce840cf left off, by correctly invoking
the new containsStatementSeparator(...) method from
executeSqlScript(...) in ScriptUtils in spring-r2dbc.

See gh-26911
2021-05-17 12:07:04 +02:00
Sébastien Deleuze 3dba3691a7 Upgrade to Coroutines 1.5.0
This commit upgrades to Coroutines 1.5.0 while retaining
Coroutines 1.4.x compatibility.

Closes gh-26897
2021-05-17 11:37:02 +02:00
Sam Brannen c80c4e001a Add missing author tags and sync SQL script support for JDBC & R2DBC 2021-05-16 17:18:56 +02:00
Sam Brannen 8da049b613 Update Javadoc URL for Apache HttpComponents Client 2021-05-16 15:22:37 +02:00
Sam Brannen 1acd832759 Fix link in @EventListener's id Javadoc 2021-05-16 15:08:33 +02:00
Sam Brannen 261927b72a Stop using deprecated Netty feature in ReactorHttpsServer 2021-05-16 15:03:42 +02:00
Sam Brannen 24aa7f546b Upgrade to JUnit 5.7.2
Closes gh-26946
2021-05-16 15:00:45 +02:00
Sam Brannen 4cfad25468 Polish ScriptUtils implementations 2021-05-14 15:15:12 +02:00
Sam Brannen 569ce840cf Ignore comments when searching for statement delimiter in ScriptUtils
Prior to this commit, the implementations of
ScriptUtils.containsSqlScriptDelimiters() in spring-jdbc and
spring-r2dbc did not ignore comments when searching for the statement
delimiter within an SQL script. This resulted in subtle bugs if a
comment contained a single single-quote or single double-quote, since
the absence of the closing single-quote or double-quote led the
algorithm to believe that it was still "within a text literal". Similar
issues could arise if a comment contained the sought statement
delimiter but the rest of the script did not contain the sought
statement delimiter. In such cases, the algorithms in ScriptUtils could
erroneously choose an incorrect statement delimiter -- for example,
using the fallback statement delimiter instead of the delimiter
specified by the user.

This commit avoids such bugs by ignoring single-line comments and block
comments when searching for the statement delimiter within an SQL
script.

Closes gh-26911
2021-05-14 14:23:27 +02:00
Sam Brannen fae484855b Fix grammar in inline comment in HttpStatus
See gh-26842
2021-05-13 16:21:45 +02:00
Qimiao Chen cab20d1202 Fix punctuation in Custom Cache Resolution section of ref docs
Closes gh-26938
2021-05-13 15:30:58 +02:00
Sam Brannen e2bf513563 Remove accidental dependency on Spring 5.2.x in spring-r2dbc tests 2021-05-12 13:43:36 +02:00
Sam Brannen 84e56bb5d9 Sync ScriptUtilsUnitTests implementations to simplify maintenance 2021-05-12 12:54:35 +02:00
Sam Brannen 6f5e66f00c Add missing tests for multiple comment prefixes in R2DBC ScriptUtils
See gh-23289
2021-05-12 12:23:54 +02:00
Sam Brannen cda72e4a70 Ignore delimiter enclosed in double quotes in ScriptUtils
Prior to this commit, the containsSqlScriptDelimiters() method in
ScriptUtils ignored delimiters enclosed in single quotes but not those
enclosed within double quotes, which contradicts the algorithm in
splitSqlScript() and therefore constitutes a bug.

This commit fixes this bug in the ScriptUtils implementations in
spring-jdbc and spring-r2dbc.

Closes gh-26935
2021-05-12 12:07:55 +02:00
Sam Brannen e31a4c4c77 Polishing 2021-05-12 11:31:15 +02:00
Spring Buildmaster 4809632f44 Next development version (v5.3.8-SNAPSHOT) 2021-05-12 05:50:28 +00:00
Arjen Poutsma 0d0d75e253 Ensure DefaultPartHttpMessageReader temp directories do not collide
This commit makes sure that the DefaultPartHttpMessageReader uses a
random temporary directory to store uploaded files, so that two
instances do not collide.

See gh-26931
2021-05-11 21:12:50 +02:00
Arjen Poutsma cce60c479c Ensure Synchronoss temp directories do not collide
This commit makes sure that Synchronoss uses a random temporary
directory to store uploaded files, so that two instances do not collide.

Closes gh-26931
2021-05-11 21:12:50 +02:00
Juergen Hoeller 1469bdbc70 Nullability refinements and related polishing 2021-05-11 16:50:19 +02:00
Juergen Hoeller be52ec8bd5 DataClassRowMapper exposes generic constructor parameters for type conversion
Closes gh-26881
2021-05-11 16:49:25 +02:00
Sam Brannen cd9cad31f9 Increase the likelihood that timed tests pass on CI server 2021-05-11 16:16:18 +02:00
Juergen Hoeller 60c551a95b Correct clientInboundChannel assertion (includes constructor javadoc)
Closes gh-26896
2021-05-11 15:49:38 +02:00
Juergen Hoeller 4164fc63b1 CandidateComponentsIndexer introspects any kind of class (including records)
Closes gh-26909
2021-05-11 15:49:15 +02:00
Juergen Hoeller 0865abef83 Expose current cached session count
Closes gh-26811
2021-05-11 15:47:15 +02:00
Juergen Hoeller 90af2d5794 Log delegate service initialization at debug level (instead of info)
Closes gh-26810
2021-05-11 15:46:41 +02:00
Juergen Hoeller 5f5cd8a7c4 Log resource path resolution failure at debug level (instead of warn)
Closes gh-26828
2021-05-11 15:46:21 +02:00
Juergen Hoeller 46b7cd54a1 Log missing web application context at warn level (instead of debug)
Closes gh-26925
2021-05-11 15:45:36 +02:00
Juergen Hoeller 7f670bbe68 TransactionSynchronization does not support @Order (just Ordered interface)
See gh-21725
2021-05-11 15:45:05 +02:00
Stephane Nicoll 6aaf7596c0 Upgrade to Reactor 2020.0.7
Closes gh-26890
2021-05-11 15:34:41 +02:00
Juergen Hoeller 4f2c589fe6 Upgrade to Jackson 2.12.3, Jetty 9.4.40, Hibernate ORM 5.4.31, Groovy 3.0.8, Caffeine 2.9.1, Woodstox 6.2.6, Protobuf 3.15.8, XStream 1.4.16, OpenPDF 1.3.26, Checkstyle 8.42, Mockito 3.9, HtmlUnit 2.49.1 2021-05-11 00:19:43 +02:00
Rossen Stoyanchev aa51ed1940 Fix failing tests
This commit ensures that if an Origin is returned as it was provided,
possibly with a trailing slash.

See gh-26892
2021-05-10 14:15:16 +01:00
Rossen Stoyanchev dc4e053d59 CorsConfiguration ignores trailing "/" in pattern
Recent commit dddcc5e9ad ensured a
trailing "/" in the Origin header has no effect. This commit does the
same for a trailing "/" in configured patterns.

See gh-26892
2021-05-10 13:30:02 +01:00
ShindongLee 07ba95739b Fix parameter bug of handler inside the filterFunction DSL
Co-authored-by: hojongs <hojong.jjh@gmail.com>
Co-authored-by: bjh970913 <bjh970913@gmail.com>

Closes gh-26838
2021-05-10 09:35:56 +02:00
Rossen Stoyanchev 0468ef46ac Follow-up fix for recent change to PORT_PATTERN
The pattern was changed in 65797d04f2
to check for characters up until "/", instead of for digits, but now
also checks up until "?" and "#".

Closes gh-26905
2021-05-10 07:19:17 +01:00
Rossen Stoyanchev eb03144e9d RSocketRequester implements Disposable
Closes gh-26886
2021-05-10 07:19:17 +01:00
Rossen Stoyanchev 29790d5bb1 Update docs on how a @ModelAttribute is sourced
Closes gh-26873
2021-05-10 07:19:17 +01:00
Sam Brannen 355d394d7f Polish contribution
See gh-25200
2021-05-08 19:40:13 +02:00
Vlad Kisel 9ddab9e69b Support single-value request param resolution for data class constructors
Prior to this commit, when Web MVC attempted to resolve a constructor
argument for a data class constructor with @ModelAttribute binding,
ModelAttributeMethodProcessor failed to unwrap the array returned by
WebRequest.getParameter(String).

According to the Javadoc for WebRequest.getParameter(String), "a
single-value parameter will be exposed as an array with a single
element."

This commit fixes this issue by extracting the single value from such
an array and using that as the constructor argument (potentially
converted by the WebDataBinder).

Closes gh-25200
2021-05-08 19:25:54 +02:00
Sam Brannen c20a43f72b Polish WebRequestDataBinderIntegrationTests 2021-05-08 18:12:55 +02:00
Rossen Stoyanchev e0fa58aa0f Polishing contribution
Closes gh-26905
2021-05-07 17:30:40 +01:00
Jeon Ilwoong 65797d04f2 UriComponentsBuilder handles invalid port correctly
See gh-26905
2021-05-07 17:15:16 +01:00
Rossen Stoyanchev 5811212a9f Add PreFlightRequestWebFilter
Closes gh-26885
2021-05-07 16:48:15 +01:00
Sam Brannen d79e33b5a0 Handle empty file input in HtmlUnitRequestBuilder
This commit revises the fix submitted in 959e6d1745 by ensuring that
empty file input is converted to a MockPart with the supplied name, an
empty filename, "application/octet-stream" as the content type, and
empty content.

This aligns with the behavior of Servlet containers, as tested with the
interaction between Firefox and a standard Servlet running in a Jetty
Servlet container.

Closes gh-26799
2021-05-07 16:00:09 +02:00
Rossen Stoyanchev dddcc5e9ad Ignore trailing slash in Origin header
See gh-26892
2021-05-07 14:56:56 +01:00
Rossen Stoyanchev 582b94d50e Allow charset input in WebClientResponseException
Closes gh-26866
2021-05-06 16:58:42 +01:00
Rossen Stoyanchev 443c34cc90 CorsRegistry implements combine correctly
Closes gh-26877
2021-05-05 21:02:25 +01:00
Sam Brannen 959e6d1745 Handle empty file input in HtmlUnitRequestBuilder
Prior to this commit, when using HtmlUnit with empty file input,
MockMvc's HtmlUnitRequestBuilder would throw a NullPointerException
when attempting to create a MockPart based on the null File.

This commit ensures that empty file input is converted to a MockPart
with a valid name but with a null filename, a null content type, and
empty content.

Closes gh-26799
2021-05-05 18:11:15 +02:00
Sam Brannen 38b592444d Store resolved toolchain info as custom values in build scan
Prior to this commit, we registered custom values in the build scan for
the main and test toolchains based on input values provided via the
mainToolchain and testToolchain project properties.

Beginning with this commit, the custom values we register are based on
the available metadata for the resolved JDK/JVM for each toolchain.

For example, instead of registering the following custom value...

Test toolchain : JDK11

... we now register the following which includes the vendor, version,
and installation path of the JDK/JVM.

Test toolchain : AdoptOpenJDK 11 (/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home)

Once Gradle's JavaInstallationMetadata includes the exact version, we
will likely use that instead of the installation path.

See gh-25787
2021-05-05 15:19:27 +02:00
Stephane Nicoll 2c2464b1e7 Make script executable 2021-05-05 14:26:12 +02:00
Sviatoslav Hryb 3b247a9c19 Fix MethodMatcher API doc description
Closes gh-26893
2021-05-05 12:21:46 +02:00
Sam Brannen d30432b6c0 Fix syntax in toolchains example
See gh-25787
2021-05-04 18:42:21 +02:00
Rossen Stoyanchev c70aed58bf Switch to Reactor 2020.0.7 snapshots
See gh-26890
2021-05-04 16:25:00 +01:00
Sam Brannen 2de7bf6e2b Exclude empty toolchain versions from Gradle build scan
See gh-25787
2021-05-04 15:20:38 +02:00
Sam Brannen a28511cdbd Polish Jaxb2MarshallerTests 2021-05-04 13:46:31 +02:00
Sam Brannen 668b938832 Remove obsolete order.xsd file
The order.xsd is no longer used by any tests and probably has not been
since commit 89a7e752ef, which removed support for Castor.

See gh-22250
2021-05-04 13:34:42 +02:00
Sam Brannen 091e7bb891 Remove duplicate copy of flight.xsd
See 85eb589c2e
See gh-25787
2021-05-04 13:19:04 +02:00
Rossen Stoyanchev b76e0c4826 HttpMethod#matches compares by String equality
Closes gh-26834
2021-05-04 12:09:35 +01:00
Bryce Yang 55faf6e320 Use HttpMethod enums
See gh-26855
2021-05-04 12:09:35 +01:00
Brian Clozel a522ed0788 Fix task parameters in CI build pipeline
Prior to this commit, the task parameters for the CI project checks were
overridden by a task anchor. This commit splits the anchor declaration
and ensures that the `TEST_TOOLCHAIN` setting is set for the JDK
variant builds.

See gh-25787
2021-05-04 11:48:17 +02:00
Sam Brannen 4152ebc2f3 Remove Eclipse resource filter for 'build' folder
Commit 3eec27a723 introduced a custom resource filter for projects
imported into Eclipse IDE. However, commit 85eb589c2e introduced
generated source files within the Gradle 'build' folder, and the filter
prevents Eclipse from seeing the generated sources, resulting in build
errors within the spring-oxm project in Eclipse.

This commit therefore effectively reverts 3eec27a723 by removing the
resource filter.

See gh-25787
2021-05-04 11:36:21 +02:00
Rossen Stoyanchev 21c90829df Polishing
See gh-26834
2021-05-04 10:34:56 +01:00
Sam Brannen 5b96c9b87e Update @since tag due to backport
See gh-26856
2021-05-04 10:59:49 +02:00
Sébastien Deleuze 08855fee51 Upgrade to Kotlin 1.5.0
This commit retains Kotlin 1.3 compatibility and
upgrades Kotlin Serialization to 1.2.0.

Closes gh-26792
Closes gh-26887
2021-05-03 17:46:25 +02:00
Sam Brannen 66cd979ce4 Support @ModelAttribute(binding=false) with WebFlux
Prior to this commit, @ModelAttribute(binding=false) was honored with
Spring Web MVC but not with WebFlux.

This commit adds support for disabling binding via @ModelAttribute with
WebFlux by adding a check to resolveArgument(...) in
ModelAttributeMethodArgumentResolver.

Closes gh-26856
2021-05-03 15:22:43 +02:00
Sam Brannen 5667d459a7 Polish Javadoc 2021-05-03 15:22:43 +02:00
Brian Clozel 85eb589c2e Fix Gradle Java Toolchain configuration
This commit fixes various issues with the configuration of the Gradle
Java toolchain in the build.

First, the configuration of build properties is fixed in the CI pipeline
because it wasn't properly checked.
The JMH plugin is also upgraded and we now configure its toolchain
support.
This commit also rewrites the XJC tasks in the spring-oxm module,
leveraging a Gradle plugin that creates actual compile tasks we can
configure.

See gh-25787
2021-05-03 15:02:09 +02:00
Arjen Poutsma b18cf3c873 Follow contract of computeIfAbsent LinkedCaseInsensitiveMap
This commit makes sure that LinkedCaseInsensitiveMap::computeIfAbsent
honors the contract of the method, and also replaces the old entry if
that mapped to null.

Closes gh-26868
2021-04-30 15:49:00 +02:00
Arjen Poutsma 399e7ebf22 Follow contract of putIfAbsent LinkedCaseInsensitiveMap
This commit makes sure that LinkedCaseInsensitiveMap::putIfAbsent honors
the contract of the method, and also replaces the old entry if that
mapped to null.

Closes gh-26868
2021-04-30 15:17:46 +02:00
Florian Kirmaier b5d6e53e50 Avoid memory leak when PropertyComparator is reused
This commit fixes a potential memory leak, since PropertyComparator
previously kept an indirect reference to the value it last compared.

Closes gh-26869
2021-04-30 15:08:32 +02:00
Stephane Nicoll 865969400b Polish
See gh-26882
2021-04-30 12:52:36 +02:00
Arjen Poutsma 6f4fb08bf8 Invoke WebMvc.fn error handlers for async errors
This commit makes sure that any error handlers registered on the route
are also applied when an error occurs asynchronously. This commit
applies to asynchronous bodies with both CompletableFuture and Reactive
Streams, as well as completely asynchronous responses.

Closes gh-26831
2021-04-30 11:43:40 +02:00
Stephane Nicoll 4c7cc705de Build PRs on CI
Closes gh-26882
2021-04-30 09:38:30 +02:00
Rossen Stoyanchev f7fc36250e Properly handle completion while in READING state
Closes gh-26834
2021-04-29 22:09:33 +01:00
Sviatoslav Hryb ae7d5200e5 Fix @Scope documentation in ref docs
Closes gh-26773
2021-04-29 18:08:54 +02:00
Sam Brannen ff9b68c1b6 Update copyright date for StaxEventXMLReader
See gh-26875
2021-04-29 18:01:27 +02:00
Tasuku Nakagawa 36c829386b Use an import instead of FQCN in StaxEventXMLReader
Closes gh-26875
2021-04-29 17:59:26 +02:00
Sam Brannen 7316dc726a Polish Javadoc for MessageSourceSupport
See gh-26874
2021-04-29 17:49:29 +02:00
Sviatoslav Hryb 118c7f969b Improve readability of MessageSourceSupport Javadoc
Closes gh-26874
2021-04-29 17:42:41 +02:00
K 26ed6d8bce Fix syntax for RequestEntity headers example in ref docs
Closes gh-26876
2021-04-29 17:34:04 +02:00
Johnny Lim 98770b15e7 Polishing
Closes gh-26878
2021-04-29 16:53:53 +02:00
Sam Brannen 697108cc42 Support safe-updates mode in MySQLMaxValueIncrementer
Prior to this commit, MySQLMaxValueIncrementer could not be used when
the MySQL database was configured to use safe-updates mode.

See https://dev.mysql.com/doc/refman/8.0/en/mysql-tips.html#safe-updates

This commit introduces a `limit 1` clause to the generated update
statement to allow MySQLMaxValueIncrementer to be compatible with
MySQL safe-updates mode.

Closes gh-26858
2021-04-29 15:37:40 +02:00
Stephane Nicoll 607d918340 Provide nested cause when a suitable CacheManager cannot be found
Closes gh-25250
2021-04-29 08:48:34 +02:00
Sam Brannen 8456eaca8e Polish SpEL selection/projection in ref docs 2021-04-28 15:54:39 +02:00
Sviatoslav Hryb 59015344a7 Fix SpEL selection description in ref docs
Closes gh-26852
2021-04-28 15:47:16 +02:00
Sam Brannen c03162e616 Polishing
See gh-26862
2021-04-28 15:43:52 +02:00
Sam Brannen 1dde30a7fd Fix grammar in ref docs 2021-04-28 15:39:21 +02:00
Sviatoslav Hryb 35196d3c62 Fix aspect autodetection description
Closes gh-26862
2021-04-28 15:37:59 +02:00
Sébastien Deleuze d7f67b3dc3 Fix a typo in PropertyResolverExtensions documentation 2021-04-28 12:17:27 +02:00
Sviatoslav Hryb 719e7394d6 Fix MessageSource doc description 2021-04-28 11:04:01 +01:00
Stephane Nicoll e4a5d2aaa5 Fix reference to assets on the default branch in ref doc
See gh-26863
2021-04-27 07:18:23 +02:00
Stephane Nicoll ab64607420 Update CI to use main as default branch name
Closes gh-26863
2021-04-27 07:09:41 +02:00
Rossen Stoyanchev b595dc1dfa Add advice on Spring MVC path matching for 5.3+
Closes gh-26750
2021-04-26 17:17:14 +01:00
Rossen Stoyanchev 86123de883 HandlerMappingIntrospector handles attribute changes properly
Closes gh-26833
2021-04-26 17:16:33 +01:00
Sam Brannen 7c3a18490b Polish SpEL SelectionAndProjectionTests 2021-04-26 16:23:21 +02:00
Sam Brannen 01e50fb60a Polish SpEL chapter 2021-04-22 18:55:40 +02:00
Sam Brannen 6c3a0a9026 Polishing 2021-04-22 18:53:31 +02:00
Sviatoslav Hryb 3bded7659a Improve documentation for SpEL constructor support
Closes gh-26846
2021-04-22 18:33:37 +02:00
Arjen Poutsma 7f1062159e Copy HttpStatus::values to prevent allocation
Before this commit, HttpStatus::resolve used the values() method in its
logic. This causes a new array to be allocated for each invocation,
and results in memory overhead.

This commit makes a copy of the HttpStatus values array, and uses that
to resolve status codes.

Closes gh-26842
2021-04-22 15:39:03 +02:00
Stephane Nicoll e4c0ff569b Merge pull request #26787 from dreis2211
* pr/26787:
  Avoid exceptions when evaluating validation hints

Closes gh-26787
2021-04-22 11:26:15 +02:00
Christoph Dreis e7cbe23771 Avoid exceptions when evaluating validation hints
Prior to this commit, evaluating validation hints for
@javax.validation.Valid caused exceptions being raised when getting the
value of this annotation, which does not exist. Bypassing
AnnotationUtils.getValue() in those cases can improve performance by
avoiding the cost incurred by raising exceptions.

See gh-26787
2021-04-22 11:19:30 +02:00
Rossen Stoyanchev d275a4e28d Asciidoc typo from previous commits 2021-04-21 17:37:06 +01:00
Rossen Stoyanchev 42a23098de Update docs on Principal controller method arguments
Closes gh-26791
2021-04-21 17:28:14 +01:00
Rossen Stoyanchev d25ae4b02c Add advice on using exchange from an ExchangeFilterFunction
Closes gh-26819
2021-04-21 17:04:10 +01:00
Sam Brannen 5740eaf33e Polishing 2021-04-21 14:15:27 +02:00
Sviatoslav Hryb 80d46ba80e Update FactoryBean generic description in ref docs
Closes gh-26758
2021-04-21 14:06:43 +02:00
Сергей Цыпанов db9a10bf35 Use String.startsWith() instead of substring() in PatternMatchUtils
Closes gh-26822
2021-04-21 13:56:38 +02:00
Arjen Poutsma 27bfcbbc82 Fix daylight saving issue in CronExpression
Closes gh-26830
2021-04-21 12:04:21 +02:00
Sviatoslav Hryb b153b5e53b Fix Kotlin code formatting for Inline Maps section of ref docs
Closes gh-26836
2021-04-21 11:13:00 +02:00
Sam Brannen 1f477a5c1c Polish Javadoc for ColumnMapRowMapper
See gh-26823
2021-04-20 19:27:56 +02:00
Marten Deinum ceac2a5c3c Remove reference to Commons Collections in ColumnMapRowMapper Javadoc
This commit removes the outdated reference to Commons Collections
in the Javadoc for ColumnMapRowMapper.

Closes gh-26823
2021-04-20 19:22:57 +02:00
Sviatoslav Hryb e03fdeaf8b Improve ref docs regarding @Bean method visibility constraints
Closes gh-26797
2021-04-20 19:08:27 +02:00
Sviatoslav Hryb 0286549466 Fix formatting for PersonValidator Kotlin example in ref docs
Closes gh-26832
2021-04-20 18:59:50 +02:00
Sam Brannen 71158f4d96 Polishing
See gh-26825
2021-04-20 18:56:18 +02:00
Sviatoslav Hryb 7303680369 Remove reference to deprecated Joda Time support in @DateTimeFormat Javadoc
Closes gh-26825
2021-04-20 18:54:34 +02:00
Sam Brannen 906a1f561a Polish CronTriggerTests and assess daylight savings time issue
This test polishes CronTriggerTests and modifies the
daylightSavingMissingHour() test to help analyze why the test fails
for CET if the minute value for the last completion time falls between
0 and 9 minutes.

Associated broken build:

https://ge.spring.io/s/epphj7vruwcn6/tests/:spring-context:test/org.springframework.scheduling.support.CronTriggerTests/testDaylightSavingMissingHour(LocalDateTime,%20TimeZone)%5B2%5D?expanded-stacktrace=WyIwIl0
2021-04-20 12:18:01 +02:00
Sam Brannen e489706f13 Ensure @DateTimeFormat tests pass on Java 9+
Prior to this commit, two tests for exception handling regarding
@DateTimeFormat processing only passed on Java 8. This is due to the
fact that the toString() implementation for annotations changed in Java
9. Specifically, the representation for arrays changed from [] to {},
and strings are enclosed in double quotes beginning with Java 9.

This commit ensures that the affected @DateTimeFormat tests pass on
Java 9+, by making the assertions more lenient regarding toString()
output for annotations.

See gh-26777
See gh-26804
2021-04-18 15:48:00 +02:00
Rossen Stoyanchev 69bbdce826 HandlerMappingIntrospector ensures initialized RequestPath
Closes gh-26814
2021-04-16 19:56:03 +01:00
Sam Brannen 0f31830ae2 Retain root cause for parsing patterns in @DateTimeFormat
The support for fallback parsing patterns in @DateTimeFormat introduced
in gh-20292 introduced a regression in that the original cause of the
parsing exception was no longer retained.

gh-26777 addressed that regression for `java.time` support; whereas,
this commit addresses that regression for legacy Date types.

This commit ensures that the original ParseException is set as the
cause for any newly created ParseException, thereby retaining the
original exception as the root cause.

Closes gh-26804
2021-04-16 19:14:41 +02:00
Sam Brannen 5d297c6387 Polishing 2021-04-16 11:44:48 +02:00
Sviatoslav Hryb 320f5836b4 Fix LocaleEditor description & formatting in reference manual
Closes gh-26816
2021-04-16 11:39:45 +02:00
Sviatoslav Hryb af06b80bdf Update FormatterRegistry interface in reference manual
Closes gh-26812
2021-04-15 18:45:13 +02:00
Sam Brannen 5b1ab31559 Polishing 2021-04-15 11:17:04 +02:00
Sviatoslav Hryb bf05da1f8c Remove unnecessary semicolon in BeanInfo example
Closes gh-26806
2021-04-15 11:10:15 +02:00
Stephane Nicoll 63217e44f1 Merge pull request #26807 from mustafau
* pr/26807:
  Update copyright year of changed file
  Remove leftover Javadoc from WebClient

Closes gh-26807
2021-04-15 09:56:16 +02:00
Stephane Nicoll 5226a67161 Update copyright year of changed file
See gh-26807
2021-04-15 09:50:54 +02:00
Mustafa Ulu 1694274e32 Remove leftover Javadoc from WebClient
See gh-26807
2021-04-15 09:50:39 +02:00
Rossen Stoyanchev 27c4e74e24 Update CORS Javadoc in spring-websocket
Closes gh-26753
2021-04-13 17:43:40 +01:00
Spring Buildmaster b73eb51cb1 Next development version (v5.3.7-SNAPSHOT) 2021-04-13 11:15:32 +00:00
Juergen Hoeller f31933e67e Nullability refinements 2021-04-13 12:26:52 +02:00
Juergen Hoeller c7989c78c8 Polishing 2021-04-13 12:26:31 +02:00
Sam Brannen f03ccd5cc9 Fix Javadoc in AcceptHeaderLocaleResolver
Closes gh-26793
2021-04-13 11:36:28 +02:00
Sam Brannen bcc6171a72 Polish contribution
See gh-26785
2021-04-13 11:21:56 +02:00
Sviatoslav Hryb a80c5fcfaf Improve @EventListener documentation in reference manual
Closes gh-26785
2021-04-13 11:17:09 +02:00
Juergen Hoeller 04ce8e0ac4 Make URL path tests compatible with Windows
See gh-26775
2021-04-13 09:52:23 +02:00
Stephane Nicoll 74f7eb11be Polish "Upgrade to Reactor 2020.0.6"
See gh-26767
2021-04-13 08:12:02 +02:00
Juergen Hoeller e05b584623 Ignore testWindowsAbsoluteFilePath exception if not on Windows
See gh-26702
2021-04-12 23:46:27 +02:00
Juergen Hoeller 29955a2898 Polishing 2021-04-12 22:41:00 +02:00
Juergen Hoeller 4b6b12bf2f Bypass root path resolution for "file:" prefix only
Closes gh-26702
2021-04-12 22:40:53 +02:00
Rossen Stoyanchev ab0e8f0617 Upgrade to Reactor 2020.0.6
Closes gh-26767
2021-04-12 20:22:38 +01:00
Rossen Stoyanchev 0a6a6d48e2 Avoid CI failures with UTF-8 chars in test filenames
See gh-26775
2021-04-12 20:14:48 +01:00
Rossen Stoyanchev a08593b44b Correct matching of static resources with parsed patterns
Closes gh-26775
2021-04-12 19:54:20 +01:00
Rebwon 7954dc7a00 Polish tests
Closes gh-26708
2021-04-12 20:11:14 +02:00
Sam Brannen 22d9012081 Retain root cause for parsing patterns in @DateTimeFormat
The support for fallback parsing patterns in @DateTimeFormat introduced
in gh-20292 introduced a regression in that the original cause of the
parsing exception was no longer retained.

This commit ensures that the original DateTimeParseException is set as
the cause for any newly created DateTimeParseException, thereby
retaining the original exception as the root cause.

Closes gh-26777
2021-04-12 19:55:43 +02:00
Arjen Poutsma 327e761536 Recreate file storage directory when removed in DefaultPartHttpMessageReader
Some operating systems delete temp files not just when booting up, but
also during operation. This commit makes sure that the
DefaultPartHttpMessageReader recreates the directory used to store
files in, if it's not there.

Closes gh-26790
2021-04-12 16:27:10 +02:00
Juergen Hoeller 4e42b5dfbc Upgrade to Tomcat 9.0.45, Jetty 9.4.39, Undertow 2.2.7, Netty 4.1.63, RxJava 3.0.12 2021-04-12 14:15:45 +02:00
Brandon Fergerson 432c720dd0 Allow spring-expression to be more easily repackaged
This commit allows the spring-expression module to be more easily repackaged
for embedding in third-party JARs -- for example, via the Shadow Gradle plugin.

Closes gh-26779
2021-04-09 17:29:29 +02:00
Sviatoslav Hryb f7606ba51b Update ref docs regarding RequiredAnnotationBPP registration
The RequiredAnnotationBeanPostProcessor is no longer automatically
registered via XML namespace elements.

Closes gh-26783
2021-04-09 16:59:48 +02:00
Sam Brannen 0f54585f05 Polish contribution
See gh-26782
2021-04-09 16:54:49 +02:00
Stephane Nicoll d3d6e100da Merge pull request #26781 from runningcode
* pr/26781:
  Update to Gradle Enterprise Gradle Plugin 3.6.1

Closes gh-26781
2021-04-09 16:47:04 +02:00
Nelson Osacky a48c5f6a0d Update to Gradle Enterprise Gradle Plugin 3.6.1
See gh-26781
2021-04-09 16:46:53 +02:00
Sviatoslav Hryb 35ea33e13a Update documentation for <context:annotation-config/>
Closes gh-26782
2021-04-09 16:32:17 +02:00
Arjen Poutsma a2d91a562d Support "Accept-Patch" for unsupported media type
This commit introduces support in both servlet and webflux for the
"Accept-Patch" header, which is sent when the client sends unsupported
data in PATCH requests.
See  section 2.2 of RFC 5789.

Closes gh-26759
2021-04-08 14:46:59 +02:00
Arjen Poutsma 97f3846971 Support "Accept-Patch" for OPTIONS requests
This commit introduces support in both servlet and webflux for the
"Accept-Patch" header in OPTIONS requests, as defined in section 3.1 of
RFC 5789.

See gh-26759
2021-04-08 14:43:49 +02:00
Stephane Nicoll 44e1d6d1bf Merge pull request #26776 from KENNYSOFT
* pr/26776:
  Update copyright year of changed file
  Fix javadoc link syntax

Closes gh-26776
2021-04-08 14:24:39 +02:00
Stephane Nicoll 7adac25e7e Update copyright year of changed file
See gh-26776
2021-04-08 14:24:18 +02:00
Hyeonmin Park 7dca6a36a6 Fix javadoc link syntax
See gh-26776
2021-04-08 14:21:11 +02:00
Rossen Stoyanchev c5ac8e8ab6 Use createUnresolved for forwarded header address
Avoid DNS resolution.

See gh-26748
2021-04-07 12:50:07 +01:00
Stephane Nicoll fa4c62cab2 Start building against Reactor 2020.0.6 snapshots
See gh-26767
2021-04-07 09:34:43 +02:00
Rossen Stoyanchev 8a1182a678 Additional validation for forwarded header address value
Closes gh-26748
2021-04-06 19:43:13 +01:00
Stephane Nicoll 01bea34569 Merge pull request #26755 from izeye
* pr/26755:
  Add since to WebClient.ResponseSpec.awaitBodyOrNull()

Closes gh-26755
2021-04-02 17:46:13 +02:00
Johnny Lim aec151e014 Add since to WebClient.ResponseSpec.awaitBodyOrNull()
See gh-26755
2021-04-02 17:45:57 +02:00
Valentin 58e40d1aa2 Add awaitBodyOrNull to WebClient.ResponseSpec
Such variant is already provided for ClientResponse but not
for WebClient.ResponseSpec.

Closes gh-26731
2021-04-01 17:06:48 +02:00
Sébastien Deleuze 85dbd2a4c3 Upgrade Kotlin to 1.4.32 2021-04-01 16:06:14 +02:00
Sébastien Deleuze eca87b87de Improve Kotlin support in BridgeMethodResolver#findBridgedMethod
This commit adds support for Kotlin non-nullable type which resolves
to primitive Java types in BridgeMethodResolver#findBridgedMethod.

Closes gh-26585
2021-04-01 15:39:53 +02:00
Rossen Stoyanchev 5e1e29a2dd Fix failing tests
See gh-26746
2021-03-31 12:25:39 +01:00
Rossen Stoyanchev 7dc3a55648 Deferred buffer allocation in SSE message writer
See gh-26746
2021-03-31 11:47:22 +01:00
Arjen Poutsma f982fd99d7 Fix timezone offset in CronExpressionTests
Closes gh-26744
2021-03-30 16:37:26 +02:00
Arjen Poutsma ab18ab6025 Fix CronExpression issue with ZonedDateTime & DST
This commit fixes an issue with CronExpression when used in combination
with ZonedDateTime and daylight saving time.

Closes gh-26744
2021-03-30 15:20:59 +02:00
Arjen Poutsma d83fb09914 Change header encoding to UTF8 in DefaultPartHttpMessageReader
This commit changes the encoding used to parse multipart headers from
ISO-8859-1 to UTF-8, in accordance with RFC 7578.

Closes gh-26736
2021-03-30 10:51:19 +02:00
Rossen Stoyanchev b651c10e83 Fix error messages to match commit #1a9556
See gh-26679
2021-03-29 18:30:49 +01:00
Rossen Stoyanchev 5651695fd1 Fix typo in Javadoc
Closes gh-26740
2021-03-29 17:59:19 +01:00
Rossen Stoyanchev 1a9556925d missingAfterConversion flag for missing request values
Closes gh-26679
2021-03-29 15:23:29 +01:00
nara 2dc203ffdc Polish web docs example 2021-03-29 11:40:56 +01:00
Brian Clozel 610de3ae78 Upgrade to Concourse Release Scripts 0.3.2 2021-03-23 13:59:53 +01:00
Juergen Hoeller 5b2ace5742 Upgrade to Hibernate ORM 5.4.30, Tomcat 9.0.44, FreeMarker 2.3.31, Log4J 2.14.1, TestNG 7.4, HtmlUnit 2.48 2021-03-22 23:34:13 +01:00
Juergen Hoeller 5b227e5677 Upgrade to Objenesis 3.2
Closes gh-26714
2021-03-22 23:11:30 +01:00
Rossen Stoyanchev 41d5048280 Add BlockHoundIntegration for spring-web
Closes gh-26712
2021-03-22 21:18:48 +00:00
Rossen Stoyanchev a931ff12f6 MappedInterceptor falls back on PathMatcher
Closes gh-26690
2021-03-22 07:12:10 +00:00
Sam Brannen e4f753e3e3 Honor class-level @DirtiesContext if test class is disabled via SpEL
Prior to this commit, if a test class annotated with @DirtiesContext
and @EnabledIf/@DisabledIf with `loadContext = true` was disabled due
to the evaluated SpEL expression, the ApplicationContext would not be
marked as dirty and closed.

The reason is that @EnabledIf/@DisabledIf are implemented via JUnit
Jupiter's ExecutionCondition extension API which results in the entire
test class (as well as any associated extension callbacks) being
skipped if the condition evaluates to `disabled`. This effectively
prevents any of Spring's TestExecutionListener APIs from being invoked.
Consequently, the DirtiesContextTestExecutionListener does not get a
chance to honor the class-level @DirtiesContext declaration.

This commit fixes this by implementing part of the logic of
DirtiesContextTestExecutionListener in
AbstractExpressionEvaluatingCondition (i.e., the base class for
@EnabledIf/@DisabledIf support). Specifically, if the test class for an
eagerly loaded ApplicationContext is disabled,
AbstractExpressionEvaluatingCondition will now mark the test
ApplicationContext as dirty if the test class is annotated with
@DirtiesContext.

Closes gh-26694
2021-03-18 13:51:32 +01:00
Rossen Stoyanchev 4982b5fcb9 Improve docs on SSE tests for Spring MVC
Closes gh-26687
2021-03-16 17:55:43 +00:00
Sam Brannen f7678cdcdd Polish core-beans.adoc 2021-03-16 13:09:36 +01:00
Brian Clozel 3ab39eda08 Fix Gradle Toolchain configuration
See gh-25787
2021-03-16 13:04:11 +01:00
Brian Clozel 14a6909c4a Fix release pipeline for Maven Central publication
This commit fixes the missing pieces in our Maven Central publication
pipeline. Our first attempt at releasing with it showed a few problems:

* the promote task did not have the artifacts downladed with the
  artifactory repository
* we applied the wrong Sonatype credentials to the task
* the github changelog task would fail because of docker rate limiting
  since we were not using the right type of resource, which is
  configured with the proper caching mechanism

See gh-26654
2021-03-16 13:04:11 +01:00
Rebwon fd17738f76 Polish TestContextAnnotationsUtilsTests
Closes gh-26684
2021-03-16 12:15:00 +01:00
Spring Buildmaster f674652dd0 Next development version (v5.3.6-SNAPSHOT) 2021-03-16 08:12:35 +00:00
1648 changed files with 28664 additions and 16616 deletions
+3
View File
@@ -0,0 +1,3 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=8.0.322-librca
+1 -1
View File
@@ -72,7 +72,7 @@ to start a discussion first or have already created an issue, once a pull reques
created, we will close the issue as superseded by the pull request, and the discussion
about the issue will continue under the pull request.
1. Always check out the `master` branch and submit pull requests against it
1. Always check out the `main` branch and submit pull requests against it
(for target version see [settings.gradle](settings.gradle)).
Backports to prior versions will be considered on a case-by-case basis and reflected as
the fix version in the issue tracker.
+1 -1
View File
@@ -8,4 +8,4 @@ wiki page.
## Reporting a Vulnerability
Please see https://pivotal.io/security.
Please see https://spring.io/security-policy.
+109 -96
View File
@@ -1,16 +1,17 @@
plugins {
id 'io.spring.dependency-management' version '1.0.9.RELEASE' apply false
id 'io.spring.nohttp' version '0.0.5.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.4.31' apply false
id 'org.jetbrains.dokka' version '0.10.1' apply false
id 'org.asciidoctor.jvm.convert' version '3.1.0'
id 'org.asciidoctor.jvm.pdf' version '3.1.0'
id 'de.undercouch.download' version '4.1.1'
id "io.freefair.aspectj" version '5.1.1' apply false
id "com.github.ben-manes.versions" version '0.28.0'
id "com.github.johnrengelman.shadow" version "6.1.0" apply false
id "me.champeau.gradle.jmh" version "0.5.2" apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.4.31" apply false
id 'io.spring.dependency-management' version '1.0.11.RELEASE' apply false
id 'io.spring.nohttp' version '0.0.10'
id "io.freefair.aspectj" version '6.2.0' apply false
id 'org.jetbrains.dokka' version '1.6.10' apply false
id 'org.jetbrains.kotlin.jvm' version '1.5.32' apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.5.32" apply false
id 'org.asciidoctor.jvm.convert' version '3.3.2'
id 'org.asciidoctor.jvm.pdf' version '3.3.2'
id "org.unbroken-dome.xjc" version '2.0.0' apply false
id "com.github.ben-manes.versions" version '0.39.0'
id "com.github.johnrengelman.shadow" version '7.0.0' apply false
id 'de.undercouch.download' version '4.1.2'
id "me.champeau.jmh" version "0.6.6" apply false
}
ext {
@@ -26,35 +27,36 @@ configure(allprojects) { project ->
dependencyManagement {
imports {
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.2"
mavenBom "io.netty:netty-bom:4.1.60.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.5"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR9"
mavenBom "io.rsocket:rsocket-bom:1.1.0"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.38.v20210224"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.4.30"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.4.3"
mavenBom "org.junit:junit-bom:5.7.1"
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.6"
mavenBom "io.netty:netty-bom:4.1.75.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.17"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR12"
mavenBom "io.rsocket:rsocket-bom:1.1.1"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.45.v20220203"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.32"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2"
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2"
mavenBom "org.junit:junit-bom:5.8.2"
}
dependencies {
dependencySet(group: 'org.apache.logging.log4j', version: '2.14.0') {
dependencySet(group: 'org.apache.logging.log4j', version: '2.17.2') {
entry 'log4j-api'
entry 'log4j-core'
entry 'log4j-jul'
entry 'log4j-slf4j-impl'
}
dependency "org.slf4j:slf4j-api:1.7.30"
dependency "org.slf4j:slf4j-api:1.7.36"
dependency("com.google.code.findbugs:findbugs:3.0.1") {
exclude group: "dom4j", name: "dom4j"
}
dependency "com.google.code.findbugs:jsr305:3.0.2"
dependencySet(group: 'org.aspectj', version: '1.9.6') {
dependencySet(group: 'org.aspectj', version: '1.9.7') {
entry 'aspectjrt'
entry 'aspectjtools'
entry 'aspectjweaver'
}
dependencySet(group: 'org.codehaus.groovy', version: '3.0.7') {
dependencySet(group: 'org.codehaus.groovy', version: '3.0.9') {
entry 'groovy'
entry 'groovy-jsr223'
entry 'groovy-templates' // requires findbugs for warning-free compilation
@@ -65,22 +67,23 @@ configure(allprojects) { project ->
dependency "io.reactivex:rxjava:1.3.8"
dependency "io.reactivex:rxjava-reactive-streams:1.2.1"
dependency "io.reactivex.rxjava2:rxjava:2.2.21"
dependency "io.reactivex.rxjava3:rxjava:3.0.11"
dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE"
dependency "io.reactivex.rxjava3:rxjava:3.1.3"
dependency "io.smallrye.reactive:mutiny:1.4.0"
dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE"
dependency "com.caucho:hessian:4.0.63"
dependency "com.fasterxml:aalto-xml:1.2.2"
dependency("com.fasterxml.woodstox:woodstox-core:6.2.4") {
dependency "com.fasterxml:aalto-xml:1.3.1"
dependency("com.fasterxml.woodstox:woodstox-core:6.2.8") {
exclude group: "stax", name: "stax-api"
}
dependency "com.google.code.gson:gson:2.8.6"
dependency "com.google.protobuf:protobuf-java-util:3.15.5"
dependency "com.google.code.gson:gson:2.8.9"
dependency "com.google.protobuf:protobuf-java-util:3.19.3"
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
dependency("com.thoughtworks.xstream:xstream:1.4.15") {
dependency("com.thoughtworks.xstream:xstream:1.4.18") {
exclude group: "xpp3", name: "xpp3_min"
exclude group: "xmlpull", name: "xmlpull"
}
dependency "org.apache.johnzon:johnzon-jsonb:1.2.10"
dependency "org.apache.johnzon:johnzon-jsonb:1.2.16"
dependency("org.codehaus.jettison:jettison:1.3.8") {
exclude group: "stax", name: "stax-api"
}
@@ -89,20 +92,16 @@ configure(allprojects) { project ->
entry 'jibx-run'
}
dependency "org.ogce:xpp3:1.1.6"
dependency "org.yaml:snakeyaml:1.28"
dependencySet(group: 'org.jetbrains.kotlinx', version: '1.0.1') {
entry 'kotlinx-serialization-core'
entry 'kotlinx-serialization-json'
}
dependency "org.yaml:snakeyaml:1.30"
dependency "com.h2database:h2:1.4.200"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.0"
dependency "com.github.librepdf:openpdf:1.3.25"
dependency "com.rometools:rome:1.15.0"
dependency "com.h2database:h2:2.1.210"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.3"
dependency "com.github.librepdf:openpdf:1.3.26"
dependency "com.rometools:rome:1.18.0"
dependency "commons-io:commons-io:2.5"
dependency "io.vavr:vavr:0.10.3"
dependency "io.vavr:vavr:0.10.4"
dependency "net.sf.jopt-simple:jopt-simple:5.0.4"
dependencySet(group: 'org.apache.activemq', version: '5.16.1') {
dependencySet(group: 'org.apache.activemq', version: '5.16.2') {
entry 'activemq-broker'
entry('activemq-kahadb-store') {
exclude group: "org.springframework", name: "spring-context"
@@ -117,55 +116,55 @@ configure(allprojects) { project ->
}
dependency "org.apache.poi:poi-ooxml:4.1.2"
dependency "org.apache-extras.beanshell:bsh:2.0b6"
dependency "org.freemarker:freemarker:2.3.30"
dependency "org.hsqldb:hsqldb:2.5.1"
dependency "org.freemarker:freemarker:2.3.31"
dependency "org.hsqldb:hsqldb:2.5.2"
dependency "org.quartz-scheduler:quartz:2.3.2"
dependency "org.codehaus.fabric3.api:commonj:1.1.0"
dependency "net.sf.ehcache:ehcache:2.10.6"
dependency "org.ehcache:jcache:1.0.1"
dependency "org.ehcache:ehcache:3.4.0"
dependency "org.hibernate:hibernate-core:5.4.29.Final"
dependency "org.hibernate:hibernate-validator:6.2.0.Final"
dependency "org.webjars:webjars-locator-core:0.46"
dependency "org.hibernate:hibernate-core:5.4.33.Final"
dependency "org.hibernate:hibernate-validator:6.2.3.Final"
dependency "org.webjars:webjars-locator-core:0.48"
dependency "org.webjars:underscorejs:1.8.3"
dependencySet(group: 'org.apache.tomcat', version: '9.0.43') {
dependencySet(group: 'org.apache.tomcat', version: '9.0.60') {
entry 'tomcat-util'
entry('tomcat-websocket') {
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
}
}
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.43') {
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.60') {
entry 'tomcat-embed-core'
entry 'tomcat-embed-websocket'
}
dependencySet(group: 'io.undertow', version: '2.2.5.Final') {
dependencySet(group: 'io.undertow', version: '2.2.16.Final') {
entry 'undertow-core'
entry('undertow-servlet') {
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_4.0_spec"
exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.3_spec"
}
entry('undertow-websockets-jsr') {
exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec"
}
entry('undertow-servlet') {
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_3.1_spec"
exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.2_spec"
}
}
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.10"
dependency 'org.apache.httpcomponents.client5:httpclient5:5.1.3'
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.3'
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.apache.httpcomponents:httpasyncclient:4.1.5") {
exclude group: "commons-logging", name: "commons-logging"
}
dependencySet(group: 'com.squareup.okhttp3', version: '3.14.9') {
entry 'okhttp'
entry 'mockwebserver'
}
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.apache.httpcomponents:httpasyncclient:4.1.4") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency 'org.apache.httpcomponents.client5:httpclient5:5.0.3'
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.0.3'
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.6"
dependency "org.jruby:jruby:9.2.16.0"
dependency "org.jruby:jruby:9.2.20.1"
dependency "org.python:jython-standalone:2.7.1"
dependency "org.mozilla:rhino:1.7.11"
@@ -188,28 +187,29 @@ configure(allprojects) { project ->
dependency("de.bechte.junit:junit-hierarchicalcontextrunner:4.12.1") {
exclude group: "junit", name: "junit"
}
dependency "org.testng:testng:7.3.0"
dependency "org.testng:testng:7.4.0"
dependency "org.junit.support:testng-engine:1.0.1"
dependency "org.hamcrest:hamcrest:2.1"
dependency "org.awaitility:awaitility:3.1.6"
dependency "org.assertj:assertj-core:3.19.0"
dependencySet(group: 'org.xmlunit', version: '2.8.2') {
dependency "org.assertj:assertj-core:3.22.0"
dependencySet(group: 'org.xmlunit', version: '2.9.0') {
entry 'xmlunit-assertj'
entry('xmlunit-matchers') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
}
dependencySet(group: 'org.mockito', version: '3.8.0') {
dependencySet(group: 'org.mockito', version: '4.4.0') {
entry('mockito-core') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
entry 'mockito-junit-jupiter'
}
dependency "io.mockk:mockk:1.10.2"
dependency "io.mockk:mockk:1.12.1"
dependency("net.sourceforge.htmlunit:htmlunit:2.47.1") {
dependency("net.sourceforge.htmlunit:htmlunit:2.59.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:htmlunit-driver:2.47.1") {
dependency("org.seleniumhq.selenium:htmlunit-driver:2.59.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
@@ -217,7 +217,7 @@ configure(allprojects) { project ->
exclude group: "io.netty", name: "netty"
}
dependency "org.skyscreamer:jsonassert:1.5.0"
dependency "com.jayway.jsonpath:json-path:2.5.0"
dependency "com.jayway.jsonpath:json-path:2.6.0"
dependency "org.bouncycastle:bcpkix-jdk15on:1.66"
dependencySet(group: 'org.apache.tiles', version: '3.0.8') {
@@ -237,8 +237,8 @@ configure(allprojects) { project ->
dependency "com.ibm.websphere:uow:6.0.2.17"
dependency "com.jamonapi:jamon:2.82"
dependency "joda-time:joda-time:2.10.10"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.8"
dependency "joda-time:joda-time:2.10.13"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.10"
dependency "org.javamoney:moneta:1.3"
dependency "com.sun.activation:javax.activation:1.2.0"
@@ -314,11 +314,13 @@ configure([rootProject] + javaProjects) { project ->
pluginManager.withPlugin("kotlin") {
apply plugin: "org.jetbrains.dokka"
apply from: "${rootDir}/gradle/docs-dokka.gradle"
compileKotlin {
kotlinOptions {
languageVersion = "1.3"
apiVersion = "1.3"
freeCompilerArgs = ["-Xjsr305=strict"]
freeCompilerArgs = ["-Xjsr305=strict", "-Xsuppress-version-warnings", "-Xopt-in=kotlin.RequiresOptIn"]
allWarningsAsErrors = true
}
}
@@ -338,35 +340,36 @@ configure([rootProject] + javaProjects) { project ->
}
checkstyle {
toolVersion = "8.41"
toolVersion = "9.3"
configDirectory.set(rootProject.file("src/checkstyle"))
}
dependencies {
testCompile("org.junit.jupiter:junit-jupiter-api")
testCompile("org.junit.jupiter:junit-jupiter-params")
testCompile("org.mockito:mockito-core")
testCompile("org.mockito:mockito-junit-jupiter")
testCompile("io.mockk:mockk")
testCompile("org.assertj:assertj-core")
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.junit.jupiter:junit-jupiter-params")
testImplementation("org.junit.platform:junit-platform-suite-api")
testImplementation("org.mockito:mockito-core")
testImplementation("org.mockito:mockito-junit-jupiter")
testImplementation("io.mockk:mockk")
testImplementation("org.assertj:assertj-core")
// Pull in the latest JUnit 5 Launcher API to ensure proper support in IDEs.
testRuntime("org.junit.platform:junit-platform-launcher")
testRuntime("org.junit.jupiter:junit-jupiter-engine")
testRuntime("org.apache.logging.log4j:log4j-core")
testRuntime("org.apache.logging.log4j:log4j-slf4j-impl")
testRuntime("org.apache.logging.log4j:log4j-jul")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testRuntimeOnly("org.junit.platform:junit-platform-suite-engine")
testRuntimeOnly("org.apache.logging.log4j:log4j-core")
testRuntimeOnly("org.apache.logging.log4j:log4j-jul")
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl")
// JSR-305 only used for non-required meta-annotations
compileOnly("com.google.code.findbugs:jsr305")
testCompileOnly("com.google.code.findbugs:jsr305")
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.15")
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.31")
}
ext.javadocLinks = [
"https://docs.oracle.com/javase/8/docs/api/",
"https://docs.oracle.com/javaee/7/api/",
"https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ
"https://www.ibm.com/support/knowledgecenter/SS7JFU_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/",
"https://glassfish.java.net/nonav/docs/v3/api/",
"https://www.ibm.com/docs/api/v1/content/SSEQTP_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/",
"https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/",
"https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/",
"https://tiles.apache.org/tiles-request/apidocs/",
@@ -377,10 +380,21 @@ configure([rootProject] + javaProjects) { project ->
"https://fasterxml.github.io/jackson-core/javadoc/2.10/",
"https://fasterxml.github.io/jackson-databind/javadoc/2.10/",
"https://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.10/",
"https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/",
"https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/",
"https://projectreactor.io/docs/test/release/api/",
"https://junit.org/junit4/javadoc/4.13.2/",
"https://junit.org/junit5/docs/5.7.1/api/"
// Disabling linking to JUnit 5.8.2, since the `package-list` file no longer exists due to
// https://github.com/junit-team/junit5/commit/67ad4e545518b0ce2b0e7c96df31a669866d5003.
// "https://junit.org/junit5/docs/5.8.2/api/",
"https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/",
"https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/",
"https://r2dbc.io/spec/0.8.5.RELEASE/api/",
// The external Javadoc link for JSR 305 must come last to ensure that types from
// JSR 250 (such as @PostConstruct) are still supported. This is due to the fact
// that JSR 250 and JSR 305 both define types in javax.annotation, which results
// in a split package, and the javadoc tool does not support split packages
// across multiple external Javadoc sites.
"https://www.javadoc.io/doc/com.google.code.findbugs/jsr305/3.0.2/"
] as String[]
}
@@ -391,7 +405,6 @@ configure(moduleProjects) { project ->
configure(rootProject) {
description = "Spring Framework"
apply plugin: "groovy"
apply plugin: "kotlin"
apply plugin: "io.spring.nohttp"
apply plugin: 'org.springframework.build.api-diff'
+1 -2
View File
@@ -8,8 +8,7 @@ repositories {
}
dependencies {
implementation "me.champeau.gradle:japicmp-gradle-plugin:0.2.8"
implementation "com.google.guava:guava:28.2-jre" // required by japicmp-gradle-plugin
implementation "me.champeau.gradle:japicmp-gradle-plugin:0.3.0"
}
gradlePlugin {
@@ -32,6 +32,7 @@ import org.gradle.api.tasks.compile.JavaCompile;
*
* @author Brian Clozel
* @author Sam Brannen
* @author Sebastien Deleuze
*/
public class CompilerConventionsPlugin implements Plugin<Project> {
@@ -43,7 +44,8 @@ public class CompilerConventionsPlugin implements Plugin<Project> {
List<String> commonCompilerArgs = Arrays.asList(
"-Xlint:serial", "-Xlint:cast", "-Xlint:classfile", "-Xlint:dep-ann",
"-Xlint:divzero", "-Xlint:empty", "-Xlint:finally", "-Xlint:overrides",
"-Xlint:path", "-Xlint:processing", "-Xlint:static", "-Xlint:try", "-Xlint:-options"
"-Xlint:path", "-Xlint:processing", "-Xlint:static", "-Xlint:try", "-Xlint:-options",
"-parameters"
);
COMPILER_ARGS = new ArrayList<>();
COMPILER_ARGS.addAll(commonCompilerArgs);
@@ -54,7 +56,7 @@ public class CompilerConventionsPlugin implements Plugin<Project> {
TEST_COMPILER_ARGS = new ArrayList<>();
TEST_COMPILER_ARGS.addAll(commonCompilerArgs);
TEST_COMPILER_ARGS.addAll(Arrays.asList("-Xlint:-varargs", "-Xlint:-fallthrough", "-Xlint:-rawtypes",
"-Xlint:-deprecation", "-Xlint:-unchecked", "-parameters"));
"-Xlint:-deprecation", "-Xlint:-unchecked"));
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -19,6 +19,7 @@ package org.springframework.build.optional;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.attributes.Usage;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSetContainer;
@@ -28,7 +29,7 @@ import org.gradle.plugins.ide.eclipse.model.EclipseModel;
/**
* A {@code Plugin} that adds support for Maven-style optional dependencies. Creates a new
* {@code optional} configuration. The {@code optional} configuration is part of the
* project's compile and runtime classpath's but does not affect the classpath of
* project's compile and runtime classpaths but does not affect the classpath of
* dependent projects.
*
* @author Andy Wilkinson
@@ -43,22 +44,16 @@ public class OptionalDependenciesPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
Configuration optional = project.getConfigurations().create("optional");
optional.setCanBeConsumed(false);
optional.setCanBeResolved(false);
project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> {
SourceSetContainer sourceSets = project.getConvention()
.getPlugin(JavaPluginConvention.class).getSourceSets();
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class)
.getSourceSets();
sourceSets.all((sourceSet) -> {
sourceSet.setCompileClasspath(
sourceSet.getCompileClasspath().plus(optional));
sourceSet.setRuntimeClasspath(
sourceSet.getRuntimeClasspath().plus(optional));
project.getConfigurations().getByName(sourceSet.getCompileClasspathConfigurationName()).extendsFrom(optional);
project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName()).extendsFrom(optional);
});
});
project.getPlugins().withType(EclipsePlugin.class, (eclipePlugin) -> {
project.getExtensions().getByType(EclipseModel.class)
.classpath((classpath) -> {
classpath.getPlusConfigurations().add(optional);
});
});
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ changelog:
- title: ":star: New Features"
labels:
- "type: enhancement"
- title: ":beetle: Bug Fixes"
- title: ":lady_beetle: Bug Fixes"
labels:
- "type: bug"
- "type: regression"
+2 -2
View File
@@ -1,4 +1,4 @@
FROM ubuntu:focal-20210119
FROM ubuntu:focal-20220302
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
@@ -6,6 +6,6 @@ RUN ./setup.sh java8
ENV JAVA_HOME /opt/openjdk/java8
ENV JDK11 /opt/openjdk/java11
ENV JDK15 /opt/openjdk/java15
ENV JDK17 /opt/openjdk/java17
ENV PATH $JAVA_HOME/bin:$PATH
+7 -4
View File
@@ -3,13 +3,16 @@ set -e
case "$1" in
java8)
echo "https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/download/jdk8u282-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u282b08.tar.gz"
echo "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u322-b06/OpenJDK8U-jdk_x64_linux_hotspot_8u322b06.tar.gz"
;;
java11)
echo "https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.10_9.tar.gz"
echo "https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.14.1%2B1/OpenJDK11U-jdk_x64_linux_hotspot_11.0.14.1_1.tar.gz"
;;
java15)
echo "https://github.com/AdoptOpenJDK/openjdk15-binaries/releases/download/jdk-15.0.2%2B7/OpenJDK15U-jdk_x64_linux_hotspot_15.0.2_7.tar.gz"
java17)
echo "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.2%2B8/OpenJDK17U-jdk_x64_linux_hotspot_17.0.2_8.tar.gz"
;;
java18)
echo "https://github.com/adoptium/temurin18-binaries/releases/download/jdk18-2022-02-12-08-06-beta/OpenJDK18-jdk_x64_linux_hotspot_2022-02-12-08-06.tar.gz"
;;
*)
echo $"Unknown java version"
+2 -2
View File
@@ -14,7 +14,7 @@ rm -rf /var/lib/apt/lists/*
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/concourse-java.sh > /opt/concourse-java.sh
curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.3.0/concourse-release-scripts-0.3.0.jar
curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.3.2/concourse-release-scripts-0.3.2.jar
###########################################################
# JAVA
@@ -22,7 +22,7 @@ curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/
mkdir -p /opt/openjdk
pushd /opt/openjdk > /dev/null
for jdk in java8 java11 java15
for jdk in java8 java11 java17
do
JDK_URL=$( /get-jdk-url.sh $jdk )
mkdir $jdk
+1 -4
View File
@@ -1,11 +1,8 @@
email-server: "smtp.svc.pivotal.io"
email-from: "ci@spring.io"
email-to: ["spring-framework-dev@pivotal.io"]
github-repo: "https://github.com/spring-projects/spring-framework.git"
github-repo-name: "spring-projects/spring-framework"
docker-hub-organization: "springci"
artifactory-server: "https://repo.spring.io"
branch: "master"
branch: "5.3.x"
milestone: "5.3.x"
build-name: "spring-framework"
pipeline-name: "spring-framework"
+73 -20
View File
@@ -2,15 +2,15 @@ anchors:
git-repo-resource-source: &git-repo-resource-source
uri: ((github-repo))
username: ((github-username))
password: ((github-password))
password: ((github-ci-release-token))
branch: ((branch))
gradle-enterprise-task-params: &gradle-enterprise-task-params
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
sonatype-task-params: &sonatype-task-params
SONATYPE_USER_TOKEN: ((sonatype-user-token))
SONATYPE_PASSWORD_TOKEN: ((sonatype-user-token-password))
SONATYPE_USERNAME: ((sonatype-username))
SONATYPE_PASSWORD: ((sonatype-password))
SONATYPE_URL: ((sonatype-url))
SONATYPE_STAGING_PROFILE_ID: ((sonatype-staging-profile-id))
artifactory-task-params: &artifactory-task-params
@@ -18,9 +18,6 @@ anchors:
ARTIFACTORY_USERNAME: ((artifactory-username))
ARTIFACTORY_PASSWORD: ((artifactory-password))
build-project-task-params: &build-project-task-params
privileged: true
timeout: ((task-timeout))
params:
BRANCH: ((branch))
<<: *gradle-enterprise-task-params
docker-resource-source: &docker-resource-source
@@ -48,12 +45,22 @@ resource_types:
type: registry-image
source:
repository: springio/artifactory-resource
tag: 0.0.13
tag: 0.0.17
- name: github-release
type: registry-image
source:
repository: concourse/github-release-resource
tag: 1.5.5
- name: github-status-resource
type: registry-image
source:
repository: dpb587/github-status-resource
tag: master
- name: pull-request
type: registry-image
source:
repository: teliaoss/github-pr-resource
tag: v0.23.0
- name: slack-notification
type: registry-image
source:
@@ -93,6 +100,14 @@ resources:
username: ((artifactory-username))
password: ((artifactory-password))
build_name: ((build-name))
- name: git-pull-request
type: pull-request
icon: source-pull
source:
access_token: ((github-ci-pull-request-token))
repository: ((github-repo-name))
base_branch: ((branch))
ignore_paths: ["ci/*"]
- name: repo-status-build
type: github-status-resource
icon: eye-check-outline
@@ -109,14 +124,14 @@ resources:
access_token: ((github-ci-status-token))
branch: ((branch))
context: jdk11-build
- name: repo-status-jdk15-build
- name: repo-status-jdk17-build
type: github-status-resource
icon: eye-check-outline
source:
repository: ((github-repo-name))
access_token: ((github-ci-status-token))
branch: ((branch))
context: jdk15-build
context: jdk17-build
- name: slack-alert
type: slack-notification
icon: slack
@@ -162,7 +177,10 @@ jobs:
- task: build-project
image: ci-image
file: git-repo/ci/tasks/build-project.yml
<<: *build-project-task-params
privileged: true
timeout: ((task-timeout))
params:
<<: *build-project-task-params
on_failure:
do:
- put: repo-status-build
@@ -217,10 +235,11 @@ jobs:
- task: check-project
image: ci-image
file: git-repo/ci/tasks/check-project.yml
privileged: true
timeout: ((task-timeout))
params:
MAIN_TOOLCHAIN: 8
TEST_TOOLCHAIN: 11
<<: *build-project-task-params
<<: *build-project-task-params
on_failure:
do:
- put: repo-status-jdk11-build
@@ -230,7 +249,7 @@ jobs:
<<: *slack-fail-params
- put: repo-status-jdk11-build
params: { state: "success", commit: "git-repo" }
- name: jdk15-build
- name: jdk17-build
serial: true
public: true
plan:
@@ -238,25 +257,57 @@ jobs:
- get: git-repo
- get: every-morning
trigger: true
- put: repo-status-jdk15-build
- put: repo-status-jdk17-build
params: { state: "pending", commit: "git-repo" }
- do:
- task: check-project
image: ci-image
file: git-repo/ci/tasks/check-project.yml
privileged: true
timeout: ((task-timeout))
params:
MAIN_TOOLCHAIN: 8
TEST_TOOLCHAIN: 15
<<: *build-project-task-params
<<: *build-project-task-params
on_failure:
do:
- put: repo-status-jdk15-build
- put: repo-status-jdk17-build
params: { state: "failure", commit: "git-repo" }
- put: slack-alert
params:
<<: *slack-fail-params
- put: repo-status-jdk15-build
- put: repo-status-jdk17-build
params: { state: "success", commit: "git-repo" }
- name: build-pull-requests
serial: true
public: true
plan:
- get: ci-image
- get: git-repo
resource: git-pull-request
trigger: true
version: every
- do:
- put: git-pull-request
params:
path: git-repo
status: pending
- task: build-pr
image: ci-image
file: git-repo/ci/tasks/build-pr.yml
privileged: true
timeout: ((task-timeout))
params:
BRANCH: ((branch))
on_success:
put: git-pull-request
params:
path: git-repo
status: success
on_failure:
put: git-pull-request
params:
path: git-repo
status: failure
- name: stage-milestone
serial: true
plan:
@@ -376,7 +427,7 @@ jobs:
trigger: false
passed: [stage-release]
params:
download_artifacts: false
download_artifacts: true
save_build_info: true
- task: promote
image: ci-image
@@ -407,8 +458,10 @@ jobs:
groups:
- name: "builds"
jobs: ["build", "jdk11-build", "jdk15-build"]
jobs: ["build", "jdk11-build", "jdk17-build"]
- name: "releases"
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"]
- name: "ci-images"
jobs: ["build-ci-images"]
- name: "pull-requests"
jobs: [ "build-pull-requests" ]
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
set -e
source $(dirname $0)/common.sh
pushd git-repo > /dev/null
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 check
popd > /dev/null
+2 -2
View File
@@ -4,6 +4,6 @@ set -e
source $(dirname $0)/common.sh
pushd git-repo > /dev/null
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Dorg.gradle.java.installations.fromEnv=JDK11,JDK15 \
-PmainToolchain=$MAIN_TOOLCHAIN -PtestToolchain=$TEST_TOOLCHAIN --no-daemon --max-workers=4 check
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK11,JDK15 \
-PmainToolchain=${MAIN_TOOLCHAIN} -PtestToolchain=${TEST_TOOLCHAIN} --no-daemon --max-workers=4 check
popd > /dev/null
+2 -2
View File
@@ -29,8 +29,8 @@ fi
echo "Staging $stageVersion (next version will be $nextVersion)"
sed -i "s/version=$snapshotVersion/version=$stageVersion/" gradle.properties
git config user.name "Spring Buildmaster" > /dev/null
git config user.email "buildmaster@springframework.org" > /dev/null
git config user.name "Spring Builds" > /dev/null
git config user.email "spring-builds@users.noreply.github.com" > /dev/null
git add gradle.properties > /dev/null
git commit -m"Release v$stageVersion" > /dev/null
git tag -a "v$stageVersion" -m"Release v$stageVersion" > /dev/null
+19
View File
@@ -0,0 +1,19 @@
---
platform: linux
inputs:
- name: git-repo
caches:
- path: gradle
params:
BRANCH:
CI: true
GRADLE_ENTERPRISE_ACCESS_KEY:
GRADLE_ENTERPRISE_CACHE_USERNAME:
GRADLE_ENTERPRISE_CACHE_PASSWORD:
GRADLE_ENTERPRISE_URL: https://ge.spring.io
run:
path: bash
args:
- -ec
- |
${PWD}/git-repo/ci/scripts/build-pr.sh
+2 -2
View File
@@ -1,10 +1,10 @@
---
platform: linux
image_resource:
type: docker-image
type: registry-image
source:
repository: springio/github-changelog-generator
tag: '0.0.6'
tag: '0.0.7'
inputs:
- name: git-repo
- name: artifactory-repo
+2 -2
View File
@@ -10,8 +10,8 @@ params:
ARTIFACTORY_SERVER:
ARTIFACTORY_USERNAME:
ARTIFACTORY_PASSWORD:
SONATYPE_USER_TOKEN:
SONATYPE_PASSWORD_TOKEN:
SONATYPE_USER:
SONATYPE_PASSWORD:
SONATYPE_URL:
SONATYPE_STAGING_PROFILE_ID:
run:
+1 -1
View File
@@ -1,4 +1,4 @@
version=5.3.5-SNAPSHOT
version=5.3.18
org.gradle.jvmargs=-Xmx1536M
org.gradle.caching=true
org.gradle.parallel=true
+30
View File
@@ -0,0 +1,30 @@
tasks.findByName("dokkaHtmlPartial")?.configure {
outputDirectory.set(new File(buildDir, "docs/kdoc"))
dokkaSourceSets {
configureEach {
sourceRoots.setFrom(file("src/main/kotlin"))
classpath.from(sourceSets["main"].runtimeClasspath)
externalDocumentationLink {
url.set(new URL("https://docs.spring.io/spring-framework/docs/current/javadoc-api/"))
}
externalDocumentationLink {
url.set(new URL("https://projectreactor.io/docs/core/release/api/"))
}
externalDocumentationLink {
url.set(new URL("https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/"))
}
externalDocumentationLink {
url.set(new URL("https://kotlin.github.io/kotlinx.coroutines/"))
}
externalDocumentationLink {
url.set(new URL("https://javadoc.io/doc/org.hamcrest/hamcrest/2.1/"))
}
externalDocumentationLink {
url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/"))
}
externalDocumentationLink {
url.set(new URL("https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/"))
}
}
}
}
+21 -55
View File
@@ -46,8 +46,9 @@ task api(type: Javadoc) {
stylesheetFile = file("src/docs/api/stylesheet.css")
splitIndex = true
links(project.ext.javadocLinks)
addStringOption('Xdoclint:none', '-quiet')
if(JavaVersion.current().isJava9Compatible()) {
addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint
addBooleanOption('Xwerror', true) // fail build on Javadoc warnings
if (JavaVersion.current().isJava9Compatible()) {
addBooleanOption('html5', true)
}
}
@@ -61,54 +62,13 @@ task api(type: Javadoc) {
/**
* Produce KDoc for all Spring Framework modules in "build/docs/kdoc"
*/
dokka {
dependsOn {
tasks.getByName("api")
}
doFirst {
configuration {
classpath = moduleProjects.collect { project -> project.jar.outputs.files.getFiles() }.flatten()
classpath += files(moduleProjects.collect { it.sourceSets.main.compileClasspath })
moduleProjects.findAll {
it.pluginManager.hasPlugin("kotlin")
}.each { project ->
def kotlinDirs = project.sourceSets.main.kotlin.srcDirs.collect()
kotlinDirs -= project.sourceSets.main.java.srcDirs
kotlinDirs.each { dir ->
if (dir.exists()) {
sourceRoot {
path = dir.path
}
}
}
}
}
}
outputFormat = "html"
outputDirectory = "$buildDir/docs/kdoc"
configuration {
moduleName = "spring-framework"
externalDocumentationLink {
url = new URL("https://docs.spring.io/spring-framework/docs/$version/javadoc-api/")
packageListUrl = new File(buildDir, "docs/javadoc/package-list").toURI().toURL()
}
externalDocumentationLink {
url = new URL("https://projectreactor.io/docs/core/release/api/")
}
externalDocumentationLink {
url = new URL("https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/")
}
externalDocumentationLink {
url = new URL("https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/")
}
externalDocumentationLink {
url = new URL("https://r2dbc.io/spec/0.8.3.RELEASE/api/")
pluginManager.withPlugin("kotlin") {
tasks.dokkaHtmlMultiModule.configure {
dependsOn {
tasks.getByName("api")
}
moduleName.set("spring-framework")
outputDirectory.set(project.file("$buildDir/docs/kdoc"))
}
}
@@ -127,6 +87,8 @@ task extractDocResources(type: Copy, dependsOn: downloadResources) {
}
asciidoctorj {
def docRoot = 'https://docs.spring.io'
def docsSpringFramework = "${docRoot}/spring-framework/docs/${project.version}"
version = '2.4.1'
fatalWarnings ".*"
options doctype: 'book', eruby: 'erubis'
@@ -134,7 +96,7 @@ asciidoctorj {
icons: 'font',
idprefix: '',
idseparator: '-',
docinfo: 'shared',
docinfo: 'shared,private-header', // https://docs.asciidoctor.org/asciidoctor/latest/docinfo/
revnumber: project.version,
sectanchors: '',
sectnums: '',
@@ -143,7 +105,11 @@ asciidoctorj {
'highlightjs-theme': 'googlecode',
stylesdir: 'css/',
stylesheet: 'stylesheet.css',
'spring-version': project.version
'spring-version': project.version,
'spring-framework-main-code': 'https://github.com/spring-projects/spring-framework/tree/main',
'doc-root': docRoot,
'docs-spring-framework': docsSpringFramework,
'api-spring-framework': "${docsSpringFramework}/javadoc-api/org/springframework"
])
}
@@ -184,7 +150,7 @@ asciidoctorPdf {
/**
* Zip all docs (API and reference) into a single archive
*/
task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dokka']) {
task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dokkaHtmlMultiModule']) {
group = "Distribution"
description = "Builds -${archiveClassifier} archive containing api and reference " +
"for deployment at https://docs.spring.io/spring-framework/docs."
@@ -203,7 +169,7 @@ task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dok
from ("$asciidoctorPdf.outputDir") {
into "reference/pdf"
}
from (dokka) {
from (dokkaHtmlMultiModule.outputDirectory) {
into "kdoc-api"
}
}
@@ -260,11 +226,11 @@ task distZip(type: Zip, dependsOn: [docsZip, schemaZip]) {
expand(copyright: new Date().format("yyyy"), version: project.version)
}
from(zipTree(docsZip.archivePath)) {
from(zipTree(docsZip.archiveFile)) {
into "${baseDir}/docs"
}
from(zipTree(schemaZip.archivePath)) {
from(zipTree(schemaZip.archiveFile)) {
into "${baseDir}/schema"
}
+27 -67
View File
@@ -1,7 +1,7 @@
import org.gradle.plugins.ide.eclipse.model.ProjectDependency
import org.gradle.plugins.ide.eclipse.model.SourceFolder
apply plugin: "eclipse"
apply plugin: 'eclipse'
eclipse.jdt {
sourceCompatibility = 1.8
@@ -18,40 +18,45 @@ eclipse.classpath.file.whenMerged { classpath ->
if (matcher) {
def projectName = matcher[0][1]
def path = "/${projectName}"
if(!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) {
def dependency = new ProjectDependency(path)
dependency.exported = true
classpath.entries.add(dependency)
if (!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) {
def recursiveDependency = entry.path.matches('.+/' + projectName + '/build/([^/]+/)+(?:main|test)')
// Avoid recursive dependency on current project.
if (!recursiveDependency) {
classpath.entries.add(new ProjectDependency(path))
}
}
classpath.entries.remove(entry)
}
}
// Remove any remaining direct depencencies on JARs in the build/libs folder
// except Spring's spring-cglib-repack and spring-objenesis-repack JARs.
classpath.entries.removeAll { entry -> (entry.path =~ /(?!.*?repack.*\.jar).*?\/([^\/]+)\/build\/libs\/[^\/]+\.jar/) }
}
// Use separate main/test outputs (prevents WTP from packaging test classes)
eclipse.classpath.defaultOutputDir = file(project.name+"/bin/eclipse")
eclipse.classpath.defaultOutputDir = file(project.name + '/bin/eclipse')
eclipse.classpath.file.beforeMerged { classpath ->
classpath.entries.findAll{ it instanceof SourceFolder }.each {
if (it.output.startsWith("bin/")) {
if (it.output.startsWith('bin/')) {
it.output = null
}
}
}
eclipse.classpath.file.whenMerged { classpath ->
classpath.entries.findAll{ it instanceof SourceFolder }.each {
it.output = "bin/" + it.path.split("/")[1]
eclipse.classpath.file.whenMerged {
entries.findAll{ it instanceof SourceFolder }.each {
it.output = 'bin/' + it.path.split('/')[1]
}
}
// Ensure project dependencies come after 3rd-party libs (SPR-11836)
// https://jira.spring.io/browse/SPR-11836
eclipse.classpath.file.whenMerged { classpath ->
classpath.entries.findAll { it instanceof ProjectDependency }.each {
eclipse.classpath.file.whenMerged {
entries.findAll { it instanceof ProjectDependency }.each {
// delete from original position
classpath.entries.remove(it)
entries.remove(it)
// append to end of classpath
classpath.entries.add(it)
entries.add(it)
}
}
@@ -64,65 +69,20 @@ eclipse.classpath.file.whenMerged {
}
}
// Allow projects to be used as WTP modules
eclipse.project.natures "org.eclipse.wst.common.project.facet.core.nature"
// Include project specific settings
task eclipseSettings(type: Copy) {
from rootProject.files(
"src/eclipse/org.eclipse.jdt.ui.prefs",
"src/eclipse/org.eclipse.wst.common.project.facet.core.xml")
'src/eclipse/org.eclipse.jdt.core.prefs',
'src/eclipse/org.eclipse.jdt.ui.prefs')
into project.file('.settings/')
outputs.upToDateWhen { false }
}
task eclipseWstComponent(type: Copy) {
from rootProject.files(
"src/eclipse/org.eclipse.wst.common.component")
into project.file('.settings/')
expand(deployname: project.name)
outputs.upToDateWhen { false }
task cleanEclipseSettings(type: Delete) {
delete project.file('.settings/org.eclipse.jdt.core.prefs')
delete project.file('.settings/org.eclipse.jdt.ui.prefs')
}
task eclipseJdtPrepare(type: Copy) {
from rootProject.file("src/eclipse/org.eclipse.jdt.core.prefs")
into project.file(".settings/")
outputs.upToDateWhen { false }
}
task cleanEclipseJdtUi(type: Delete) {
delete project.file(".settings/org.eclipse.jdt.core.prefs")
delete project.file(".settings/org.eclipse.jdt.ui.prefs")
delete project.file(".settings/org.eclipse.wst.common.component")
delete project.file(".settings/org.eclipse.wst.common.project.facet.core.xml")
}
task eclipseBuildship(type: Copy) {
from rootProject.files(
"src/eclipse/org.eclipse.jdt.ui.prefs",
"src/eclipse/org.eclipse.jdt.core.prefs")
into project.file('.settings/')
outputs.upToDateWhen { false }
}
tasks["eclipseJdt"].dependsOn(eclipseJdtPrepare)
tasks["cleanEclipse"].dependsOn(cleanEclipseJdtUi)
tasks["eclipse"].dependsOn(eclipseSettings, eclipseWstComponent)
// Filter 'build' folder
eclipse.project.file.withXml {
def node = it.asNode()
def filteredResources = node.get("filteredResources")
if(filteredResources) {
node.remove(filteredResources)
}
def filterNode = node.appendNode("filteredResources").appendNode("filter")
filterNode.appendNode("id", "1359048889071")
filterNode.appendNode("name", "")
filterNode.appendNode("type", "30")
def matcherNode = filterNode.appendNode("matcher")
matcherNode.appendNode("id", "org.eclipse.ui.ide.multiFilter")
matcherNode.appendNode("arguments", "1.0-projectRelativePath-matches-false-false-build")
}
tasks['eclipse'].dependsOn(eclipseSettings)
tasks['eclipseJdt'].dependsOn(eclipseSettings)
tasks['cleanEclipse'].dependsOn(cleanEclipseSettings)
+8 -4
View File
@@ -4,19 +4,23 @@ apply plugin: 'org.springframework.build.optional-dependencies'
// Uncomment the following for Shadow support in the jmhJar block.
// Currently commented out due to ZipException: archive is not a ZIP archive
// apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'me.champeau.gradle.jmh'
apply plugin: 'me.champeau.jmh'
apply from: "$rootDir/gradle/publications.gradle"
dependencies {
jmh 'org.openjdk.jmh:jmh-core:1.25'
jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.25'
jmh 'net.sf.jopt-simple:jopt-simple:4.6'
jmh 'org.openjdk.jmh:jmh-core:1.32'
jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.32'
jmh 'net.sf.jopt-simple:jopt-simple'
}
jmh {
duplicateClassesStrategy = DuplicatesStrategy.EXCLUDE
}
tasks.findByName("processJmhResources").configure {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
jmhJar {
// Uncomment the following for Shadow's Transformer support.
// mergeServiceFiles()
+76 -21
View File
@@ -11,6 +11,8 @@
* <li>a JDK11 toolchain for compiling and running the test SourceSet
* </ul>
*
* By default, the build will fall back to using the current JDK and 1.8 language level for all sourceSets.
*
* Gradle will automatically detect JDK distributions in well-known locations.
* The following command will list the detected JDKs on the host.
* {@code
@@ -23,21 +25,41 @@
* /opt/openjdk/java11
* $ echo JDK15
* /opt/openjdk/java15
* $ ./gradlew -Dorg.gradle.java.installations.fromEnv=JDK11,JDK15 check
* $ ./gradlew -Porg.gradle.java.installations.fromEnv=JDK11,JDK15 check
* }
*
* @author Brian Clozel
* @author Sam Brannen
*/
def mainToolchain = 'mainToolchain'
def testToolchain = 'testToolchain'
def mainToolchainConfigured() {
return project.hasProperty('mainToolchain') && project.mainToolchain
}
def testToolchainConfigured() {
return project.hasProperty('testToolchain') && project.testToolchain
}
def mainToolchainLanguageVersion() {
if (mainToolchainConfigured()) {
return JavaLanguageVersion.of(project.mainToolchain.toString())
}
return JavaLanguageVersion.of(8)
}
def testToolchainLanguageVersion() {
if (testToolchainConfigured()) {
return JavaLanguageVersion.of(project.testToolchain.toString())
}
return mainToolchainLanguageVersion()
}
plugins.withType(JavaPlugin) {
// Configure the Java Toolchain if the 'mainToolchain' property is defined
if (project.hasProperty(mainToolchain)) {
def mainLanguageVersion = JavaLanguageVersion.of(project.property(mainToolchain).toString())
// Configure the Java Toolchain if the 'mainToolchain' is configured
if (mainToolchainConfigured()) {
java {
toolchain {
languageVersion = mainLanguageVersion
languageVersion = mainToolchainLanguageVersion()
}
}
}
@@ -48,8 +70,8 @@ plugins.withType(JavaPlugin) {
}
}
// Configure a specific Java Toolchain for compiling and running tests if the 'testToolchain' property is defined
if (project.hasProperty(testToolchain)) {
def testLanguageVersion = JavaLanguageVersion.of(project.property(testToolchain).toString());
if (testToolchainConfigured()) {
def testLanguageVersion = testToolchainLanguageVersion()
tasks.withType(JavaCompile).matching { it.name.contains("Test") }.configureEach {
javaCompiler = javaToolchains.compilerFor {
languageVersion = testLanguageVersion
@@ -65,17 +87,17 @@ plugins.withType(JavaPlugin) {
plugins.withType(GroovyPlugin) {
// Fallback to JDK8
if (!project.hasProperty(mainToolchain)) {
if (!mainToolchainConfigured()) {
compileGroovy {
sourceCompatibility = JavaVersion.VERSION_1_8
}
}
}
// Configure the Kotlin compiler if the 'mainToolchain' property is defined
pluginManager.withPlugin("kotlin") {
if (project.hasProperty(mainToolchain)) {
def mainLanguageVersion = JavaLanguageVersion.of(project.property(mainToolchain).toString());
// Configure the Kotlin compiler if the 'mainToolchain' property is defined
if (mainToolchainConfigured()) {
def mainLanguageVersion = mainToolchainLanguageVersion()
def compiler = javaToolchains.compilerFor {
languageVersion = mainLanguageVersion
}
@@ -96,15 +118,21 @@ pluginManager.withPlugin("kotlin") {
}
}
else {
// Fallback to JDK8
compileKotlin {
kotlinOptions {
jvmTarget = '1.8'
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = '1.8'
}
}
}
if (project.hasProperty(testToolchain)) {
def testLanguageVersion = JavaLanguageVersion.of(project.property(testToolchain).toString());
if (testToolchainConfigured()) {
def testLanguageVersion = testToolchainLanguageVersion()
def compiler = javaToolchains.compilerFor {
languageVersion = testLanguageVersion
}
@@ -117,11 +145,38 @@ pluginManager.withPlugin("kotlin") {
}
}
}
else {
compileTestKotlin {
kotlinOptions {
jvmTarget = '1.8'
}
// Configure the JMH plugin to use the toolchain for generating and running JMH bytecode
pluginManager.withPlugin("me.champeau.jmh") {
if (mainToolchainConfigured() || testToolchainConfigured()) {
tasks.matching { it.name.contains('jmh') && it.hasProperty('javaLauncher') }.configureEach {
javaLauncher.set(javaToolchains.launcherFor {
languageVersion.set(testToolchainLanguageVersion())
})
}
tasks.withType(JavaCompile).matching { it.name.contains("Jmh") }.configureEach {
javaCompiler = javaToolchains.compilerFor {
languageVersion = testToolchainLanguageVersion()
}
}
}
}
}
// Store resolved Toolchain JVM information as custom values in the build scan.
rootProject.ext {
resolvedMainToolchain = false
resolvedTestToolchain = false
}
gradle.taskGraph.afterTask { Task task, TaskState state ->
if (mainToolchainConfigured() && !resolvedMainToolchain && task instanceof JavaCompile && task.javaCompiler.isPresent()) {
def metadata = task.javaCompiler.get().metadata
task.project.buildScan.value('Main toolchain', "$metadata.vendor $metadata.languageVersion ($metadata.installationPath)")
resolvedMainToolchain = true
}
if (testToolchainConfigured() && !resolvedTestToolchain && task instanceof Test && task.javaLauncher.isPresent()) {
def metadata = task.javaLauncher.get().metadata
task.project.buildScan.value('Test toolchain', "$metadata.vendor $metadata.languageVersion ($metadata.installationPath)")
resolvedTestToolchain = true
}
}
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+159 -110
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,67 +17,101 @@
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@@ -106,80 +140,95 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
+24 -20
View File
@@ -3,11 +3,11 @@
This document will guide you through the process of importing the Spring Framework
projects into Eclipse or the Spring Tool Suite (_STS_). It is recommended that you
have a recent version of Eclipse. As a bare minimum you will need Eclipse with full Java
8 support, Eclipse Buildship, the Kotlin plugin, and the Groovy plugin.
8 support, Eclipse Buildship, and the Groovy plugin.
The following instructions have been tested against [STS](https://spring.io/tools) 4.3.2
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-432-changelog))
(based on Eclipse 4.12) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship).
The following instructions have been tested against [STS](https://spring.io/tools) 4.12.0
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-4120-changelog))
(based on Eclipse 4.21) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship).
The instructions should work with the latest Eclipse distribution as long as you install
[Buildship](https://marketplace.eclipse.org/content/buildship-gradle-integration). Note
that STS 4 comes with Buildship preinstalled.
@@ -16,28 +16,32 @@ that STS 4 comes with Buildship preinstalled.
_When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._
1. Ensure that Eclipse launches with JDK 8.
- For example, on Mac OS this can be configured in the `Info.plist` file located in the `Contents` folder of the installed Eclipse or STS application (e.g., the `Eclipse.app` file).
1. Install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) in Eclipse.
1. Install the [Eclipse Groovy Development Tools](https://github.com/groovy/groovy-eclipse/wiki) in Eclipse.
1. Switch to Groovy 2.5 (Preferences -> Groovy -> Compiler -> Switch to 2.5...) in Eclipse.
1. Change the _Forbidden reference (access rule)_ in Eclipse from Error to Warning
(Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API -> Forbidden reference (access rule)).
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project. The AspectJ Development Tools available in the Eclipse Marketplace have been tested with these instructions using STS 4.5 (Eclipse 4.14).
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute TestNG tests in the `spring-test` module.
1. Install the [Groovy Development Tools](https://marketplace.eclipse.org/content/groovy-development-tools).
1. Switch to Groovy 3.0 in Eclipse (Preferences &#8594; Groovy &#8594; Compiler &#8594; Switch to 3.0...).
- If you encounter build errors stating something similar to _"Groovy: compiler mismatch: project level is 2.5, workspace level is 3.0"_, change the Groovy compiler version to 3.0 for each affected project.
1. Ensure that the _Forbidden reference (access rule)_ in Eclipse is set to `Info`
(Preferences &#8594; Java &#8594; Compiler &#8594; Errors/Warnings &#8594; Deprecated and restricted API &#8594; Forbidden reference (access rule)).
1. Optionally install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) if you need to execute Kotlin-based tests or develop Kotlin extensions.
- **NOTE**: As of September 21, 2021, it appears that the Kotlin Plugin for Eclipse does not yet work with Eclipse 4.21.
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project.
- **NOTE**: As of September 21, 2021, it appears that the AspectJ Development Tools do not yet work with Eclipse 4.21.
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute individual TestNG test classes or tests in the `spring-test` module.
- As an alternative to installing the TestNG plugin, you can execute the `org.springframework.test.context.testng.TestNGTestSuite` class as a "JUnit 5" test class in Eclipse.
1. Build `spring-oxm` from the command line with `./gradlew :spring-oxm:check`.
1. To apply project specific settings, run `./gradlew eclipseBuildship` from the command line.
1. Import into Eclipse (File -> Import -> Gradle -> Existing Gradle Project -> Navigate to the locally cloned `spring-framework` directory -> Select Finish).
1. To apply Spring Framework specific settings, run `./gradlew cleanEclipse eclipse` from the command line.
1. Import all projects into Eclipse (File &#8594; Import &#8594; Gradle &#8594; Existing Gradle Project &#8594; Navigate to the locally cloned `spring-framework` directory &#8594; Select Finish).
- If you have not installed AJDT, exclude the `spring-aspects` project from the import, if prompted, or close it after the import.
- If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences -> Gradle -> Java home).
1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select `Build Path -> Use as Source Folder`).
- If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the small downward facing arrow in the upper right corner of the Package Explorer).
- If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences &#8594; Gradle &#8594; Java home).
1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select "Build Path &#8594; Use as Source Folder").
- If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the _three vertical dots_ in the upper right corner of the Package Explorer).
1. Code away!
## Known Issues
1. `spring-core` and `spring-oxm` should be pre-compiled due to repackaged dependencies.
- See `*RepackJar` tasks in the build.
1. `spring-core` should be pre-compiled due to repackaged dependencies.
- See `*RepackJar` tasks in the `spring-core.gradle` build file.
1. `spring-oxm` should be pre-compiled due to JAXB types generated for tests.
- Note that executing `./gradlew :spring-oxm:check` as explained in the _Steps_ above will compile `spring-core` and generate JAXB types for `spring-oxm`.
1. `spring-aspects` does not compile due to references to aspect types unknown to Eclipse.
- If you installed _AJDT_ into Eclipse it should work.
1. While JUnit tests pass from the command line with Gradle, some may fail when run from
+20 -20
View File
@@ -1,26 +1,26 @@
description = "Spring Integration Tests"
dependencies {
testCompile(project(":spring-aop"))
testCompile(project(":spring-beans"))
testCompile(project(":spring-context"))
testCompile(project(":spring-core"))
testCompile(testFixtures(project(":spring-aop")))
testCompile(testFixtures(project(":spring-beans")))
testCompile(testFixtures(project(":spring-core")))
testCompile(testFixtures(project(":spring-tx")))
testCompile(project(":spring-expression"))
testCompile(project(":spring-jdbc"))
testCompile(project(":spring-orm"))
testCompile(project(":spring-test"))
testCompile(project(":spring-tx"))
testCompile(project(":spring-web"))
testCompile("javax.inject:javax.inject")
testCompile("javax.resource:javax.resource-api")
testCompile("javax.servlet:javax.servlet-api")
testCompile("org.aspectj:aspectjweaver")
testCompile("org.hsqldb:hsqldb")
testCompile("org.hibernate:hibernate-core")
testImplementation(project(":spring-aop"))
testImplementation(project(":spring-beans"))
testImplementation(project(":spring-context"))
testImplementation(project(":spring-core"))
testImplementation(testFixtures(project(":spring-aop")))
testImplementation(testFixtures(project(":spring-beans")))
testImplementation(testFixtures(project(":spring-core")))
testImplementation(testFixtures(project(":spring-tx")))
testImplementation(project(":spring-expression"))
testImplementation(project(":spring-jdbc"))
testImplementation(project(":spring-orm"))
testImplementation(project(":spring-test"))
testImplementation(project(":spring-tx"))
testImplementation(project(":spring-web"))
testImplementation("javax.inject:javax.inject")
testImplementation("javax.resource:javax.resource-api")
testImplementation("javax.servlet:javax.servlet-api")
testImplementation("org.aspectj:aspectjweaver")
testImplementation("org.hsqldb:hsqldb")
testImplementation("org.hibernate:hibernate-core")
}
normalization {
@@ -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.
@@ -34,7 +34,6 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ScopeMetadata;
import org.springframework.context.annotation.ScopeMetadataResolver;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
@@ -307,29 +306,26 @@ class ClassPathBeanDefinitionScannerJsr330ScopeIntegrationTests {
GenericWebApplicationContext context = new GenericWebApplicationContext();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.setIncludeAnnotationConfig(false);
scanner.setScopeMetadataResolver(new ScopeMetadataResolver() {
@Override
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
for (String type : annDef.getMetadata().getAnnotationTypes()) {
if (type.equals(javax.inject.Singleton.class.getName())) {
metadata.setScopeName(BeanDefinition.SCOPE_SINGLETON);
break;
}
else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(javax.inject.Scope.class.getName())) {
metadata.setScopeName(type.substring(type.length() - 13, type.length() - 6).toLowerCase());
metadata.setScopedProxyMode(scopedProxyMode);
break;
}
else if (type.startsWith("javax.inject")) {
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
}
scanner.setScopeMetadataResolver(definition -> {
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
for (String type : annDef.getMetadata().getAnnotationTypes()) {
if (type.equals(javax.inject.Singleton.class.getName())) {
metadata.setScopeName(BeanDefinition.SCOPE_SINGLETON);
break;
}
else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(javax.inject.Scope.class.getName())) {
metadata.setScopeName(type.substring(type.length() - 13, type.length() - 6).toLowerCase());
metadata.setScopedProxyMode(scopedProxyMode);
break;
}
else if (type.startsWith("javax.inject")) {
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
}
}
return metadata;
}
return metadata;
});
// Scan twice in order to find errors in the bean definition compatibility check.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -74,7 +74,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
MyRepository repository = ctx.getBean(MyRepository.class);
CallCountingTransactionManager txManager = ctx.getBean(CallCountingTransactionManager.class);
assertThat(AopUtils.isCglibProxy(repository)).isEqualTo(true);
assertThat(AopUtils.isCglibProxy(repository)).isTrue();
assertThat(repository.getInvocationCount()).isGreaterThan(0);
assertThat(txManager.commits).isGreaterThan(0);
}
+5 -12
View File
@@ -1,13 +1,14 @@
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
maven { url 'https://repo.spring.io/plugins-release' }
maven { url "https://repo.spring.io/release" }
}
}
plugins {
id "com.gradle.enterprise" version "3.5.1"
id "io.spring.ge.conventions" version "0.0.7"
id "com.gradle.enterprise" version "3.8.1"
id "io.spring.ge.conventions" version "0.0.9"
}
include "spring-aop"
@@ -17,8 +18,6 @@ include "spring-context"
include "spring-context-indexer"
include "spring-context-support"
include "spring-core"
include "kotlin-coroutines"
project(':kotlin-coroutines').projectDir = file('spring-core/kotlin-coroutines')
include "spring-expression"
include "spring-instrument"
include "spring-jcl"
@@ -45,19 +44,13 @@ rootProject.children.each {project ->
settings.gradle.projectsLoaded {
gradleEnterprise {
buildScan {
if (settings.gradle.rootProject.hasProperty('mainToolchain')) {
value("Main toolchain", 'JDK' + settings.gradle.rootProject.getProperty('mainToolchain'))
}
if (settings.gradle.rootProject.hasProperty('testToolchain')) {
value("Test toolchain", 'JDK' + settings.gradle.rootProject.getProperty('testToolchain'))
}
File buildDir = settings.gradle.rootProject.getBuildDir()
buildDir.mkdirs()
new File(buildDir, "build-scan-uri.txt").text = "(build scan not generated)"
buildScanPublished { scan ->
if (buildDir.exists()) {
new File(buildDir, "build-scan-uri.txt").text = "${scan.buildScanUri}\n"
}
}
}
}
}
+5 -4
View File
@@ -1,12 +1,13 @@
description = "Spring AOP"
dependencies {
compile(project(":spring-beans"))
compile(project(":spring-core"))
api(project(":spring-beans"))
api(project(":spring-core"))
optional("org.aspectj:aspectjweaver")
optional("org.apache.commons:commons-pool2")
optional("com.jamonapi:jamon")
testCompile(testFixtures(project(":spring-beans")))
testCompile(testFixtures(project(":spring-core")))
testImplementation(testFixtures(project(":spring-beans")))
testImplementation(testFixtures(project(":spring-core")))
testFixturesImplementation(testFixtures(project(":spring-beans")))
testFixturesImplementation(testFixtures(project(":spring-core")))
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2021 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 javax.annotation.Nullable;
* terminology).
*
* <p>A runtime joinpoint is an <i>event</i> that occurs on a static
* joinpoint (i.e. a location in a the program). For instance, an
* joinpoint (i.e. a location in a program). For instance, an
* invocation is the runtime joinpoint on a method (static joinpoint).
* The static part of a given joinpoint can be generically retrieved
* using the {@link #getStaticPart()} method.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -625,7 +625,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
StringBuilder sb = new StringBuilder();
if (bodyStart >= 0 && bodyStart != (currentToken.length() - 1)) {
sb.append(currentToken.substring(bodyStart + 1));
sb.append(" ");
sb.append(' ');
}
numTokensConsumed++;
int currentIndex = startIndex + numTokensConsumed;
@@ -645,7 +645,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
toAppend = toAppend.substring(1);
}
sb.append(toAppend);
sb.append(" ");
sb.append(' ');
currentIndex++;
numTokensConsumed++;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -547,7 +547,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
StringBuilder sb = new StringBuilder("AspectJExpressionPointcut: (");
for (int i = 0; i < this.pointcutParameterTypes.length; i++) {
sb.append(this.pointcutParameterTypes[i].getName());
sb.append(" ");
sb.append(' ');
sb.append(this.pointcutParameterNames[i]);
if ((i+1) < this.pointcutParameterTypes.length) {
sb.append(", ");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -255,19 +255,19 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
StringBuilder sb = new StringBuilder();
if (includeModifier) {
sb.append(Modifier.toString(getModifiers()));
sb.append(" ");
sb.append(' ');
}
if (includeReturnTypeAndArgs) {
appendType(sb, getReturnType(), useLongReturnAndArgumentTypeName);
sb.append(" ");
sb.append(' ');
}
appendType(sb, getDeclaringType(), useLongTypeName);
sb.append(".");
sb.append('.');
sb.append(getMethod().getName());
sb.append("(");
sb.append('(');
Class<?>[] parametersTypes = getParameterTypes();
appendTypes(sb, parametersTypes, includeReturnTypeAndArgs, useLongReturnAndArgumentTypeName);
sb.append(")");
sb.append(')');
return sb.toString();
}
@@ -278,7 +278,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
for (int size = types.length, i = 0; i < size; i++) {
appendType(sb, types[i], useLongReturnAndArgumentTypeName);
if (i < size - 1) {
sb.append(",");
sb.append(',');
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -103,10 +103,11 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
@Override
public void validate(Class<?> aspectClass) throws AopConfigException {
// If the parent has the annotation and isn't abstract it's an error
if (aspectClass.getSuperclass().getAnnotation(Aspect.class) != null &&
!Modifier.isAbstract(aspectClass.getSuperclass().getModifiers())) {
Class<?> superclass = aspectClass.getSuperclass();
if (superclass.getAnnotation(Aspect.class) != null &&
!Modifier.isAbstract(superclass.getModifiers())) {
throw new AopConfigException("[" + aspectClass.getName() + "] cannot extend concrete aspect [" +
aspectClass.getSuperclass().getName() + "]");
superclass.getName() + "]");
}
AjType<?> ajType = AjTypeSystem.getAjType(aspectClass);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -34,7 +34,7 @@ import org.springframework.util.ClassUtils;
/**
* AspectJ-based proxy factory, allowing for programmatic building
* of proxies which include AspectJ aspects (code style as well
* Java 5 annotation style).
* annotation style).
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -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.
@@ -60,8 +60,8 @@ public class AspectMetadata implements Serializable {
private final Class<?> aspectClass;
/**
* AspectJ reflection information (AspectJ 5 / Java 5 specific).
* Re-resolved on deserialization since it isn't serializable itself.
* AspectJ reflection information.
* <p>Re-resolved on deserialization since it isn't serializable itself.
*/
private transient AjType<?> ajType;
@@ -521,8 +521,8 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
copy.copyFrom(this);
copy.targetSource = EmptyTargetSource.forClass(getTargetClass(), getTargetSource().isStatic());
copy.advisorChainFactory = this.advisorChainFactory;
copy.interfaces = this.interfaces;
copy.advisors = this.advisors;
copy.interfaces = new ArrayList<>(this.interfaces);
copy.advisors = new ArrayList<>(this.advisors);
return copy;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -19,7 +19,9 @@ package org.springframework.aop.framework;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetClassAware;
@@ -29,7 +31,9 @@ import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.core.DecoratingProxy;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
/**
* Utility methods for AOP proxy factories.
@@ -40,10 +44,16 @@ import org.springframework.util.ObjectUtils;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @see org.springframework.aop.support.AopUtils
*/
public abstract class AopProxyUtils {
// JDK 17 Class.isSealed() method available?
@Nullable
private static final Method isSealedMethod = ClassUtils.getMethodIfAvailable(Class.class, "isSealed");
/**
* Obtain the singleton target object behind the given proxy, if any.
* @param candidate the (potential) proxy to check
@@ -124,40 +134,29 @@ public abstract class AopProxyUtils {
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
else if (Proxy.isProxyClass(targetClass)) {
else if (Proxy.isProxyClass(targetClass) || isLambda(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
specifiedInterfaces = advised.getProxiedInterfaces();
}
}
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
int nonUserIfcCount = 0;
if (addSpringProxy) {
nonUserIfcCount++;
List<Class<?>> proxiedInterfaces = new ArrayList<>(specifiedInterfaces.length + 3);
for (Class<?> ifc : specifiedInterfaces) {
// Only non-sealed interfaces are actually eligible for JDK proxying (on JDK 17)
if (isSealedMethod == null || Boolean.FALSE.equals(ReflectionUtils.invokeMethod(isSealedMethod, ifc))) {
proxiedInterfaces.add(ifc);
}
}
if (addAdvised) {
nonUserIfcCount++;
if (!advised.isInterfaceProxied(SpringProxy.class)) {
proxiedInterfaces.add(SpringProxy.class);
}
if (addDecoratingProxy) {
nonUserIfcCount++;
if (!advised.isOpaque() && !advised.isInterfaceProxied(Advised.class)) {
proxiedInterfaces.add(Advised.class);
}
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
int index = specifiedInterfaces.length;
if (addSpringProxy) {
proxiedInterfaces[index] = SpringProxy.class;
index++;
if (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class)) {
proxiedInterfaces.add(DecoratingProxy.class);
}
if (addAdvised) {
proxiedInterfaces[index] = Advised.class;
index++;
}
if (addDecoratingProxy) {
proxiedInterfaces[index] = DecoratingProxy.class;
}
return proxiedInterfaces;
return ClassUtils.toClassArray(proxiedInterfaces);
}
/**
@@ -246,4 +245,18 @@ public abstract class AopProxyUtils {
return arguments;
}
/**
* Determine if the supplied {@link Class} is a JVM-generated implementation
* class for a lambda expression or method reference.
* <p>This method makes a best-effort attempt at determining this, based on
* checks that work on modern, main stream JVMs.
* @param clazz the class to check
* @return {@code true} if the class is a lambda implementation class
* @since 5.3.16
*/
static boolean isLambda(Class<?> clazz) {
return (clazz.isSynthetic() && (clazz.getSuperclass() == Object.class) &&
(clazz.getInterfaces().length > 0) && clazz.getName().contains("$$Lambda"));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -237,7 +237,7 @@ class CglibAopProxy implements AopProxy, Serializable {
* validates it if not.
*/
private void validateClassIfNecessary(Class<?> proxySuperClass, @Nullable ClassLoader proxyClassLoader) {
if (logger.isWarnEnabled()) {
if (!this.advised.isOptimize() && logger.isInfoEnabled()) {
synchronized (validatedClasses) {
if (!validatedClasses.containsKey(proxySuperClass)) {
doValidateClass(proxySuperClass, proxyClassLoader,
@@ -679,13 +679,19 @@ class CglibAopProxy implements AopProxy, Serializable {
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
try {
retVal = methodProxy.invoke(target, argsToUse);
}
catch (CodeGenerationException ex) {
CglibMethodInvocation.logFastClassGenerationFailure(method);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
}
else {
// We need to create a method invocation...
@@ -737,10 +743,7 @@ class CglibAopProxy implements AopProxy, Serializable {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
// Only use method proxy for public methods not derived from java.lang.Object
this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
methodProxy : null);
this.methodProxy = (isMethodProxyCompatible(method) ? methodProxy : null);
}
@Override
@@ -776,10 +779,25 @@ class CglibAopProxy implements AopProxy, Serializable {
@Override
protected Object invokeJoinpoint() throws Throwable {
if (this.methodProxy != null) {
return this.methodProxy.invoke(this.target, this.arguments);
try {
return this.methodProxy.invoke(this.target, this.arguments);
}
catch (CodeGenerationException ex) {
logFastClassGenerationFailure(this.method);
}
}
else {
return super.invokeJoinpoint();
return super.invokeJoinpoint();
}
static boolean isMethodProxyCompatible(Method method) {
return (Modifier.isPublic(method.getModifiers()) &&
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method));
}
static void logFastClassGenerationFailure(Method method) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to generate CGLIB fast class for method: " + method);
}
}
}
@@ -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.
@@ -40,14 +40,16 @@ import org.springframework.core.NativeDetector;
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sebastien Deleuze
* @author Sam Brannen
* @since 12.03.2004
* @see AdvisedSupport#setOptimize
* @see AdvisedSupport#setProxyTargetClass
* @see AdvisedSupport#setInterfaces
*/
@SuppressWarnings("serial")
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
private static final long serialVersionUID = 7930414337282325166L;
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
@@ -58,7 +60,7 @@ public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || AopProxyUtils.isLambda(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -73,11 +73,9 @@ public class ProxyConfig implements Serializable {
* The exact meaning of "aggressive optimizations" will differ
* between proxies, but there is usually some tradeoff.
* Default is "false".
* <p>For example, optimization will usually mean that advice changes won't
* take effect after a proxy has been created. For this reason, optimization
* is disabled by default. An optimize value of "true" may be ignored
* if other settings preclude optimization: for example, if "exposeProxy"
* is set to "true" and that's not compatible with the optimization.
* <p>With Spring's current proxy options, this flag effectively
* enforces CGLIB proxies (similar to {@link #setProxyTargetClass})
* but without any class validation checks (for final methods etc).
*/
public void setOptimize(boolean optimize) {
this.optimize = optimize;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -421,11 +421,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
* are unaffected by such changes.
*/
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
if (this.advisorChainInitialized) {
return;
}
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
if (!this.advisorChainInitialized && !ObjectUtils.isEmpty(this.interceptorNames)) {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
@@ -464,9 +460,9 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
addAdvisorOnChainCreation(advice);
}
}
}
this.advisorChainInitialized = true;
this.advisorChainInitialized = true;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2021 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.
@@ -25,8 +25,8 @@ import org.springframework.aop.Advisor;
import org.springframework.aop.ThrowsAdvice;
/**
* Adapter to enable {@link org.springframework.aop.MethodBeforeAdvice}
* to be used in the Spring AOP framework.
* Adapter to enable {@link org.springframework.aop.ThrowsAdvice} to be used
* in the Spring AOP framework.
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -17,6 +17,7 @@
package org.springframework.aop.framework.autoproxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -440,7 +441,17 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (proxyFactory.isProxyTargetClass()) {
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
if (Proxy.isProxyClass(beanClass)) {
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
}
else {
// No proxyTargetClass flag enforced, let's apply our default checks...
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
@@ -510,7 +521,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
if (specificInterceptors.length > 0) {
// specificInterceptors may equals PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS
// specificInterceptors may equal PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS
allInterceptors.addAll(Arrays.asList(specificInterceptors));
}
if (commonInterceptors.length > 0) {
@@ -61,7 +61,7 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
* FactoryBean will get proxied. This default behavior applies as of Spring 2.0.
* If you intend to proxy a FactoryBean instance itself (a rare use case, but
* Spring 1.2's default behavior), specify the bean name of the FactoryBean
* including the factory-bean prefix "&": e.g. "&myFactoryBean".
* including the factory-bean prefix "&amp;": e.g. "&amp;myFactoryBean".
* @see org.springframework.beans.factory.FactoryBean
* @see org.springframework.beans.factory.BeanFactory#FACTORY_BEAN_PREFIX
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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.
@@ -125,12 +125,8 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
*/
protected DefaultListableBeanFactory getInternalBeanFactoryForBean(String beanName) {
synchronized (this.internalBeanFactories) {
DefaultListableBeanFactory internalBeanFactory = this.internalBeanFactories.get(beanName);
if (internalBeanFactory == null) {
internalBeanFactory = buildInternalBeanFactory(this.beanFactory);
this.internalBeanFactories.put(beanName, internalBeanFactory);
}
return internalBeanFactory;
return this.internalBeanFactories.computeIfAbsent(beanName,
name -> buildInternalBeanFactory(this.beanFactory));
}
}
@@ -25,9 +25,11 @@ import org.springframework.lang.Nullable;
/**
* Convenient TargetSourceCreator using bean name prefixes to create one of three
* well-known TargetSource types:
* <li>: CommonsPool2TargetSource
* <li>% ThreadLocalTargetSource
* <li>! PrototypeTargetSource
* <ul>
* <li>: CommonsPool2TargetSource</li>
* <li>% ThreadLocalTargetSource</li>
* <li>! PrototypeTargetSource</li>
* </ul>
*
* @author Rod Johnson
* @author Stephane Nicoll
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 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.
@@ -233,7 +233,8 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
return beanFactory.getBean(TaskExecutor.class);
}
catch (NoUniqueBeanDefinitionException ex) {
logger.debug("Could not find unique TaskExecutor bean", ex);
logger.debug("Could not find unique TaskExecutor bean. " +
"Continuing search for an Executor bean named 'taskExecutor'", ex);
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
}
@@ -246,7 +247,8 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
}
}
catch (NoSuchBeanDefinitionException ex) {
logger.debug("Could not find default TaskExecutor bean", ex);
logger.debug("Could not find default TaskExecutor bean. " +
"Continuing search for an Executor bean named 'taskExecutor'", ex);
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2021 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.
@@ -137,7 +137,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
StringBuilder sb = new StringBuilder(getClass().getName());
sb.append(": advice ");
if (this.adviceBeanName != null) {
sb.append("bean '").append(this.adviceBeanName).append("'");
sb.append("bean '").append(this.adviceBeanName).append('\'');
}
else {
sb.append(this.advice);
@@ -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.
@@ -183,8 +183,8 @@ public abstract class AopUtils {
* may be {@code DefaultFoo}. In this case, the method may be
* {@code DefaultFoo.bar()}. This enables attributes on that method to be found.
* <p><b>NOTE:</b> In contrast to {@link org.springframework.util.ClassUtils#getMostSpecificMethod},
* this method resolves Java 5 bridge methods in order to retrieve attributes
* from the <i>original</i> method definition.
* this method resolves bridge methods in order to retrieve attributes from
* the <i>original</i> method definition.
* @param method the method to be invoked, which may come from an interface
* @param targetClass the target class for the current invocation.
* May be {@code null} or may not even implement the method.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -146,7 +146,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
@Override
public String toString() {
return getClass().getName() + ": class = " + this.clazz.getName() + "; methodName = " + methodName;
return getClass().getName() + ": class = " + this.clazz.getName() + "; methodName = " + this.methodName;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -71,7 +71,8 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
if (introductionInfo != null) {
Class<?>[] introducedInterfaces = introductionInfo.getInterfaces();
if (introducedInterfaces.length == 0) {
throw new IllegalArgumentException("IntroductionAdviceSupport implements no interfaces");
throw new IllegalArgumentException(
"IntroductionInfo defines no interfaces to introduce: " + introductionInfo);
}
for (Class<?> ifc : introducedInterfaces) {
addInterface(ifc);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 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.
@@ -24,8 +24,7 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Simple ClassFilter that looks for a specific Java 5 annotation
* being present on a class.
* Simple ClassFilter that looks for a specific annotation being present on a class.
*
* @author Juergen Hoeller
* @since 2.0
@@ -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,9 +26,8 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Simple Pointcut that looks for a specific Java 5 annotation
* being present on a {@link #forClassAnnotation class} or
* {@link #forMethodAnnotation method}.
* Simple {@link Pointcut} that looks for a specific annotation being present on a
* {@linkplain #forClassAnnotation class} or {@linkplain #forMethodAnnotation method}.
*
* @author Juergen Hoeller
* @author Sam Brannen
@@ -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.
@@ -27,9 +27,10 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Simple MethodMatcher that looks for a specific Java 5 annotation
* being present on a method (checking both the method on the invoked
* interface, if any, and the corresponding method on the target class).
* Simple {@link org.springframework.aop.MethodMatcher MethodMatcher} that looks
* for a specific annotation being present on a method (checking both the method
* on the invoked interface, if any, and the corresponding method on the target
* class).
*
* @author Juergen Hoeller
* @author Sam Brannen
@@ -191,9 +191,9 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
@Override
public String toString() {
StringBuilder sb = new StringBuilder(getClass().getSimpleName());
sb.append(" for target bean '").append(this.targetBeanName).append("'");
sb.append(" for target bean '").append(this.targetBeanName).append('\'');
if (this.targetClass != null) {
sb.append(" of type [").append(this.targetClass.getName()).append("]");
sb.append(" of type [").append(this.targetClass.getName()).append(']');
}
return sb.toString();
}
@@ -1,44 +0,0 @@
/*
* Copyright 2002-2018 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import org.aspectj.lang.ProceedingJoinPoint;
import org.junit.jupiter.api.Test;
/**
* Additional parameter name discover tests that need Java 5.
* Yes this will re-run the tests from the superclass, but that
* doesn't matter in the grand scheme of things...
*
* @author Adrian Colyer
* @author Chris Beams
*/
public class AspectJAdviceParameterNameDiscoverAnnotationTests extends AspectJAdviceParameterNameDiscovererTests {
@Test
public void testAnnotationBinding() {
assertParameterNames(getMethod("pjpAndAnAnnotation"),
"execution(* *(..)) && @annotation(ann)",
new String[] {"thisJoinPoint","ann"});
}
public void pjpAndAnAnnotation(ProceedingJoinPoint pjp, MyAnnotation ann) {}
@interface MyAnnotation {}
}
@@ -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.
@@ -17,8 +17,11 @@
package org.springframework.aop.aspectj;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.aop.aspectj.AspectJAdviceParameterNameDiscoverer.AmbiguousBindingException;
@@ -27,200 +30,265 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Unit tests for the {@link AspectJAdviceParameterNameDiscoverer} class.
*
* <p>See also {@link TigerAspectJAdviceParameterNameDiscovererTests} for tests relating to annotations.
* Unit tests for {@link AspectJAdviceParameterNameDiscoverer}.
*
* @author Adrian Colyer
* @author Chris Beams
* @author Sam Brannen
*/
public class AspectJAdviceParameterNameDiscovererTests {
class AspectJAdviceParameterNameDiscovererTests {
@Test
public void testNoArgs() {
assertParameterNames(getMethod("noArgs"), "execution(* *(..))", new String[0]);
@Nested
class StandardTests {
@Test
void noArgs() {
assertParameterNames(getMethod("noArgs"), "execution(* *(..))", new String[0]);
}
@Test
void joinPointOnly() {
assertParameterNames(getMethod("tjp"), "execution(* *(..))", new String[] {"thisJoinPoint"});
}
@Test
void joinPointStaticPartOnly() {
assertParameterNames(getMethod("tjpsp"), "execution(* *(..))", new String[] {"thisJoinPointStaticPart"});
}
@Test
void twoJoinPoints() {
assertException(getMethod("twoJoinPoints"), "foo()", IllegalStateException.class,
"Failed to bind all argument names: 1 argument(s) could not be bound");
}
@Test
void oneThrowable() {
assertParameterNames(getMethod("oneThrowable"), "foo()", null, "ex", new String[] {"ex"});
}
@Test
void oneJPAndOneThrowable() {
assertParameterNames(getMethod("jpAndOneThrowable"), "foo()", null, "ex", new String[] {"thisJoinPoint", "ex"});
}
@Test
void oneJPAndTwoThrowables() {
assertException(getMethod("jpAndTwoThrowables"), "foo()", null, "ex", AmbiguousBindingException.class,
"Binding of throwing parameter 'ex' is ambiguous: could be bound to argument 1 or argument 2");
}
@Test
void throwableNoCandidates() {
assertException(getMethod("noArgs"), "foo()", null, "ex", IllegalStateException.class,
"Not enough arguments in method to satisfy binding of returning and throwing variables");
}
@Test
void returning() {
assertParameterNames(getMethod("oneObject"), "foo()", "obj", null, new String[] {"obj"});
}
@Test
void ambiguousReturning() {
assertException(getMethod("twoObjects"), "foo()", "obj", null, AmbiguousBindingException.class,
"Binding of returning parameter 'obj' is ambiguous, there are 2 candidates.");
}
@Test
void returningNoCandidates() {
assertException(getMethod("noArgs"), "foo()", "obj", null, IllegalStateException.class,
"Not enough arguments in method to satisfy binding of returning and throwing variables");
}
@Test
void thisBindingOneCandidate() {
assertParameterNames(getMethod("oneObject"), "this(x)", new String[] {"x"});
}
@Test
void thisBindingWithAlternateTokenizations() {
assertParameterNames(getMethod("oneObject"), "this( x )", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "this( x)", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "this (x )", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "this(x )", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "foo() && this(x)", new String[] {"x"});
}
@Test
void thisBindingTwoCandidates() {
assertException(getMethod("oneObject"), "this(x) || this(y)", AmbiguousBindingException.class,
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
}
@Test
void thisBindingWithBadPointcutExpressions() {
assertException(getMethod("oneObject"), "this(", IllegalStateException.class,
"Failed to bind all argument names: 1 argument(s) could not be bound");
assertException(getMethod("oneObject"), "this(x && foo()", IllegalStateException.class,
"Failed to bind all argument names: 1 argument(s) could not be bound");
}
@Test
void targetBindingOneCandidate() {
assertParameterNames(getMethod("oneObject"), "target(x)", new String[] {"x"});
}
@Test
void targetBindingWithAlternateTokenizations() {
assertParameterNames(getMethod("oneObject"), "target( x )", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "target( x)", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "target (x )", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "target(x )", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "foo() && target(x)", new String[] {"x"});
}
@Test
void targetBindingTwoCandidates() {
assertException(getMethod("oneObject"), "target(x) || target(y)", AmbiguousBindingException.class,
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
}
@Test
void targetBindingWithBadPointcutExpressions() {
assertException(getMethod("oneObject"), "target(", IllegalStateException.class,
"Failed to bind all argument names: 1 argument(s) could not be bound");
assertException(getMethod("oneObject"), "target(x && foo()", IllegalStateException.class,
"Failed to bind all argument names: 1 argument(s) could not be bound");
}
@Test
void argsBindingOneObject() {
assertParameterNames(getMethod("oneObject"), "args(x)", new String[] {"x"});
}
@Test
void argsBindingOneObjectTwoCandidates() {
assertException(getMethod("oneObject"), "args(x,y)", AmbiguousBindingException.class,
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
}
@Test
void ambiguousArgsBinding() {
assertException(getMethod("twoObjects"), "args(x,y)", AmbiguousBindingException.class,
"Still 2 unbound args at this(),target(),args() binding stage, with no way to determine between them");
}
@Test
void argsOnePrimitive() {
assertParameterNames(getMethod("onePrimitive"), "args(count)", new String[] {"count"});
}
@Test
void argsOnePrimitiveOneObject() {
assertException(getMethod("oneObjectOnePrimitive"), "args(count,obj)", AmbiguousBindingException.class,
"Found 2 candidate variable names but only one candidate binding slot when matching primitive args");
}
@Test
void thisAndPrimitive() {
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && this(obj)",
new String[] {"obj", "count"});
}
@Test
void targetAndPrimitive() {
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && target(obj)",
new String[] {"obj", "count"});
}
@Test
void throwingAndPrimitive() {
assertParameterNames(getMethod("oneThrowableOnePrimitive"), "args(count)", null, "ex",
new String[] {"ex", "count"});
}
@Test
void allTogetherNow() {
assertParameterNames(getMethod("theBigOne"), "this(foo) && args(x)", null, "ex",
new String[] {"thisJoinPoint", "ex", "x", "foo"});
}
@Test
void referenceBinding() {
assertParameterNames(getMethod("onePrimitive"),"somepc(foo)", new String[] {"foo"});
}
@Test
void referenceBindingWithAlternateTokenizations() {
assertParameterNames(getMethod("onePrimitive"),"call(bar *) && somepc(foo)", new String[] {"foo"});
assertParameterNames(getMethod("onePrimitive"),"somepc ( foo )", new String[] {"foo"});
assertParameterNames(getMethod("onePrimitive"),"somepc( foo)", new String[] {"foo"});
}
}
@Test
public void testJoinPointOnly() {
assertParameterNames(getMethod("tjp"), "execution(* *(..))", new String[] {"thisJoinPoint"});
}
/**
* Tests just the annotation binding part of {@link AspectJAdviceParameterNameDiscoverer}.
*/
@Nested
class AnnotationTests {
@Test
public void testJoinPointStaticPartOnly() {
assertParameterNames(getMethod("tjpsp"), "execution(* *(..))", new String[] {"thisJoinPointStaticPart"});
}
@Test
void atThis() {
assertParameterNames(getMethod("oneAnnotation"),"@this(a)", new String[] {"a"});
}
@Test
public void testTwoJoinPoints() {
assertException(getMethod("twoJoinPoints"), "foo()", IllegalStateException.class,
"Failed to bind all argument names: 1 argument(s) could not be bound");
}
@Test
void atTarget() {
assertParameterNames(getMethod("oneAnnotation"),"@target(a)", new String[] {"a"});
}
@Test
public void testOneThrowable() {
assertParameterNames(getMethod("oneThrowable"), "foo()", null, "ex", new String[] {"ex"});
}
@Test
void atArgs() {
assertParameterNames(getMethod("oneAnnotation"),"@args(a)", new String[] {"a"});
}
@Test
public void testOneJPAndOneThrowable() {
assertParameterNames(getMethod("jpAndOneThrowable"), "foo()", null, "ex", new String[] {"thisJoinPoint", "ex"});
}
@Test
void atWithin() {
assertParameterNames(getMethod("oneAnnotation"),"@within(a)", new String[] {"a"});
}
@Test
public void testOneJPAndTwoThrowables() {
assertException(getMethod("jpAndTwoThrowables"), "foo()", null, "ex", AmbiguousBindingException.class,
"Binding of throwing parameter 'ex' is ambiguous: could be bound to argument 1 or argument 2");
}
@Test
void atWithincode() {
assertParameterNames(getMethod("oneAnnotation"),"@withincode(a)", new String[] {"a"});
}
@Test
public void testThrowableNoCandidates() {
assertException(getMethod("noArgs"), "foo()", null, "ex", IllegalStateException.class,
"Not enough arguments in method to satisfy binding of returning and throwing variables");
}
@Test
void atAnnotation() {
assertParameterNames(getMethod("oneAnnotation"),"@annotation(a)", new String[] {"a"});
}
@Test
public void testReturning() {
assertParameterNames(getMethod("oneObject"), "foo()", "obj", null, new String[] {"obj"});
}
@Test
void ambiguousAnnotationTwoVars() {
assertException(getMethod("twoAnnotations"),"@annotation(a) && @this(x)", AmbiguousBindingException.class,
"Found 2 potential annotation variable(s), and 2 potential argument slots");
}
@Test
public void testAmbiguousReturning() {
assertException(getMethod("twoObjects"), "foo()", "obj", null, AmbiguousBindingException.class,
"Binding of returning parameter 'obj' is ambiguous, there are 2 candidates.");
}
@Test
void ambiguousAnnotationOneVar() {
assertException(getMethod("oneAnnotation"),"@annotation(a) && @this(x)",IllegalArgumentException.class,
"Found 2 candidate annotation binding variables but only one potential argument binding slot");
}
@Test
public void testReturningNoCandidates() {
assertException(getMethod("noArgs"), "foo()", "obj", null, IllegalStateException.class,
"Not enough arguments in method to satisfy binding of returning and throwing variables");
}
@Test
void annotationMedley() {
assertParameterNames(getMethod("annotationMedley"),"@annotation(a) && args(count) && this(foo)",
null, "ex", new String[] {"ex", "foo", "count", "a"});
}
@Test
public void testThisBindingOneCandidate() {
assertParameterNames(getMethod("oneObject"), "this(x)", new String[] {"x"});
}
@Test
void annotationBinding() {
assertParameterNames(getMethod("pjpAndAnAnnotation"),
"execution(* *(..)) && @annotation(ann)",
new String[] {"thisJoinPoint","ann"});
}
@Test
public void testThisBindingWithAlternateTokenizations() {
assertParameterNames(getMethod("oneObject"), "this( x )", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "this( x)", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "this (x )", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "this(x )", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "foo() && this(x)", new String[] {"x"});
}
@Test
public void testThisBindingTwoCandidates() {
assertException(getMethod("oneObject"), "this(x) || this(y)", AmbiguousBindingException.class,
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
}
@Test
public void testThisBindingWithBadPointcutExpressions() {
assertException(getMethod("oneObject"), "this(", IllegalStateException.class,
"Failed to bind all argument names: 1 argument(s) could not be bound");
assertException(getMethod("oneObject"), "this(x && foo()", IllegalStateException.class,
"Failed to bind all argument names: 1 argument(s) could not be bound");
}
@Test
public void testTargetBindingOneCandidate() {
assertParameterNames(getMethod("oneObject"), "target(x)", new String[] {"x"});
}
@Test
public void testTargetBindingWithAlternateTokenizations() {
assertParameterNames(getMethod("oneObject"), "target( x )", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "target( x)", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "target (x )", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "target(x )", new String[] {"x"});
assertParameterNames(getMethod("oneObject"), "foo() && target(x)", new String[] {"x"});
}
@Test
public void testTargetBindingTwoCandidates() {
assertException(getMethod("oneObject"), "target(x) || target(y)", AmbiguousBindingException.class,
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
}
@Test
public void testTargetBindingWithBadPointcutExpressions() {
assertException(getMethod("oneObject"), "target(", IllegalStateException.class,
"Failed to bind all argument names: 1 argument(s) could not be bound");
assertException(getMethod("oneObject"), "target(x && foo()", IllegalStateException.class,
"Failed to bind all argument names: 1 argument(s) could not be bound");
}
@Test
public void testArgsBindingOneObject() {
assertParameterNames(getMethod("oneObject"), "args(x)", new String[] {"x"});
}
@Test
public void testArgsBindingOneObjectTwoCandidates() {
assertException(getMethod("oneObject"), "args(x,y)", AmbiguousBindingException.class,
"Found 2 candidate this(), target() or args() variables but only one unbound argument slot");
}
@Test
public void testAmbiguousArgsBinding() {
assertException(getMethod("twoObjects"), "args(x,y)", AmbiguousBindingException.class,
"Still 2 unbound args at this(),target(),args() binding stage, with no way to determine between them");
}
@Test
public void testArgsOnePrimitive() {
assertParameterNames(getMethod("onePrimitive"), "args(count)", new String[] {"count"});
}
@Test
public void testArgsOnePrimitiveOneObject() {
assertException(getMethod("oneObjectOnePrimitive"), "args(count,obj)", AmbiguousBindingException.class,
"Found 2 candidate variable names but only one candidate binding slot when matching primitive args");
}
@Test
public void testThisAndPrimitive() {
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && this(obj)",
new String[] {"obj", "count"});
}
@Test
public void testTargetAndPrimitive() {
assertParameterNames(getMethod("oneObjectOnePrimitive"), "args(count) && target(obj)",
new String[] {"obj", "count"});
}
@Test
public void testThrowingAndPrimitive() {
assertParameterNames(getMethod("oneThrowableOnePrimitive"), "args(count)", null, "ex",
new String[] {"ex", "count"});
}
@Test
public void testAllTogetherNow() {
assertParameterNames(getMethod("theBigOne"), "this(foo) && args(x)", null, "ex",
new String[] {"thisJoinPoint", "ex", "x", "foo"});
}
@Test
public void testReferenceBinding() {
assertParameterNames(getMethod("onePrimitive"),"somepc(foo)", new String[] {"foo"});
}
@Test
public void testReferenceBindingWithAlternateTokenizations() {
assertParameterNames(getMethod("onePrimitive"),"call(bar *) && somepc(foo)", new String[] {"foo"});
assertParameterNames(getMethod("onePrimitive"),"somepc ( foo )", new String[] {"foo"});
assertParameterNames(getMethod("onePrimitive"),"somepc( foo)", new String[] {"foo"});
}
protected Method getMethod(String name) {
private Method getMethod(String name) {
// Assumes no overloading of test methods...
Method[] candidates = getClass().getMethods();
for (Method candidate : candidates) {
for (Method candidate : getClass().getMethods()) {
if (candidate.getName().equals(name)) {
return candidate;
}
@@ -228,11 +296,11 @@ public class AspectJAdviceParameterNameDiscovererTests {
throw new AssertionError("Bad test specification, no method '" + name + "' found in test class");
}
protected void assertParameterNames(Method method, String pointcut, String[] parameterNames) {
private void assertParameterNames(Method method, String pointcut, String[] parameterNames) {
assertParameterNames(method, pointcut, null, null, parameterNames);
}
protected void assertParameterNames(
private void assertParameterNames(
Method method, String pointcut, String returning, String throwing, String[] parameterNames) {
assertThat(parameterNames.length).as("bad test specification, must have same number of parameter names as method arguments").isEqualTo(method.getParameterCount());
@@ -243,8 +311,8 @@ public class AspectJAdviceParameterNameDiscovererTests {
discoverer.setThrowingName(throwing);
String[] discoveredNames = discoverer.getParameterNames(method);
String formattedExpectedNames = format(parameterNames);
String formattedActualNames = format(discoveredNames);
String formattedExpectedNames = Arrays.toString(parameterNames);
String formattedActualNames = Arrays.toString(discoveredNames);
assertThat(discoveredNames.length).as("Expecting " + parameterNames.length + " parameter names in return set '" +
formattedExpectedNames + "', but found " + discoveredNames.length +
@@ -257,37 +325,23 @@ public class AspectJAdviceParameterNameDiscovererTests {
}
}
protected void assertException(Method method, String pointcut, Class<? extends Throwable> exceptionType, String message) {
private void assertException(Method method, String pointcut, Class<? extends Throwable> exceptionType, String message) {
assertException(method, pointcut, null, null, exceptionType, message);
}
protected void assertException(Method method, String pointcut, String returning,
private void assertException(Method method, String pointcut, String returning,
String throwing, Class<? extends Throwable> exceptionType, String message) {
AspectJAdviceParameterNameDiscoverer discoverer = new AspectJAdviceParameterNameDiscoverer(pointcut);
discoverer.setRaiseExceptions(true);
discoverer.setReturningName(returning);
discoverer.setThrowingName(throwing);
assertThatExceptionOfType(exceptionType).isThrownBy(() ->
discoverer.getParameterNames(method))
assertThatExceptionOfType(exceptionType)
.isThrownBy(() -> discoverer.getParameterNames(method))
.withMessageContaining(message);
}
private static String format(String[] names) {
StringBuilder sb = new StringBuilder();
sb.append("(");
for (int i = 0; i < names.length; i++) {
sb.append(names[i]);
if ((i + 1) < names.length) {
sb.append(",");
}
}
sb.append(")");
return sb.toString();
}
// Methods to discover parameter names for
public void noArgs() {
@@ -329,4 +383,14 @@ public class AspectJAdviceParameterNameDiscovererTests {
public void theBigOne(JoinPoint jp, Throwable x, int y, Object foo) {
}
public void oneAnnotation(MyAnnotation ann) {}
public void twoAnnotations(MyAnnotation ann, MyAnnotation anotherAnn) {}
public void annotationMedley(Throwable t, Object foo, int x, MyAnnotation ma) {}
public void pjpAndAnAnnotation(ProceedingJoinPoint pjp, MyAnnotation ann) {}
@interface MyAnnotation {}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -17,6 +17,9 @@
package org.springframework.aop.aspectj;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
@@ -25,6 +28,8 @@ import org.aspectj.weaver.tools.PointcutPrimitive;
import org.aspectj.weaver.tools.UnsupportedPointcutPrimitiveException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import test.annotation.EmptySpringAnnotation;
import test.annotation.transaction.Tx;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
@@ -56,12 +61,19 @@ public class AspectJExpressionPointcutTests {
private Method setSomeNumber;
private final Map<String, Method> methodsOnHasGeneric = new HashMap<>();
@BeforeEach
public void setUp() throws NoSuchMethodException {
getAge = TestBean.class.getMethod("getAge");
setAge = TestBean.class.getMethod("setAge", int.class);
setSomeNumber = TestBean.class.getMethod("setSomeNumber", Number.class);
// Assumes no overloading
for (Method method : HasGeneric.class.getMethods()) {
methodsOnHasGeneric.put(method.getName(), method);
}
}
@@ -299,6 +311,279 @@ public class AspectJExpressionPointcutTests {
}
}
@Test
public void testMatchGenericArgument() {
String expression = "execution(* set*(java.util.List<org.springframework.beans.testfixture.beans.TestBean>) )";
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setExpression(expression);
// TODO this will currently map, would be nice for optimization
//assertTrue(ajexp.matches(HasGeneric.class));
//assertFalse(ajexp.matches(TestBean.class));
Method takesGenericList = methodsOnHasGeneric.get("setFriends");
assertThat(ajexp.matches(takesGenericList, HasGeneric.class)).isTrue();
assertThat(ajexp.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isTrue();
assertThat(ajexp.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse();
assertThat(ajexp.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse();
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
}
@Test
public void testMatchVarargs() throws Exception {
@SuppressWarnings("unused")
class MyTemplate {
public int queryForInt(String sql, Object... params) {
return 0;
}
}
String expression = "execution(int *.*(String, Object...))";
AspectJExpressionPointcut jdbcVarArgs = new AspectJExpressionPointcut();
jdbcVarArgs.setExpression(expression);
assertThat(jdbcVarArgs.matches(
MyTemplate.class.getMethod("queryForInt", String.class, Object[].class),
MyTemplate.class)).isTrue();
Method takesGenericList = methodsOnHasGeneric.get("setFriends");
assertThat(jdbcVarArgs.matches(takesGenericList, HasGeneric.class)).isFalse();
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isFalse();
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse();
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse();
assertThat(jdbcVarArgs.matches(getAge, TestBean.class)).isFalse();
}
@Test
public void testMatchAnnotationOnClassWithAtWithin() throws Exception {
String expression = "@within(test.annotation.transaction.Tx)";
testMatchAnnotationOnClass(expression);
}
@Test
public void testMatchAnnotationOnClassWithoutBinding() throws Exception {
String expression = "within(@test.annotation.transaction.Tx *)";
testMatchAnnotationOnClass(expression);
}
@Test
public void testMatchAnnotationOnClassWithSubpackageWildcard() throws Exception {
String expression = "within(@(test.annotation..*) *)";
AspectJExpressionPointcut springAnnotatedPc = testMatchAnnotationOnClass(expression);
assertThat(springAnnotatedPc.matches(TestBean.class.getMethod("setName", String.class), TestBean.class)).isFalse();
assertThat(springAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isTrue();
expression = "within(@(test.annotation.transaction..*) *)";
AspectJExpressionPointcut springTxAnnotatedPc = testMatchAnnotationOnClass(expression);
assertThat(springTxAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isFalse();
}
@Test
public void testMatchAnnotationOnClassWithExactPackageWildcard() throws Exception {
String expression = "within(@(test.annotation.transaction.*) *)";
testMatchAnnotationOnClass(expression);
}
private AspectJExpressionPointcut testMatchAnnotationOnClass(String expression) throws Exception {
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setExpression(expression);
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isTrue();
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isTrue();
assertThat(ajexp.matches(BeanB.class.getMethod("setName", String.class), BeanB.class)).isTrue();
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
return ajexp;
}
@Test
public void testAnnotationOnMethodWithFQN() throws Exception {
String expression = "@annotation(test.annotation.transaction.Tx)";
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setExpression(expression);
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue();
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
}
@Test
public void testAnnotationOnCglibProxyMethod() throws Exception {
String expression = "@annotation(test.annotation.transaction.Tx)";
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setExpression(expression);
ProxyFactory factory = new ProxyFactory(new BeanA());
factory.setProxyTargetClass(true);
BeanA proxy = (BeanA) factory.getProxy();
assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), proxy.getClass())).isTrue();
}
@Test
public void testAnnotationOnDynamicProxyMethod() throws Exception {
String expression = "@annotation(test.annotation.transaction.Tx)";
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setExpression(expression);
ProxyFactory factory = new ProxyFactory(new BeanA());
factory.setProxyTargetClass(false);
IBeanA proxy = (IBeanA) factory.getProxy();
assertThat(ajexp.matches(IBeanA.class.getMethod("getAge"), proxy.getClass())).isTrue();
}
@Test
public void testAnnotationOnMethodWithWildcard() throws Exception {
String expression = "execution(@(test.annotation..*) * *(..))";
AspectJExpressionPointcut anySpringMethodAnnotation = new AspectJExpressionPointcut();
anySpringMethodAnnotation.setExpression(expression);
assertThat(anySpringMethodAnnotation.matches(getAge, TestBean.class)).isFalse();
assertThat(anySpringMethodAnnotation.matches(
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
assertThat(anySpringMethodAnnotation.matches(
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue();
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
}
@Test
public void testAnnotationOnMethodArgumentsWithFQN() throws Exception {
String expression = "@args(*, test.annotation.EmptySpringAnnotation))";
AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut();
takesSpringAnnotatedArgument2.setExpression(expression);
assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(
ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class),
ProcessesSpringAnnotatedParameters.class)).isTrue();
// True because it maybeMatches with potential argument subtypes
assertThat(takesSpringAnnotatedArgument2.matches(
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
ProcessesSpringAnnotatedParameters.class)).isTrue();
assertThat(takesSpringAnnotatedArgument2.matches(
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
ProcessesSpringAnnotatedParameters.class, new TestBean(), new BeanA())).isFalse();
}
@Test
public void testAnnotationOnMethodArgumentsWithWildcards() throws Exception {
String expression = "execution(* *(*, @(test..*) *))";
AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut();
takesSpringAnnotatedArgument2.setExpression(expression);
assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(
ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class),
ProcessesSpringAnnotatedParameters.class)).isTrue();
assertThat(takesSpringAnnotatedArgument2.matches(
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
ProcessesSpringAnnotatedParameters.class)).isFalse();
}
public static class HasGeneric {
public void setFriends(List<TestBean> friends) {
}
public void setEnemies(List<TestBean> enemies) {
}
public void setPartners(List<?> partners) {
}
public void setPhoneNumbers(List<String> numbers) {
}
}
public static class ProcessesSpringAnnotatedParameters {
public void takesAnnotatedParameters(TestBean tb, SpringAnnotated sa) {
}
public void takesNoAnnotatedParameters(TestBean tb, BeanA tb3) {
}
}
@Tx
public static class HasTransactionalAnnotation {
public void foo() {
}
public Object bar(String foo) {
throw new UnsupportedOperationException();
}
}
@EmptySpringAnnotation
public static class SpringAnnotated {
public void foo() {
}
}
interface IBeanA {
@Tx
int getAge();
}
static class BeanA implements IBeanA {
@SuppressWarnings("unused")
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
@Tx
@Override
public int getAge() {
return age;
}
}
@Tx
static class BeanB {
@SuppressWarnings("unused")
private String name;
public void setName(String name) {
this.name = name;
}
}
}
@@ -1,89 +0,0 @@
/*
* Copyright 2002-2017 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import org.junit.jupiter.api.Test;
import org.springframework.aop.aspectj.AspectJAdviceParameterNameDiscoverer.AmbiguousBindingException;
/**
* Tests just the annotation binding part of {@link AspectJAdviceParameterNameDiscoverer};
* see supertype for remaining tests.
*
* @author Adrian Colyer
* @author Chris Beams
*/
public class TigerAspectJAdviceParameterNameDiscovererTests extends AspectJAdviceParameterNameDiscovererTests {
@Test
public void testAtThis() {
assertParameterNames(getMethod("oneAnnotation"),"@this(a)", new String[] {"a"});
}
@Test
public void testAtTarget() {
assertParameterNames(getMethod("oneAnnotation"),"@target(a)", new String[] {"a"});
}
@Test
public void testAtArgs() {
assertParameterNames(getMethod("oneAnnotation"),"@args(a)", new String[] {"a"});
}
@Test
public void testAtWithin() {
assertParameterNames(getMethod("oneAnnotation"),"@within(a)", new String[] {"a"});
}
@Test
public void testAtWithincode() {
assertParameterNames(getMethod("oneAnnotation"),"@withincode(a)", new String[] {"a"});
}
@Test
public void testAtAnnotation() {
assertParameterNames(getMethod("oneAnnotation"),"@annotation(a)", new String[] {"a"});
}
@Test
public void testAmbiguousAnnotationTwoVars() {
assertException(getMethod("twoAnnotations"),"@annotation(a) && @this(x)", AmbiguousBindingException.class,
"Found 2 potential annotation variable(s), and 2 potential argument slots");
}
@Test
public void testAmbiguousAnnotationOneVar() {
assertException(getMethod("oneAnnotation"),"@annotation(a) && @this(x)",IllegalArgumentException.class,
"Found 2 candidate annotation binding variables but only one potential argument binding slot");
}
@Test
public void testAnnotationMedley() {
assertParameterNames(getMethod("annotationMedley"),"@annotation(a) && args(count) && this(foo)",
null, "ex", new String[] {"ex", "foo", "count", "a"});
}
public void oneAnnotation(MyAnnotation ann) {}
public void twoAnnotations(MyAnnotation ann, MyAnnotation anotherAnn) {}
public void annotationMedley(Throwable t, Object foo, int x, MyAnnotation ma) {}
@interface MyAnnotation {}
}
@@ -1,330 +0,0 @@
/*
* Copyright 2002-2019 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import test.annotation.EmptySpringAnnotation;
import test.annotation.transaction.Tx;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.testfixture.beans.TestBean;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Java 5 specific {@link AspectJExpressionPointcutTests}.
*
* @author Rod Johnson
* @author Chris Beams
*/
public class TigerAspectJExpressionPointcutTests {
private Method getAge;
private final Map<String, Method> methodsOnHasGeneric = new HashMap<>();
@BeforeEach
public void setup() throws NoSuchMethodException {
getAge = TestBean.class.getMethod("getAge");
// Assumes no overloading
for (Method method : HasGeneric.class.getMethods()) {
methodsOnHasGeneric.put(method.getName(), method);
}
}
@Test
public void testMatchGenericArgument() {
String expression = "execution(* set*(java.util.List<org.springframework.beans.testfixture.beans.TestBean>) )";
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setExpression(expression);
// TODO this will currently map, would be nice for optimization
//assertTrue(ajexp.matches(HasGeneric.class));
//assertFalse(ajexp.matches(TestBean.class));
Method takesGenericList = methodsOnHasGeneric.get("setFriends");
assertThat(ajexp.matches(takesGenericList, HasGeneric.class)).isTrue();
assertThat(ajexp.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isTrue();
assertThat(ajexp.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse();
assertThat(ajexp.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse();
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
}
@Test
public void testMatchVarargs() throws Exception {
@SuppressWarnings("unused")
class MyTemplate {
public int queryForInt(String sql, Object... params) {
return 0;
}
}
String expression = "execution(int *.*(String, Object...))";
AspectJExpressionPointcut jdbcVarArgs = new AspectJExpressionPointcut();
jdbcVarArgs.setExpression(expression);
assertThat(jdbcVarArgs.matches(
MyTemplate.class.getMethod("queryForInt", String.class, Object[].class),
MyTemplate.class)).isTrue();
Method takesGenericList = methodsOnHasGeneric.get("setFriends");
assertThat(jdbcVarArgs.matches(takesGenericList, HasGeneric.class)).isFalse();
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setEnemies"), HasGeneric.class)).isFalse();
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPartners"), HasGeneric.class)).isFalse();
assertThat(jdbcVarArgs.matches(methodsOnHasGeneric.get("setPhoneNumbers"), HasGeneric.class)).isFalse();
assertThat(jdbcVarArgs.matches(getAge, TestBean.class)).isFalse();
}
@Test
public void testMatchAnnotationOnClassWithAtWithin() throws Exception {
String expression = "@within(test.annotation.transaction.Tx)";
testMatchAnnotationOnClass(expression);
}
@Test
public void testMatchAnnotationOnClassWithoutBinding() throws Exception {
String expression = "within(@test.annotation.transaction.Tx *)";
testMatchAnnotationOnClass(expression);
}
@Test
public void testMatchAnnotationOnClassWithSubpackageWildcard() throws Exception {
String expression = "within(@(test.annotation..*) *)";
AspectJExpressionPointcut springAnnotatedPc = testMatchAnnotationOnClass(expression);
assertThat(springAnnotatedPc.matches(TestBean.class.getMethod("setName", String.class), TestBean.class)).isFalse();
assertThat(springAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isTrue();
expression = "within(@(test.annotation.transaction..*) *)";
AspectJExpressionPointcut springTxAnnotatedPc = testMatchAnnotationOnClass(expression);
assertThat(springTxAnnotatedPc.matches(SpringAnnotated.class.getMethod("foo"), SpringAnnotated.class)).isFalse();
}
@Test
public void testMatchAnnotationOnClassWithExactPackageWildcard() throws Exception {
String expression = "within(@(test.annotation.transaction.*) *)";
testMatchAnnotationOnClass(expression);
}
private AspectJExpressionPointcut testMatchAnnotationOnClass(String expression) throws Exception {
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setExpression(expression);
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isTrue();
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isTrue();
assertThat(ajexp.matches(BeanB.class.getMethod("setName", String.class), BeanB.class)).isTrue();
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
return ajexp;
}
@Test
public void testAnnotationOnMethodWithFQN() throws Exception {
String expression = "@annotation(test.annotation.transaction.Tx)";
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setExpression(expression);
assertThat(ajexp.matches(getAge, TestBean.class)).isFalse();
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
assertThat(ajexp.matches(HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue();
assertThat(ajexp.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
}
@Test
public void testAnnotationOnCglibProxyMethod() throws Exception {
String expression = "@annotation(test.annotation.transaction.Tx)";
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setExpression(expression);
ProxyFactory factory = new ProxyFactory(new BeanA());
factory.setProxyTargetClass(true);
BeanA proxy = (BeanA) factory.getProxy();
assertThat(ajexp.matches(BeanA.class.getMethod("getAge"), proxy.getClass())).isTrue();
}
@Test
public void testAnnotationOnDynamicProxyMethod() throws Exception {
String expression = "@annotation(test.annotation.transaction.Tx)";
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setExpression(expression);
ProxyFactory factory = new ProxyFactory(new BeanA());
factory.setProxyTargetClass(false);
IBeanA proxy = (IBeanA) factory.getProxy();
assertThat(ajexp.matches(IBeanA.class.getMethod("getAge"), proxy.getClass())).isTrue();
}
@Test
public void testAnnotationOnMethodWithWildcard() throws Exception {
String expression = "execution(@(test.annotation..*) * *(..))";
AspectJExpressionPointcut anySpringMethodAnnotation = new AspectJExpressionPointcut();
anySpringMethodAnnotation.setExpression(expression);
assertThat(anySpringMethodAnnotation.matches(getAge, TestBean.class)).isFalse();
assertThat(anySpringMethodAnnotation.matches(
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
assertThat(anySpringMethodAnnotation.matches(
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isTrue();
assertThat(anySpringMethodAnnotation.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
}
@Test
public void testAnnotationOnMethodArgumentsWithFQN() throws Exception {
String expression = "@args(*, test.annotation.EmptySpringAnnotation))";
AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut();
takesSpringAnnotatedArgument2.setExpression(expression);
assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(
ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class),
ProcessesSpringAnnotatedParameters.class)).isTrue();
// True because it maybeMatches with potential argument subtypes
assertThat(takesSpringAnnotatedArgument2.matches(
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
ProcessesSpringAnnotatedParameters.class)).isTrue();
assertThat(takesSpringAnnotatedArgument2.matches(
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
ProcessesSpringAnnotatedParameters.class, new TestBean(), new BeanA())).isFalse();
}
@Test
public void testAnnotationOnMethodArgumentsWithWildcards() throws Exception {
String expression = "execution(* *(*, @(test..*) *))";
AspectJExpressionPointcut takesSpringAnnotatedArgument2 = new AspectJExpressionPointcut();
takesSpringAnnotatedArgument2.setExpression(expression);
assertThat(takesSpringAnnotatedArgument2.matches(getAge, TestBean.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(
HasTransactionalAnnotation.class.getMethod("foo"), HasTransactionalAnnotation.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(
HasTransactionalAnnotation.class.getMethod("bar", String.class), HasTransactionalAnnotation.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("getAge"), BeanA.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(BeanA.class.getMethod("setName", String.class), BeanA.class)).isFalse();
assertThat(takesSpringAnnotatedArgument2.matches(
ProcessesSpringAnnotatedParameters.class.getMethod("takesAnnotatedParameters", TestBean.class, SpringAnnotated.class),
ProcessesSpringAnnotatedParameters.class)).isTrue();
assertThat(takesSpringAnnotatedArgument2.matches(
ProcessesSpringAnnotatedParameters.class.getMethod("takesNoAnnotatedParameters", TestBean.class, BeanA.class),
ProcessesSpringAnnotatedParameters.class)).isFalse();
}
public static class HasGeneric {
public void setFriends(List<TestBean> friends) {
}
public void setEnemies(List<TestBean> enemies) {
}
public void setPartners(List<?> partners) {
}
public void setPhoneNumbers(List<String> numbers) {
}
}
public static class ProcessesSpringAnnotatedParameters {
public void takesAnnotatedParameters(TestBean tb, SpringAnnotated sa) {
}
public void takesNoAnnotatedParameters(TestBean tb, BeanA tb3) {
}
}
@Tx
public static class HasTransactionalAnnotation {
public void foo() {
}
public Object bar(String foo) {
throw new UnsupportedOperationException();
}
}
@EmptySpringAnnotation
public static class SpringAnnotated {
public void foo() {
}
}
interface IBeanA {
@Tx
int getAge();
}
static class BeanA implements IBeanA {
@SuppressWarnings("unused")
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
@Tx
@Override
public int getAge() {
return age;
}
}
@Tx
static class BeanB {
@SuppressWarnings("unused")
private String name;
public void setName(String name) {
this.name = name;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -98,7 +98,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
}
@Test
void perTargetAspect() throws SecurityException, NoSuchMethodException {
void perTargetAspect() throws Exception {
TestBean target = new TestBean();
int realAge = 65;
target.setAge(realAge);
@@ -130,7 +130,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
}
@Test
void multiplePerTargetAspects() throws SecurityException, NoSuchMethodException {
void multiplePerTargetAspects() throws Exception {
TestBean target = new TestBean();
int realAge = 65;
target.setAge(realAge);
@@ -158,7 +158,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
}
@Test
void multiplePerTargetAspectsWithOrderAnnotation() throws SecurityException, NoSuchMethodException {
void multiplePerTargetAspectsWithOrderAnnotation() throws Exception {
TestBean target = new TestBean();
int realAge = 65;
target.setAge(realAge);
@@ -184,7 +184,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
}
@Test
void perThisAspect() throws SecurityException, NoSuchMethodException {
void perThisAspect() throws Exception {
TestBean target = new TestBean();
int realAge = 65;
target.setAge(realAge);
@@ -220,7 +220,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
}
@Test
void perTypeWithinAspect() throws SecurityException, NoSuchMethodException {
void perTypeWithinAspect() throws Exception {
TestBean target = new TestBean();
int realAge = 65;
target.setAge(realAge);
@@ -322,7 +322,7 @@ abstract class AbstractAspectJAdvisorFactoryTests {
int b = 12;
int c = 25;
String d = "d";
StringBuffer e = new StringBuffer("stringbuf");
StringBuilder e = new StringBuilder("stringbuf");
String expectedResult = a + b+ c + d + e;
assertThat(mva.mungeArgs(a, b, c, d, e)).isEqualTo(expectedResult);
}
@@ -728,12 +728,12 @@ abstract class AbstractAspectJAdvisorFactoryTests {
@Aspect
static class ManyValuedArgs {
String mungeArgs(String a, int b, int c, String d, StringBuffer e) {
String mungeArgs(String a, int b, int c, String d, StringBuilder e) {
return a + b + c + d + e;
}
@Around(value="execution(String mungeArgs(..)) && args(a, b, c, d, e)", argNames="b,c,d,e,a")
String reverseAdvice(ProceedingJoinPoint pjp, int b, int c, String d, StringBuffer e, String a) throws Throwable {
String reverseAdvice(ProceedingJoinPoint pjp, int b, int c, String d, StringBuilder e, String a) throws Throwable {
assertThat(pjp.proceed()).isEqualTo(a + b+ c+ d+ e);
return a + b + c + d + e;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -28,7 +28,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* @since 2.0
* @author Rod Johnson
* @author Chris Beams
* @author Sam Brannen
@@ -56,7 +55,7 @@ class AspectMetadataTests {
assertThat(am.getAjType().getPerClause().getKind()).isEqualTo(PerClauseKind.PERTARGET);
assertThat(am.getPerClausePointcut()).isInstanceOf(AspectJExpressionPointcut.class);
assertThat(((AspectJExpressionPointcut) am.getPerClausePointcut()).getExpression())
.isEqualTo("execution(* *.getSpouse())");
.isEqualTo("execution(* *.getSpouse())");
}
@Test
@@ -67,7 +66,7 @@ class AspectMetadataTests {
assertThat(am.getAjType().getPerClause().getKind()).isEqualTo(PerClauseKind.PERTHIS);
assertThat(am.getPerClausePointcut()).isInstanceOf(AspectJExpressionPointcut.class);
assertThat(((AspectJExpressionPointcut) am.getPerClausePointcut()).getExpression())
.isEqualTo("execution(* *.getSpouse())");
.isEqualTo("execution(* *.getSpouse())");
}
}
@@ -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.
@@ -16,6 +16,7 @@
package org.springframework.aop.config;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@@ -40,7 +41,7 @@ import static org.springframework.core.testfixture.io.ResourceTestUtils.qualifie
* @author Juergen Hoeller
* @author Chris Beams
*/
public class AopNamespaceHandlerEventTests {
class AopNamespaceHandlerEventTests {
private static final Class<?> CLASS = AopNamespaceHandlerEventTests.class;
@@ -57,25 +58,24 @@ public class AopNamespaceHandlerEventTests {
@BeforeEach
public void setup() {
void setup() {
this.reader = new XmlBeanDefinitionReader(this.beanFactory);
this.reader.setEventListener(this.eventListener);
}
@Test
public void testPointcutEvents() {
void pointcutEvents() {
this.reader.loadBeanDefinitions(POINTCUT_EVENTS_CONTEXT);
ComponentDefinition[] componentDefinitions = this.eventListener.getComponentDefinitions();
assertThat(componentDefinitions.length).as("Incorrect number of events fired").isEqualTo(1);
boolean condition = componentDefinitions[0] instanceof CompositeComponentDefinition;
assertThat(condition).as("No holder with nested components").isTrue();
assertThat(componentDefinitions).as("Incorrect number of events fired").hasSize(1);
assertThat(componentDefinitions[0]).as("No holder with nested components").isInstanceOf(CompositeComponentDefinition.class);
CompositeComponentDefinition compositeDef = (CompositeComponentDefinition) componentDefinitions[0];
assertThat(compositeDef.getName()).isEqualTo("aop:config");
ComponentDefinition[] nestedComponentDefs = compositeDef.getNestedComponents();
assertThat(nestedComponentDefs.length).as("Incorrect number of inner components").isEqualTo(2);
assertThat(nestedComponentDefs).as("Incorrect number of inner components").hasSize(2);
PointcutComponentDefinition pcd = null;
for (ComponentDefinition componentDefinition : nestedComponentDefs) {
if (componentDefinition instanceof PointcutComponentDefinition) {
@@ -84,84 +84,77 @@ public class AopNamespaceHandlerEventTests {
}
}
assertThat(pcd).as("PointcutComponentDefinition not found").isNotNull();
assertThat(pcd.getBeanDefinitions().length).as("Incorrect number of BeanDefinitions").isEqualTo(1);
assertThat(pcd.getBeanDefinitions()).as("Incorrect number of BeanDefinitions").hasSize(1);
}
@Test
public void testAdvisorEventsWithPointcutRef() {
void advisorEventsWithPointcutRef() {
this.reader.loadBeanDefinitions(POINTCUT_REF_CONTEXT);
ComponentDefinition[] componentDefinitions = this.eventListener.getComponentDefinitions();
assertThat(componentDefinitions.length).as("Incorrect number of events fired").isEqualTo(2);
assertThat(componentDefinitions).as("Incorrect number of events fired").hasSize(2);
boolean condition1 = componentDefinitions[0] instanceof CompositeComponentDefinition;
assertThat(condition1).as("No holder with nested components").isTrue();
assertThat(componentDefinitions[0]).as("No holder with nested components").isInstanceOf(CompositeComponentDefinition.class);
CompositeComponentDefinition compositeDef = (CompositeComponentDefinition) componentDefinitions[0];
assertThat(compositeDef.getName()).isEqualTo("aop:config");
ComponentDefinition[] nestedComponentDefs = compositeDef.getNestedComponents();
assertThat(nestedComponentDefs.length).as("Incorrect number of inner components").isEqualTo(3);
assertThat(nestedComponentDefs).as("Incorrect number of inner components").hasSize(3);
AdvisorComponentDefinition acd = null;
for (int i = 0; i < nestedComponentDefs.length; i++) {
ComponentDefinition componentDefinition = nestedComponentDefs[i];
for (ComponentDefinition componentDefinition : nestedComponentDefs) {
if (componentDefinition instanceof AdvisorComponentDefinition) {
acd = (AdvisorComponentDefinition) componentDefinition;
break;
}
}
assertThat(acd).as("AdvisorComponentDefinition not found").isNotNull();
assertThat(acd.getBeanDefinitions().length).isEqualTo(1);
assertThat(acd.getBeanReferences().length).isEqualTo(2);
assertThat(acd.getBeanDefinitions()).hasSize(1);
assertThat(acd.getBeanReferences()).hasSize(2);
boolean condition = componentDefinitions[1] instanceof BeanComponentDefinition;
assertThat(condition).as("No advice bean found").isTrue();
assertThat(componentDefinitions[1]).as("No advice bean found").isInstanceOf(BeanComponentDefinition.class);
BeanComponentDefinition adviceDef = (BeanComponentDefinition) componentDefinitions[1];
assertThat(adviceDef.getBeanName()).isEqualTo("countingAdvice");
}
@Test
public void testAdvisorEventsWithDirectPointcut() {
void advisorEventsWithDirectPointcut() {
this.reader.loadBeanDefinitions(DIRECT_POINTCUT_EVENTS_CONTEXT);
ComponentDefinition[] componentDefinitions = this.eventListener.getComponentDefinitions();
assertThat(componentDefinitions.length).as("Incorrect number of events fired").isEqualTo(2);
assertThat(componentDefinitions).as("Incorrect number of events fired").hasSize(2);
boolean condition1 = componentDefinitions[0] instanceof CompositeComponentDefinition;
assertThat(condition1).as("No holder with nested components").isTrue();
assertThat(componentDefinitions[0]).as("No holder with nested components").isInstanceOf(CompositeComponentDefinition.class);
CompositeComponentDefinition compositeDef = (CompositeComponentDefinition) componentDefinitions[0];
assertThat(compositeDef.getName()).isEqualTo("aop:config");
ComponentDefinition[] nestedComponentDefs = compositeDef.getNestedComponents();
assertThat(nestedComponentDefs.length).as("Incorrect number of inner components").isEqualTo(2);
assertThat(nestedComponentDefs).as("Incorrect number of inner components").hasSize(2);
AdvisorComponentDefinition acd = null;
for (int i = 0; i < nestedComponentDefs.length; i++) {
ComponentDefinition componentDefinition = nestedComponentDefs[i];
for (ComponentDefinition componentDefinition : nestedComponentDefs) {
if (componentDefinition instanceof AdvisorComponentDefinition) {
acd = (AdvisorComponentDefinition) componentDefinition;
break;
}
}
assertThat(acd).as("AdvisorComponentDefinition not found").isNotNull();
assertThat(acd.getBeanDefinitions().length).isEqualTo(2);
assertThat(acd.getBeanReferences().length).isEqualTo(1);
assertThat(acd.getBeanDefinitions()).hasSize(2);
assertThat(acd.getBeanReferences()).hasSize(1);
boolean condition = componentDefinitions[1] instanceof BeanComponentDefinition;
assertThat(condition).as("No advice bean found").isTrue();
assertThat(componentDefinitions[1]).as("No advice bean found").isInstanceOf(BeanComponentDefinition.class);
BeanComponentDefinition adviceDef = (BeanComponentDefinition) componentDefinitions[1];
assertThat(adviceDef.getBeanName()).isEqualTo("countingAdvice");
}
@Test
public void testAspectEvent() {
void aspectEvent() {
this.reader.loadBeanDefinitions(CONTEXT);
ComponentDefinition[] componentDefinitions = this.eventListener.getComponentDefinitions();
assertThat(componentDefinitions.length).as("Incorrect number of events fired").isEqualTo(5);
assertThat(componentDefinitions).as("Incorrect number of events fired").hasSize(2);
boolean condition = componentDefinitions[0] instanceof CompositeComponentDefinition;
assertThat(condition).as("No holder with nested components").isTrue();
assertThat(componentDefinitions[0]).as("No holder with nested components").isInstanceOf(CompositeComponentDefinition.class);
CompositeComponentDefinition compositeDef = (CompositeComponentDefinition) componentDefinitions[0];
assertThat(compositeDef.getName()).isEqualTo("aop:config");
ComponentDefinition[] nestedComponentDefs = compositeDef.getNestedComponents();
assertThat(nestedComponentDefs.length).as("Incorrect number of inner components").isEqualTo(2);
assertThat(nestedComponentDefs).as("Incorrect number of inner components").hasSize(2);
AspectComponentDefinition acd = null;
for (ComponentDefinition componentDefinition : nestedComponentDefs) {
if (componentDefinition instanceof AspectComponentDefinition) {
@@ -172,9 +165,9 @@ public class AopNamespaceHandlerEventTests {
assertThat(acd).as("AspectComponentDefinition not found").isNotNull();
BeanDefinition[] beanDefinitions = acd.getBeanDefinitions();
assertThat(beanDefinitions.length).isEqualTo(5);
assertThat(beanDefinitions).hasSize(5);
BeanReference[] beanReferences = acd.getBeanReferences();
assertThat(beanReferences.length).isEqualTo(6);
assertThat(beanReferences).hasSize(6);
Set<String> expectedReferences = new HashSet<>();
expectedReferences.add("pc");
@@ -182,19 +175,16 @@ public class AopNamespaceHandlerEventTests {
for (BeanReference beanReference : beanReferences) {
expectedReferences.remove(beanReference.getBeanName());
}
assertThat(expectedReferences.size()).as("Incorrect references found").isEqualTo(0);
assertThat(expectedReferences).as("Incorrect references found").isEmpty();
for (int i = 1; i < componentDefinitions.length; i++) {
boolean condition1 = componentDefinitions[i] instanceof BeanComponentDefinition;
assertThat(condition1).isTrue();
}
Arrays.stream(componentDefinitions).skip(1).forEach(definition ->
assertThat(definition).isInstanceOf(BeanComponentDefinition.class));
ComponentDefinition[] nestedComponentDefs2 = acd.getNestedComponents();
assertThat(nestedComponentDefs2.length).as("Inner PointcutComponentDefinition not found").isEqualTo(1);
boolean condition1 = nestedComponentDefs2[0] instanceof PointcutComponentDefinition;
assertThat(condition1).isTrue();
assertThat(nestedComponentDefs2).as("Inner PointcutComponentDefinition not found").hasSize(1);
assertThat(nestedComponentDefs2[0]).isInstanceOf(PointcutComponentDefinition.class);
PointcutComponentDefinition pcd = (PointcutComponentDefinition) nestedComponentDefs2[0];
assertThat(pcd.getBeanDefinitions().length).as("Incorrect number of BeanDefinitions").isEqualTo(1);
assertThat(pcd.getBeanDefinitions()).as("Incorrect number of BeanDefinitions").hasSize(1);
}
}
@@ -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.
@@ -30,10 +30,10 @@ import static org.springframework.core.testfixture.io.ResourceTestUtils.qualifie
* @author Mark Fisher
* @author Chris Beams
*/
public class AopNamespaceHandlerPointcutErrorTests {
class AopNamespaceHandlerPointcutErrorTests {
@Test
public void testDuplicatePointcutConfig() {
void duplicatePointcutConfig() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(() ->
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
@@ -42,7 +42,7 @@ public class AopNamespaceHandlerPointcutErrorTests {
}
@Test
public void testMissingPointcutConfig() {
void missingPointcutConfig() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(() ->
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
@@ -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.
@@ -30,10 +30,10 @@ import static org.springframework.core.testfixture.io.ResourceTestUtils.qualifie
* @author Rob Harrop
* @author Chris Beams
*/
public class TopLevelAopTagTests {
class TopLevelAopTagTests {
@Test
public void testParse() {
void parse() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(
qualifiedResource(TopLevelAopTagTests.class, "context.xml"));
@@ -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.
@@ -19,6 +19,7 @@ package org.springframework.aop.framework;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
@@ -32,6 +33,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
/**
* @author Rod Johnson
* @author Chris Beams
* @author Sam Brannen
*/
public class AopProxyUtilsTests {
@@ -132,4 +134,61 @@ public class AopProxyUtilsTests {
AopProxyUtils.proxiedUserInterfaces(proxy));
}
@Test
void isLambda() {
assertIsLambda(AopProxyUtilsTests.staticLambdaExpression);
assertIsLambda(AopProxyUtilsTests::staticStringFactory);
assertIsLambda(this.instanceLambdaExpression);
assertIsLambda(this::instanceStringFactory);
}
@Test
void isNotLambda() {
assertIsNotLambda(new EnigmaSupplier());
assertIsNotLambda(new Supplier<String>() {
@Override
public String get() {
return "anonymous inner class";
}
});
assertIsNotLambda(new Fake$$LambdaSupplier());
}
private static void assertIsLambda(Supplier<String> supplier) {
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isTrue();
}
private static void assertIsNotLambda(Supplier<String> supplier) {
assertThat(AopProxyUtils.isLambda(supplier.getClass())).isFalse();
}
private static final Supplier<String> staticLambdaExpression = () -> "static lambda expression";
private final Supplier<String> instanceLambdaExpression = () -> "instance lambda expressions";
private static String staticStringFactory() {
return "static string factory";
}
private String instanceStringFactory() {
return "instance string factory";
}
private static class EnigmaSupplier implements Supplier<String> {
@Override
public String get() {
return "enigma";
}
}
private static class Fake$$LambdaSupplier implements Supplier<String> {
@Override
public String get() {
return "fake lambda";
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -183,7 +183,7 @@ public class ProxyFactoryTests {
}
@Test
public void testGetsAllInterfaces() throws Exception {
public void testGetsAllInterfaces() {
// Extend to get new interface
class TestBeanSubclass extends TestBean implements Comparable<Object> {
@Override
@@ -240,6 +240,16 @@ public class ProxyFactoryTests {
assertThat(factory.countAdvicesOfType(NopInterceptor.class) == 2).isTrue();
}
@Test
public void testSealedInterfaceExclusion() {
// String implements ConstantDesc on JDK 12+, sealed as of JDK 17
ProxyFactory factory = new ProxyFactory(new String());
NopInterceptor di = new NopInterceptor();
factory.addAdvice(0, di);
Object proxy = factory.getProxy();
assertThat(proxy).isInstanceOf(CharSequence.class);
}
/**
* Should see effect immediately on behavior.
*/
@@ -125,16 +125,7 @@ public class ConcurrencyThrottleInterceptorTests {
try {
this.proxy.exceptional(this.ex);
}
catch (RuntimeException ex) {
if (ex == this.ex) {
logger.debug("Expected exception thrown", ex);
}
else {
// should never happen
ex.printStackTrace();
}
}
catch (Error err) {
catch (RuntimeException | Error err) {
if (err == this.ex) {
logger.debug("Expected exception thrown", err);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.support;
import org.junit.jupiter.api.Test;
@@ -29,10 +30,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Rob Harrop
* @author Rick Evans
*/
public class ClassUtilsTests {
class ClassUtilsTests {
@Test
public void getShortNameForCglibClass() {
void getShortNameForCglibClass() {
TestBean tb = new TestBean();
ProxyFactory pf = new ProxyFactory();
pf.setTarget(tb);
@@ -41,4 +42,5 @@ public class ClassUtilsTests {
String className = ClassUtils.getShortName(proxy.getClass());
assertThat(className).as("Class name did not match").isEqualTo("TestBean");
}
}
@@ -16,12 +16,6 @@
</aop:aspect>
</aop:config>
<bean id="getNameCounter" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
<bean id="getAgeCounter" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
<bean id="testBean" class="org.springframework.beans.testfixture.beans.TestBean"/>
<bean id="countingAdvice" class="org.springframework.aop.config.CountingAspectJAdvice"/>
</beans>
@@ -9,6 +9,6 @@
<aop:advisor advice-ref="countingAdvice" pointcut="within(org.springframework..*)"/>
</aop:config>
<bean id="countingAdvice" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
<bean id="countingAdvice" class="org.springframework.aop.testfixture.advice.CountingBeforeAdvice"/>
</beans>
@@ -10,6 +10,6 @@
<aop:advisor advice-ref="countingAdvice" pointcut-ref="pc"/>
</aop:config>
<bean id="countingAdvice" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
<bean id="countingAdvice" class="org.springframework.aop.testfixture.advice.CountingBeforeAdvice"/>
</beans>
@@ -12,10 +12,6 @@
</aop:aspect>
</aop:config>
<bean id="getAgeCounter" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
<bean id="testBean" class="org.springframework.beans.testfixture.beans.TestBean"/>
<bean id="countingAdvice" class="org.springframework.aop.config.CountingAspectJAdvice"/>
</beans>
@@ -12,10 +12,6 @@
</aop:aspect>
</aop:config>
<bean id="getAgeCounter" class="org.springframework.aop.framework.CountingBeforeAdvice"/>
<bean id="testBean" class="org.springframework.beans.testfixture.beans.TestBean"/>
<bean id="countingAdvice" class="org.springframework.aop.config.CountingAspectJAdvice"/>
</beans>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -19,6 +19,7 @@ package org.springframework.aop.testfixture.advice;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* Abstract superclass for counting advices etc.
@@ -31,7 +32,7 @@ import java.util.HashMap;
public class MethodCounter implements Serializable {
/** Method name --> count, does not understand overloading */
private HashMap<String, Integer> map = new HashMap<>();
private Map<String, Integer> map = new HashMap<>();
private int allCount;
+8 -8
View File
@@ -11,7 +11,7 @@ sourceSets.test.java.srcDirs = files()
aspectj.version = dependencyManagement.managedVersions['org.aspectj:aspectjweaver']
dependencies {
compile("org.aspectj:aspectjweaver")
api("org.aspectj:aspectjweaver")
compileOnly("org.aspectj:aspectjrt")
optional(project(":spring-aop")) // for @Async support
optional(project(":spring-beans")) // for @Configurable support
@@ -21,13 +21,13 @@ dependencies {
optional(project(":spring-tx")) // for JPA, @Transactional support
optional("javax.cache:cache-api") // for JCache aspect
optional("javax.transaction:javax.transaction-api") // for @javax.transaction.Transactional support
testCompile(project(":spring-core")) // for CodeStyleAspect
testCompile(project(":spring-test"))
testCompile(testFixtures(project(":spring-context")))
testCompile(testFixtures(project(":spring-context-support")))
testCompile(testFixtures(project(":spring-core")))
testCompile(testFixtures(project(":spring-tx")))
testCompile("javax.mail:javax.mail-api")
testImplementation(project(":spring-core")) // for CodeStyleAspect
testImplementation(project(":spring-test"))
testImplementation(testFixtures(project(":spring-context")))
testImplementation(testFixtures(project(":spring-context-support")))
testImplementation(testFixtures(project(":spring-core")))
testImplementation(testFixtures(project(":spring-tx")))
testImplementation("javax.mail:javax.mail-api")
testCompileOnly("org.aspectj:aspectjrt")
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2021 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.
@@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.aspectj;
/**
* Marker interface for domain object that need DI through aspects.
* Marker interface for domain objects that need DI through aspects.
*
* @author Ramnivas Laddad
* @since 2.5
*/
public interface ConfigurableObject {
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
@@ -20,7 +20,6 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
@@ -107,10 +106,7 @@ public class AspectJEnableCachingIsolatedTests {
try {
load(MultiCacheManagerConfigurer.class, EnableCachingConfig.class);
}
catch (BeanCreationException ex) {
Throwable root = ex.getRootCause();
boolean condition = root instanceof IllegalStateException;
assertThat(condition).isTrue();
catch (IllegalStateException ex) {
assertThat(ex.getMessage().contains("implementations of CachingConfigurer")).isTrue();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2021 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,13 +22,18 @@ import org.springframework.contextsupport.testfixture.jcache.AbstractJCacheAnnot
/**
* @author Stephane Nicoll
* @author Sam Brannen
*/
public class JCacheAspectJNamespaceConfigTests extends AbstractJCacheAnnotationTests {
@Override
protected ApplicationContext getApplicationContext() {
return new GenericXmlApplicationContext(
"/org/springframework/cache/config/annotation-jcache-aspectj.xml");
GenericXmlApplicationContext context = new GenericXmlApplicationContext();
// Disallow bean definition overriding to test https://github.com/spring-projects/spring-framework/pull/27499
context.setAllowBeanDefinitionOverriding(false);
context.load("/org/springframework/cache/config/annotation-jcache-aspectj.xml");
context.refresh();
return context;
}
}
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.transaction.aspectj;
import org.springframework.transaction.annotation.Transactional;
@@ -29,4 +30,5 @@ public class ClassWithPrivateAnnotatedMember {
@Transactional
private void doInTransaction() {}
}
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.transaction.aspectj;
import org.springframework.transaction.annotation.Transactional;
@@ -29,4 +30,5 @@ public class ClassWithProtectedAnnotatedMember {
@Transactional
protected void doInTransaction() {}
}
+3 -3
View File
@@ -4,14 +4,14 @@ apply plugin: "groovy"
apply plugin: "kotlin"
dependencies {
compile(project(":spring-core"))
api(project(":spring-core"))
optional("javax.inject:javax.inject")
optional("org.yaml:snakeyaml")
optional("org.codehaus.groovy:groovy-xml")
optional("org.jetbrains.kotlin:kotlin-reflect")
optional("org.jetbrains.kotlin:kotlin-stdlib")
testCompile(testFixtures(project(":spring-core")))
testCompile("javax.annotation:javax.annotation-api")
testImplementation(testFixtures(project(":spring-core")))
testImplementation("javax.annotation:javax.annotation-api")
testFixturesApi("org.junit.jupiter:junit-jupiter-api")
testFixturesImplementation("org.assertj:assertj-core")
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -41,8 +41,6 @@ import kotlin.reflect.KParameter;
import kotlin.reflect.full.KClasses;
import kotlin.reflect.jvm.KCallablesJvm;
import kotlin.reflect.jvm.ReflectJvmMapping;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.KotlinDetector;
@@ -75,8 +73,6 @@ import org.springframework.util.StringUtils;
*/
public abstract class BeanUtils {
private static final Log logger = LogFactory.getLog(BeanUtils.class);
private static final ParameterNameDiscoverer parameterNameDiscoverer =
new DefaultParameterNameDiscoverer();
@@ -91,7 +87,10 @@ public abstract class BeanUtils {
values.put(byte.class, (byte) 0);
values.put(short.class, (short) 0);
values.put(int.class, 0);
values.put(long.class, (long) 0);
values.put(long.class, 0L);
values.put(float.class, 0F);
values.put(double.class, 0D);
values.put(char.class, '\0');
DEFAULT_TYPE_VALUES = Collections.unmodifiableMap(values);
}
@@ -101,9 +100,9 @@ public abstract class BeanUtils {
* @param clazz class to instantiate
* @return the new instance
* @throws BeanInstantiationException if the bean cannot be instantiated
* @see Class#newInstance()
* @deprecated as of Spring 5.0, following the deprecation of
* {@link Class#newInstance()} in JDK 9
* @see Class#newInstance()
*/
@Deprecated
public static <T> T instantiate(Class<T> clazz) throws BeanInstantiationException {
@@ -227,32 +226,45 @@ public abstract class BeanUtils {
}
/**
* Return a resolvable constructor for the provided class, either a primary constructor
* or single public constructor or simply a default constructor. Callers have to be
* prepared to resolve arguments for the returned constructor's parameters, if any.
* Return a resolvable constructor for the provided class, either a primary or single
* public constructor with arguments, or a single non-public constructor with arguments,
* or simply a default constructor. Callers have to be prepared to resolve arguments
* for the returned constructor's parameters, if any.
* @param clazz the class to check
* @throws IllegalStateException in case of no unique constructor found at all
* @since 5.3
* @see #findPrimaryConstructor
*/
@SuppressWarnings("unchecked")
public static <T> Constructor<T> getResolvableConstructor(Class<T> clazz) {
Constructor<T> ctor = findPrimaryConstructor(clazz);
if (ctor == null) {
Constructor<?>[] ctors = clazz.getConstructors();
if (ctor != null) {
return ctor;
}
Constructor<?>[] ctors = clazz.getConstructors();
if (ctors.length == 1) {
// A single public constructor
return (Constructor<T>) ctors[0];
}
else if (ctors.length == 0){
ctors = clazz.getDeclaredConstructors();
if (ctors.length == 1) {
ctor = (Constructor<T>) ctors[0];
}
else {
try {
ctor = clazz.getDeclaredConstructor();
}
catch (NoSuchMethodException ex) {
throw new IllegalStateException("No primary or single public constructor found for " +
clazz + " - and no default constructor found either");
}
// A single non-public constructor, e.g. from a non-public record type
return (Constructor<T>) ctors[0];
}
}
return ctor;
// Several constructors -> let's try to take the default constructor
try {
return clazz.getDeclaredConstructor();
}
catch (NoSuchMethodException ex) {
// Giving up...
}
// No unique constructor at all
throw new IllegalStateException("No primary or single unique constructor found for " + clazz);
}
/**
@@ -528,7 +540,7 @@ public abstract class BeanUtils {
/**
* Find a JavaBeans PropertyEditor following the 'Editor' suffix convention
* (e.g. "mypackage.MyDomainClass" -> "mypackage.MyDomainClassEditor").
* (e.g. "mypackage.MyDomainClass" &rarr; "mypackage.MyDomainClassEditor").
* <p>Compatible to the standard JavaBeans convention as implemented by
* {@link java.beans.PropertyEditorManager} but isolated from the latter's
* registered default editors for primitive types.
@@ -551,9 +563,6 @@ public abstract class BeanUtils {
}
catch (Throwable ex) {
// e.g. AccessControlException on Google App Engine
if (logger.isDebugEnabled()) {
logger.debug("Could not access system ClassLoader: " + ex);
}
return null;
}
}
@@ -564,10 +573,6 @@ public abstract class BeanUtils {
Class<?> editorClass = cl.loadClass(editorName);
if (editorClass != null) {
if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
if (logger.isInfoEnabled()) {
logger.info("Editor class [" + editorName +
"] does not implement [java.beans.PropertyEditor] interface");
}
unknownEditorTypes.add(targetType);
return null;
}
@@ -579,10 +584,6 @@ public abstract class BeanUtils {
catch (ClassNotFoundException ex) {
// Ignore - fall back to unknown editor type registration below
}
if (logger.isTraceEnabled()) {
logger.trace("No property editor [" + editorName + "] found for type " +
targetTypeName + " according to 'Editor' suffix convention");
}
unknownEditorTypes.add(targetType);
return null;
}
@@ -690,7 +691,25 @@ public abstract class BeanUtils {
* from each other, as long as the properties match. Any bean properties that the
* source bean exposes but the target bean does not will silently be ignored.
* <p>This is just a convenience method. For more complex transfer needs,
* consider using a full BeanWrapper.
* consider using a full {@link BeanWrapper}.
* <p>As of Spring Framework 5.3, this method honors generic type information
* when matching properties in the source and target objects.
* <p>The following table provides a non-exhaustive set of examples of source
* and target property types that can be copied as well as source and target
* property types that cannot be copied.
* <table border="1">
* <tr><th>source property type</th><th>target property type</th><th>copy supported</th></tr>
* <tr><td>{@code Integer}</td><td>{@code Integer}</td><td>yes</td></tr>
* <tr><td>{@code Integer}</td><td>{@code Number}</td><td>yes</td></tr>
* <tr><td>{@code List<Integer>}</td><td>{@code List<Integer>}</td><td>yes</td></tr>
* <tr><td>{@code List<?>}</td><td>{@code List<?>}</td><td>yes</td></tr>
* <tr><td>{@code List<Integer>}</td><td>{@code List<?>}</td><td>yes</td></tr>
* <tr><td>{@code List<Integer>}</td><td>{@code List<? extends Number>}</td><td>yes</td></tr>
* <tr><td>{@code String}</td><td>{@code Integer}</td><td>no</td></tr>
* <tr><td>{@code Number}</td><td>{@code Integer}</td><td>no</td></tr>
* <tr><td>{@code List<Integer>}</td><td>{@code List<Long>}</td><td>no</td></tr>
* <tr><td>{@code List<Integer>}</td><td>{@code List<Number>}</td><td>no</td></tr>
* </table>
* @param source the source bean
* @param target the target bean
* @throws BeansException if the copying failed
@@ -707,7 +726,10 @@ public abstract class BeanUtils {
* from each other, as long as the properties match. Any bean properties that the
* source bean exposes but the target bean does not will silently be ignored.
* <p>This is just a convenience method. For more complex transfer needs,
* consider using a full BeanWrapper.
* consider using a full {@link BeanWrapper}.
* <p>As of Spring Framework 5.3, this method honors generic type information
* when matching properties in the source and target objects. See the
* documentation for {@link #copyProperties(Object, Object)} for details.
* @param source the source bean
* @param target the target bean
* @param editable the class (or interface) to restrict property setting to
@@ -725,7 +747,10 @@ public abstract class BeanUtils {
* from each other, as long as the properties match. Any bean properties that the
* source bean exposes but the target bean does not will silently be ignored.
* <p>This is just a convenience method. For more complex transfer needs,
* consider using a full BeanWrapper.
* consider using a full {@link BeanWrapper}.
* <p>As of Spring Framework 5.3, this method honors generic type information
* when matching properties in the source and target objects. See the
* documentation for {@link #copyProperties(Object, Object)} for details.
* @param source the source bean
* @param target the target bean
* @param ignoreProperties array of property names to ignore
@@ -742,7 +767,8 @@ public abstract class BeanUtils {
* from each other, as long as the properties match. Any bean properties that the
* source bean exposes but the target bean does not will silently be ignored.
* <p>As of Spring Framework 5.3, this method honors generic type information
* when matching properties in the source and target objects.
* when matching properties in the source and target objects. See the
* documentation for {@link #copyProperties(Object, Object)} for details.
* @param source the source bean
* @param target the target bean
* @param editable the class (or interface) to restrict property setting to
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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,6 +22,7 @@ import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -286,9 +287,13 @@ public final class CachedIntrospectionResults {
// This call is slow so we do it once.
PropertyDescriptor[] pds = this.beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if (Class.class == beanClass &&
("classLoader".equals(pd.getName()) || "protectionDomain".equals(pd.getName()))) {
// Ignore Class.getClassLoader() and getProtectionDomain() methods - nobody needs to bind to those
if (Class.class == beanClass && (!"name".equals(pd.getName()) && !pd.getName().endsWith("Name"))) {
// Only allow all name variants of Class properties
continue;
}
if (pd.getPropertyType() != null && (ClassLoader.class.isAssignableFrom(pd.getPropertyType())
|| ProtectionDomain.class.isAssignableFrom(pd.getPropertyType()))) {
// Ignore ClassLoader and ProtectionDomain types - nobody needs to bind to those
continue;
}
if (logger.isTraceEnabled()) {
@@ -337,6 +342,11 @@ public final class CachedIntrospectionResults {
// GenericTypeAwarePropertyDescriptor leniently resolves a set* write method
// against a declared read method, so we prefer read method descriptors here.
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
if (pd.getPropertyType() != null && (ClassLoader.class.isAssignableFrom(pd.getPropertyType())
|| ProtectionDomain.class.isAssignableFrom(pd.getPropertyType()))) {
// Ignore ClassLoader and ProtectionDomain types - nobody needs to bind to those
continue;
}
this.propertyDescriptors.put(pd.getName(), pd);
Method readMethod = pd.getReadMethod();
if (readMethod != null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -138,7 +138,7 @@ final class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
Set<Method> ambiguousCandidates = this.ambiguousWriteMethods;
if (ambiguousCandidates != null) {
this.ambiguousWriteMethods = null;
LogFactory.getLog(GenericTypeAwarePropertyDescriptor.class).warn("Invalid JavaBean property '" +
LogFactory.getLog(GenericTypeAwarePropertyDescriptor.class).debug("Non-unique JavaBean property '" +
getName() + "' being accessed! Ambiguous write methods found next to actually used [" +
this.writeMethod + "]: " + ambiguousCandidates);
}
@@ -134,8 +134,8 @@ public abstract class PropertyAccessorUtils {
/**
* Determine the canonical name for the given property path.
* Removes surrounding quotes from map keys:<br>
* {@code map['key']} -> {@code map[key]}<br>
* {@code map["key"]} -> {@code map[key]}
* {@code map['key']} &rarr; {@code map[key]}<br>
* {@code map["key"]} &rarr; {@code map[key]}
* @param propertyName the bean property path
* @return the canonical representation of the property path
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -422,10 +422,13 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
}
if (editor == null) {
// Find editor for superclass or interface.
for (Iterator<Class<?>> it = this.customEditors.keySet().iterator(); it.hasNext() && editor == null;) {
Class<?> key = it.next();
for (Map.Entry<Class<?>, PropertyEditor> entry : this.customEditors.entrySet()) {
if (editor != null) {
break;
}
Class<?> key = entry.getKey();
if (key.isAssignableFrom(requiredType)) {
editor = this.customEditors.get(key);
editor = entry.getValue();
// Cache editor for search type, to avoid the overhead
// of repeated assignable-from checks.
if (this.customEditorCache == null) {
@@ -247,14 +247,14 @@ class TypeConverterDelegate {
// Definitely doesn't match: throw IllegalArgumentException/IllegalStateException
StringBuilder msg = new StringBuilder();
msg.append("Cannot convert value of type '").append(ClassUtils.getDescriptiveType(newValue));
msg.append("' to required type '").append(ClassUtils.getQualifiedName(requiredType)).append("'");
msg.append("' to required type '").append(ClassUtils.getQualifiedName(requiredType)).append('\'');
if (propertyName != null) {
msg.append(" for property '").append(propertyName).append("'");
msg.append(" for property '").append(propertyName).append('\'');
}
if (editor != null) {
msg.append(": PropertyEditor [").append(editor.getClass().getName()).append(
"] returned inappropriate value of type '").append(
ClassUtils.getDescriptiveType(convertedValue)).append("'");
ClassUtils.getDescriptiveType(convertedValue)).append('\'');
throw new IllegalArgumentException(msg.toString());
}
else {
@@ -1,5 +1,5 @@
/**
* Support package for beans-style handling of Java 5 annotations.
* Support package for beans-style handling of annotations.
*/
@NonNullApi
@NonNullFields
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -84,7 +84,7 @@ import org.springframework.lang.Nullable;
* (only applicable when running in a web application context)
* <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
* <li>InitializingBean's {@code afterPropertiesSet}
* <li>a custom init-method definition
* <li>a custom {@code init-method} definition
* <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
* </ol>
*
@@ -92,7 +92,7 @@ import org.springframework.lang.Nullable;
* <ol>
* <li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
* <li>DisposableBean's {@code destroy}
* <li>a custom destroy-method definition
* <li>a custom {@code destroy-method} definition
* </ol>
*
* @author Rod Johnson
@@ -102,6 +102,8 @@ import org.springframework.lang.Nullable;
* @see BeanNameAware#setBeanName
* @see BeanClassLoaderAware#setBeanClassLoader
* @see BeanFactoryAware#setBeanFactory
* @see org.springframework.context.EnvironmentAware#setEnvironment
* @see org.springframework.context.EmbeddedValueResolverAware#setEmbeddedValueResolver
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader
* @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher
* @see org.springframework.context.MessageSourceAware#setMessageSource
@@ -111,6 +113,7 @@ import org.springframework.lang.Nullable;
* @see InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
* @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor#postProcessBeforeDestruction
* @see DisposableBean#destroy
* @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName
*/
@@ -211,6 +214,7 @@ public interface BeanFactory {
/**
* Return a provider for the specified bean, allowing for lazy on-demand retrieval
* of instances, including availability and uniqueness options.
* <p>For matching a generic type, consider {@link #getBeanProvider(ResolvableType)}.
* @param requiredType type the bean must match; can be an interface or superclass
* @return a corresponding provider handle
* @since 5.1
@@ -220,13 +224,20 @@ public interface BeanFactory {
/**
* Return a provider for the specified bean, allowing for lazy on-demand retrieval
* of instances, including availability and uniqueness options.
* @param requiredType type the bean must match; can be a generic type declaration.
* Note that collection types are not supported here, in contrast to reflective
* of instances, including availability and uniqueness options. This variant allows
* for specifying a generic type to match, similar to reflective injection points
* with generic type declarations in method/constructor parameters.
* <p>Note that collections of beans are not supported here, in contrast to reflective
* injection points. For programmatically retrieving a list of beans matching a
* specific type, specify the actual bean type as an argument here and subsequently
* use {@link ObjectProvider#orderedStream()} or its lazy streaming/iteration options.
* <p>Also, generics matching is strict here, as per the Java assignment rules.
* For lenient fallback matching with unchecked semantics (similar to the ´unchecked´
* Java compiler warning), consider calling {@link #getBeanProvider(Class)} with the
* raw type as a second step if no full generic match is
* {@link ObjectProvider#getIfAvailable() available} with this variant.
* @return a corresponding provider handle
* @param requiredType type the bean must match; can be a generic type declaration
* @since 5.1
* @see ObjectProvider#iterator()
* @see ObjectProvider#stream()
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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.
@@ -353,9 +353,31 @@ public interface ListableBeanFactory extends BeanFactory {
* @since 3.0
* @see #getBeanNamesForAnnotation
* @see #getBeansWithAnnotation
* @see #getType(String)
*/
@Nullable
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
/**
* Find an {@link Annotation} of {@code annotationType} on the specified bean,
* traversing its interfaces and super classes if no annotation can be found on
* the given class itself, as well as checking the bean's factory method (if any).
* @param beanName the name of the bean to look for annotations on
* @param annotationType the type of annotation to look for
* (at class, interface or factory method level of the specified bean)
* @param allowFactoryBeanInit whether a {@code FactoryBean} may get initialized
* just for the purpose of determining its object type
* @return the annotation of the given type if found, or {@code null} otherwise
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 5.3.14
* @see #getBeanNamesForAnnotation
* @see #getBeansWithAnnotation
* @see #getType(String, boolean)
*/
@Nullable
<A extends Annotation> A findAnnotationOnBean(
String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)
throws NoSuchBeanDefinitionException;
}
@@ -459,7 +459,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
return metadata;
}
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
@@ -537,11 +537,10 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
* @param ann the Autowired annotation
* @return whether the annotation indicates that a dependency is required
*/
@SuppressWarnings({"deprecation", "cast"})
@SuppressWarnings("deprecation")
protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
// The following (AnnotationAttributes) cast is required on JDK 9+.
return determineRequiredStatus((AnnotationAttributes)
ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
return determineRequiredStatus(ann.<AnnotationAttributes> asMap(
mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
}
/**
@@ -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.
@@ -302,7 +302,7 @@ public class InitDestroyAnnotationBeanPostProcessor
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
checkedInitMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + element);
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
}
}
}
@@ -313,7 +313,7 @@ public class InitDestroyAnnotationBeanPostProcessor
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
checkedDestroyMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + element);
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -44,7 +44,7 @@ import org.springframework.util.Assert;
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
* that enforces required JavaBean properties to have been configured.
* Required bean properties are detected through a Java 5 annotation:
* Required bean properties are detected through an annotation:
* by default, Spring's {@link Required} annotation.
*
* <p>The motivation for the existence of this BeanPostProcessor is to allow
@@ -217,13 +217,13 @@ public class RequiredAnnotationBeanPostProcessor implements SmartInstantiationAw
sb.append(" and");
}
else {
sb.append(",");
sb.append(',');
}
}
sb.append(" '").append(propertyName).append("'");
sb.append(" '").append(propertyName).append('\'');
}
sb.append(size == 1 ? " is" : " are");
sb.append(" required for bean '").append(beanName).append("'");
sb.append(" required for bean '").append(beanName).append('\'');
return sb.toString();
}

Some files were not shown because too many files have changed in this diff Show More