Compare commits

...

347 Commits

Author SHA1 Message Date
Spring Builds 850cb6c4c9 Release v5.3.12 2021-10-21 05:44:20 +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
837 changed files with 9522 additions and 5773 deletions
+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.
+75 -65
View File
@@ -1,17 +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.5.10' 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.jmh" version "0.6.4" apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.5.10" 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.5.0' apply false
id 'org.jetbrains.kotlin.jvm' version '1.5.31' apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.5.31" 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 {
@@ -27,16 +27,16 @@ configure(allprojects) { project ->
dependencyManagement {
imports {
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.3"
mavenBom "io.netty:netty-bom:4.1.65.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.7"
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5"
mavenBom "io.netty:netty-bom:4.1.69.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.12"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10"
mavenBom "io.rsocket:rsocket-bom:1.1.0"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.41.v20210516"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.10"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.0"
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.1"
mavenBom "org.junit:junit-bom:5.7.2"
mavenBom "io.rsocket:rsocket-bom:1.1.1"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.44.v20210927"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.31"
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.1"
}
dependencies {
dependencySet(group: 'org.apache.logging.log4j', version: '2.14.1') {
@@ -45,18 +45,18 @@ configure(allprojects) { project ->
entry 'log4j-jul'
entry 'log4j-slf4j-impl'
}
dependency "org.slf4j:slf4j-api:1.7.30"
dependency "org.slf4j:slf4j-api:1.7.32"
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.8') {
dependencySet(group: 'org.codehaus.groovy', version: '3.0.9') {
entry 'groovy'
entry 'groovy-jsr223'
entry 'groovy-templates' // requires findbugs for warning-free compilation
@@ -67,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.13"
dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE"
dependency "io.reactivex.rxjava3:rxjava:3.1.1"
dependency "io.smallrye.reactive:mutiny:1.1.1"
dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE"
dependency "com.caucho:hessian:4.0.63"
dependency "com.fasterxml:aalto-xml:1.3.0"
dependency("com.fasterxml.woodstox:woodstox-core:6.2.6") {
exclude group: "stax", name: "stax-api"
}
dependency "com.google.code.gson:gson:2.8.7"
dependency "com.google.protobuf:protobuf-java-util:3.17.2"
dependency "com.google.code.gson:gson:2.8.8"
dependency "com.google.protobuf:protobuf-java-util:3.18.0"
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
dependency("com.thoughtworks.xstream:xstream:1.4.17") {
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.14"
dependency("org.codehaus.jettison:jettison:1.3.8") {
exclude group: "stax", name: "stax-api"
}
@@ -91,14 +92,14 @@ configure(allprojects) { project ->
entry 'jibx-run'
}
dependency "org.ogce:xpp3:1.1.6"
dependency "org.yaml:snakeyaml:1.28"
dependency "org.yaml:snakeyaml:1.29"
dependency "com.h2database:h2:1.4.200"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.1"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.2"
dependency "com.github.librepdf:openpdf:1.3.26"
dependency "com.rometools:rome:1.15.0"
dependency "com.rometools:rome:1.16.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.2') {
entry 'activemq-broker'
@@ -124,28 +125,28 @@ configure(allprojects) { project ->
dependency "org.ehcache:ehcache:3.4.0"
dependency "org.hibernate:hibernate-core:5.4.32.Final"
dependency "org.hibernate:hibernate-validator:6.2.0.Final"
dependency "org.webjars:webjars-locator-core:0.46"
dependency "org.webjars:webjars-locator-core:0.48"
dependency "org.webjars:underscorejs:1.8.3"
dependencySet(group: 'org.apache.tomcat', version: '9.0.45') {
dependencySet(group: 'org.apache.tomcat', version: '9.0.53') {
entry 'tomcat-util'
entry('tomcat-websocket') {
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
}
}
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.45') {
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.53') {
entry 'tomcat-embed-core'
entry 'tomcat-embed-websocket'
}
dependencySet(group: 'io.undertow', version: '2.2.8.Final') {
dependencySet(group: 'io.undertow', version: '2.2.12.Final') {
entry 'undertow-core'
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"
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"
}
}
@@ -161,9 +162,9 @@ configure(allprojects) { project ->
}
dependency 'org.apache.httpcomponents.client5:httpclient5:5.1'
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.1'
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.8"
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.9"
dependency "org.jruby:jruby:9.2.17.0"
dependency "org.jruby:jruby:9.2.19.0"
dependency "org.python:jython-standalone:2.7.1"
dependency "org.mozilla:rhino:1.7.11"
@@ -187,27 +188,28 @@ configure(allprojects) { project ->
exclude group: "junit", name: "junit"
}
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"
dependency "org.assertj:assertj-core:3.21.0"
dependencySet(group: 'org.xmlunit', version: '2.8.2') {
entry 'xmlunit-assertj'
entry('xmlunit-matchers') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
}
dependencySet(group: 'org.mockito', version: '3.11.0') {
dependencySet(group: 'org.mockito', version: '4.0.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.0"
dependency("net.sourceforge.htmlunit:htmlunit:2.50.0") {
dependency("net.sourceforge.htmlunit:htmlunit:2.53.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:htmlunit-driver:2.50.0") {
dependency("org.seleniumhq.selenium:htmlunit-driver:2.53.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
@@ -215,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') {
@@ -236,7 +238,7 @@ 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 "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.9"
dependency "org.javamoney:moneta:1.3"
dependency "com.sun.activation:javax.activation:1.2.0"
@@ -312,6 +314,8 @@ configure([rootProject] + javaProjects) { project ->
pluginManager.withPlugin("kotlin") {
apply plugin: "org.jetbrains.dokka"
apply from: "${rootDir}/gradle/docs-dokka.gradle"
compileKotlin {
kotlinOptions {
languageVersion = "1.3"
@@ -336,35 +340,36 @@ configure([rootProject] + javaProjects) { project ->
}
checkstyle {
toolVersion = "8.43"
toolVersion = "9.0"
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.platform:junit-platform-launcher")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
testRuntimeOnly("org.junit.platform:junit-platform-suite-engine")
testRuntimeOnly("org.apache.logging.log4j:log4j-core")
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl")
testRuntimeOnly("org.apache.logging.log4j:log4j-jul")
// 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.29")
}
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/",
@@ -378,7 +383,12 @@ configure([rootProject] + javaProjects) { project ->
"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.2/api/"
// Disabling linking to JUnit 5.8.1, 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.1/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/"
] as String[]
}
+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-20210827
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 JDK16 /opt/openjdk/java16
ENV PATH $JAVA_HOME/bin:$PATH
+4 -4
View File
@@ -3,13 +3,13 @@ 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/jdk8u302-b08/OpenJDK8U-jdk_x64_linux_hotspot_8u302b08.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.12%2B7/OpenJDK11U-jdk_x64_linux_hotspot_11.0.12_7.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"
java16)
echo "https://github.com/adoptium/temurin16-binaries/releases/download/jdk-16.0.2%2B7/OpenJDK16U-jdk_x64_linux_hotspot_16.0.2_7.tar.gz"
;;
*)
echo $"Unknown java version"
+1 -1
View File
@@ -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 java16
do
JDK_URL=$( /get-jdk-url.sh $jdk )
mkdir $jdk
+1 -1
View File
@@ -5,7 +5,7 @@ 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: "main"
branch: "5.3.x"
milestone: "5.3.x"
build-name: "spring-framework"
pipeline-name: "spring-framework"
+15 -10
View File
@@ -2,7 +2,7 @@ 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))
@@ -45,7 +45,12 @@ 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:
@@ -119,14 +124,14 @@ resources:
access_token: ((github-ci-status-token))
branch: ((branch))
context: jdk11-build
- name: repo-status-jdk15-build
- name: repo-status-jdk16-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: jdk16-build
- name: slack-alert
type: slack-notification
icon: slack
@@ -244,7 +249,7 @@ jobs:
<<: *slack-fail-params
- put: repo-status-jdk11-build
params: { state: "success", commit: "git-repo" }
- name: jdk15-build
- name: jdk16-build
serial: true
public: true
plan:
@@ -252,7 +257,7 @@ jobs:
- get: git-repo
- get: every-morning
trigger: true
- put: repo-status-jdk15-build
- put: repo-status-jdk16-build
params: { state: "pending", commit: "git-repo" }
- do:
- task: check-project
@@ -265,12 +270,12 @@ jobs:
<<: *build-project-task-params
on_failure:
do:
- put: repo-status-jdk15-build
- put: repo-status-jdk16-build
params: { state: "failure", commit: "git-repo" }
- put: slack-alert
params:
<<: *slack-fail-params
- put: repo-status-jdk15-build
- put: repo-status-jdk16-build
params: { state: "success", commit: "git-repo" }
- name: build-pull-requests
serial: true
@@ -292,7 +297,7 @@ jobs:
privileged: true
timeout: ((task-timeout))
params:
<<: *build-project-task-params
BRANCH: ((branch))
on_success:
put: git-pull-request
params:
@@ -453,7 +458,7 @@ jobs:
groups:
- name: "builds"
jobs: ["build", "jdk11-build", "jdk15-build"]
jobs: ["build", "jdk11-build", "jdk16-build"]
- name: "releases"
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"]
- name: "ci-images"
+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
+1 -1
View File
@@ -4,7 +4,7 @@ image_resource:
type: registry-image
source:
repository: springio/github-changelog-generator
tag: '0.0.6'
tag: '0.0.7'
inputs:
- name: git-repo
- name: artifactory-repo
+1 -1
View File
@@ -1,4 +1,4 @@
version=5.3.8-SNAPSHOT
version=5.3.12
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/"))
}
}
}
}
+20 -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: '',
@@ -144,7 +106,10 @@ asciidoctorj {
stylesdir: 'css/',
stylesheet: 'stylesheet.css',
'spring-version': project.version,
'spring-framework-main-code': 'https://github.com/spring-projects/spring-framework/tree/main'
'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"
])
}
@@ -185,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."
@@ -204,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"
}
}
@@ -261,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 -49
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,47 +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)
tasks['eclipse'].dependsOn(eclipseSettings)
tasks['eclipseJdt'].dependsOn(eclipseSettings)
tasks['cleanEclipse'].dependsOn(cleanEclipseSettings)
+7 -3
View File
@@ -8,15 +8,19 @@ apply plugin: 'me.champeau.jmh'
apply from: "$rootDir/gradle/publications.gradle"
dependencies {
jmh 'org.openjdk.jmh:jmh-core:1.28'
jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.28'
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()
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 {
+2 -4
View File
@@ -1,7 +1,7 @@
pluginManagement {
repositories {
gradlePluginPortal()
maven { url 'https://repo.spring.io/plugins-release' }
maven { url "https://repo.spring.io/plugins-release" }
}
}
@@ -17,8 +17,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"
@@ -51,7 +49,7 @@ settings.gradle.projectsLoaded {
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);
@@ -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-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,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.
@@ -44,6 +48,11 @@ import org.springframework.util.ObjectUtils;
*/
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
@@ -130,34 +139,23 @@ public abstract class AopProxyUtils {
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);
}
/**
@@ -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-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;
@@ -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);
}
@@ -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-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-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);
@@ -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();
}
@@ -276,14 +276,14 @@ public class AspectJAdviceParameterNameDiscovererTests {
private static String format(String[] names) {
StringBuilder sb = new StringBuilder();
sb.append("(");
sb.append('(');
for (int i = 0; i < names.length; i++) {
sb.append(names[i]);
if ((i + 1) < names.length) {
sb.append(",");
sb.append(',');
}
}
sb.append(")");
sb.append(')');
return sb.toString();
}
@@ -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.
*/
@@ -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");
}
}
+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-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-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.
@@ -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;
}
@@ -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
*/
@@ -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 {
@@ -539,8 +539,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
*/
@SuppressWarnings({"deprecation", "cast"})
protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
// The following (AnnotationAttributes) cast is required on JDK 9+.
return determineRequiredStatus((AnnotationAttributes)
return determineRequiredStatus(
ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
}
@@ -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.
@@ -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();
}
@@ -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.
@@ -351,7 +351,9 @@ public class ConstructorArgumentValues {
* @return the ValueHolder for the argument, or {@code null} if none set
*/
@Nullable
public ValueHolder getArgumentValue(int index, @Nullable Class<?> requiredType, @Nullable String requiredName, @Nullable Set<ValueHolder> usedValueHolders) {
public ValueHolder getArgumentValue(int index, @Nullable Class<?> requiredType,
@Nullable String requiredName, @Nullable Set<ValueHolder> usedValueHolders) {
Assert.isTrue(index >= 0, "Index must not be negative");
ValueHolder valueHolder = getIndexedArgumentValue(index, requiredType, requiredName);
if (valueHolder == null) {
@@ -47,17 +47,17 @@ import org.springframework.util.ClassUtils;
* which uses this class to call a static initialization method:
*
* <pre class="code">
* &lt;bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingBean">
* &lt;property name="staticMethod" value="com.whatever.MyClass.init"/>
* &lt;/bean></pre>
* &lt;bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingBean"&gt;
* &lt;property name="staticMethod" value="com.whatever.MyClass.init"/&gt;
* &lt;/bean&gt;</pre>
*
* <p>An example of calling an instance method to start some server bean:
*
* <pre class="code">
* &lt;bean id="myStarter" class="org.springframework.beans.factory.config.MethodInvokingBean">
* &lt;property name="targetObject" ref="myServer"/>
* &lt;property name="targetMethod" value="start"/>
* &lt;/bean></pre>
* &lt;bean id="myStarter" class="org.springframework.beans.factory.config.MethodInvokingBean"&gt;
* &lt;property name="targetObject" ref="myServer"/&gt;
* &lt;property name="targetMethod" value="start"/&gt;
* &lt;/bean&gt;</pre>
*
* @author Juergen Hoeller
* @since 4.0.3
@@ -56,24 +56,24 @@ import org.springframework.lang.Nullable;
* which uses this class to call a static factory method:
*
* <pre class="code">
* &lt;bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
* &lt;property name="staticMethod" value="com.whatever.MyClassFactory.getInstance"/>
* &lt;/bean></pre>
* &lt;bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"&gt;
* &lt;property name="staticMethod" value="com.whatever.MyClassFactory.getInstance"/&gt;
* &lt;/bean&gt;</pre>
*
* <p>An example of calling a static method then an instance method to get at a
* Java system property. Somewhat verbose, but it works.
*
* <pre class="code">
* &lt;bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
* &lt;property name="targetClass" value="java.lang.System"/>
* &lt;property name="targetMethod" value="getProperties"/>
* &lt;/bean>
* &lt;bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"&gt;
* &lt;property name="targetClass" value="java.lang.System"/&gt;
* &lt;property name="targetMethod" value="getProperties"/&gt;
* &lt;/bean&gt;
*
* &lt;bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
* &lt;property name="targetObject" ref="sysProps"/>
* &lt;property name="targetMethod" value="getProperty"/>
* &lt;property name="arguments" value="java.version"/>
* &lt;/bean></pre>
* &lt;bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"&gt;
* &lt;property name="targetObject" ref="sysProps"/&gt;
* &lt;property name="targetMethod" value="getProperty"/&gt;
* &lt;property name="arguments" value="java.version"/&gt;
* &lt;/bean&gt;</pre>
*
* @author Colin Sampaleanu
* @author Juergen Hoeller
@@ -83,22 +83,22 @@ import org.springframework.util.StringUtils;
* <p>A sample config in an XML-based
* {@link org.springframework.beans.factory.BeanFactory} might look as follows:
*
* <pre class="code">&lt;beans>
* <pre class="code">&lt;beans&gt;
*
* &lt;!-- Prototype bean since we have state -->
* &lt;bean id="myService" class="a.b.c.MyService" singleton="false"/>
* &lt;!-- Prototype bean since we have state --&gt;
* &lt;bean id="myService" class="a.b.c.MyService" singleton="false"/&gt;
*
* &lt;!-- will lookup the above 'myService' bean by *TYPE* -->
* &lt;!-- will lookup the above 'myService' bean by *TYPE* --&gt;
* &lt;bean id="myServiceFactory"
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
* &lt;property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
* &lt;/bean>
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean"&gt;
* &lt;property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/&gt;
* &lt;/bean&gt;
*
* &lt;bean id="clientBean" class="a.b.c.MyClientBean">
* &lt;property name="myServiceFactory" ref="myServiceFactory"/>
* &lt;/bean>
* &lt;bean id="clientBean" class="a.b.c.MyClientBean"&gt;
* &lt;property name="myServiceFactory" ref="myServiceFactory"/&gt;
* &lt;/bean&gt;
*
*&lt;/beans></pre>
*&lt;/beans&gt;</pre>
*
* <p>The attendant {@code MyClientBean} class implementation might then
* look something like this:
@@ -135,22 +135,22 @@ import org.springframework.util.StringUtils;
* <p>A sample config in an XML-based
* {@link org.springframework.beans.factory.BeanFactory} might look as follows:
*
* <pre class="code">&lt;beans>
* <pre class="code">&lt;beans&gt;
*
* &lt;!-- Prototype beans since we have state (both extend MyService) -->
* &lt;bean id="specialService" class="a.b.c.SpecialService" singleton="false"/>
* &lt;bean id="anotherService" class="a.b.c.AnotherService" singleton="false"/>
* &lt;!-- Prototype beans since we have state (both extend MyService) --&gt;
* &lt;bean id="specialService" class="a.b.c.SpecialService" singleton="false"/&gt;
* &lt;bean id="anotherService" class="a.b.c.AnotherService" singleton="false"/&gt;
*
* &lt;bean id="myServiceFactory"
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
* &lt;property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
* &lt;/bean>
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean"&gt;
* &lt;property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/&gt;
* &lt;/bean&gt;
*
* &lt;bean id="clientBean" class="a.b.c.MyClientBean">
* &lt;property name="myServiceFactory" ref="myServiceFactory"/>
* &lt;/bean>
* &lt;bean id="clientBean" class="a.b.c.MyClientBean"&gt;
* &lt;property name="myServiceFactory" ref="myServiceFactory"/&gt;
* &lt;/bean&gt;
*
*&lt;/beans></pre>
*&lt;/beans&gt;</pre>
*
* <p>The attendant {@code MyClientBean} class implementation might then
* look something like this:
@@ -86,7 +86,7 @@ public abstract class YamlProcessor {
* </pre>
* when mapped with
* <pre class="code">
* setDocumentMatchers(properties ->
* setDocumentMatchers(properties -&gt;
* ("prod".equals(properties.getProperty("environment")) ? MatchStatus.FOUND : MatchStatus.NOT_FOUND));
* </pre>
* would end up as
@@ -75,18 +75,18 @@ import org.springframework.util.StringUtils;
*
* def reader = new GroovyBeanDefinitionReader(myApplicationContext)
* reader.beans {
* dataSource(BasicDataSource) { // <--- invokeMethod
* dataSource(BasicDataSource) { // &lt;--- invokeMethod
* driverClassName = "org.hsqldb.jdbcDriver"
* url = "jdbc:hsqldb:mem:grailsDB"
* username = "sa" // <-- setProperty
* username = "sa" // &lt;-- setProperty
* password = ""
* settings = [mynew:"setting"]
* }
* sessionFactory(SessionFactory) {
* dataSource = dataSource // <-- getProperty for retrieving references
* dataSource = dataSource // &lt;-- getProperty for retrieving references
* }
* myService(MyService) {
* nestedBean = { AnotherBean bean -> // <-- setProperty with closure for nested bean
* nestedBean = { AnotherBean bean -&gt; // &lt;-- setProperty with closure for nested bean
* dataSource = dataSource
* }
* }
@@ -113,7 +113,7 @@ import org.springframework.util.StringUtils;
* dataSource = dataSource
* }
* myService(MyService) {
* nestedBean = { AnotherBean bean ->
* nestedBean = { AnotherBean bean -&gt;
* dataSource = dataSource
* }
* }
@@ -489,9 +489,9 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
resolveConstructorArguments(args, 2, hasClosureArgument ? args.length - 1 : args.length);
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, (Class<?>) args[1], constructorArgs);
Map<?, ?> namedArgs = (Map<?, ?>) args[0];
for (Object key : namedArgs.keySet()) {
String propName = (String) key;
setProperty(propName, namedArgs.get(propName));
for (Map.Entry<?, ?> entity : namedArgs.entrySet()) {
String propName = (String) entity.getKey();
setProperty(propName, entity.getValue());
}
}
// factory method syntax
@@ -246,6 +246,15 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
this.allowCircularReferences = allowCircularReferences;
}
/**
* Return whether to allow circular references between beans.
* @since 5.3.10
* @see #setAllowCircularReferences
*/
public boolean isAllowCircularReferences() {
return this.allowCircularReferences;
}
/**
* Set whether to allow the raw injection of a bean instance into some other
* bean's property, despite the injected bean eventually getting wrapped
@@ -264,6 +273,15 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
this.allowRawInjectionDespiteWrapping = allowRawInjectionDespiteWrapping;
}
/**
* Return whether to allow the raw injection of a bean instance.
* @since 5.3.10
* @see #setAllowRawInjectionDespiteWrapping
*/
public boolean isAllowRawInjectionDespiteWrapping() {
return this.allowRawInjectionDespiteWrapping;
}
/**
* Ignore the given dependency type for autowiring:
* for example, String. Default is none.
@@ -1324,7 +1342,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param explicitArgs argument values passed in programmatically via the getBean method,
* or {@code null} if none (-> use constructor argument values from bean definition)
* or {@code null} if none (implying the use of constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
* @see #getBean(String, Object[])
*/
@@ -1345,7 +1363,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @param mbd the bean definition for the bean
* @param ctors the chosen candidate constructors
* @param explicitArgs argument values passed in programmatically via the getBean method,
* or {@code null} if none (-> use constructor argument values from bean definition)
* or {@code null} if none (implying the use of constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
*/
protected BeanWrapper autowireConstructor(
@@ -1241,7 +1241,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
@Override
public String toString() {
StringBuilder sb = new StringBuilder("class [");
sb.append(getBeanClassName()).append("]");
sb.append(getBeanClassName()).append(']');
sb.append("; scope=").append(this.scope);
sb.append("; abstract=").append(this.abstractFlag);
sb.append("; lazyInit=").append(this.lazyInit);
@@ -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.
@@ -361,7 +361,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
@@ -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.
@@ -21,6 +21,7 @@ import java.util.function.Supplier;
import org.springframework.beans.factory.config.AutowiredPropertyMarker;
import org.springframework.beans.factory.config.BeanDefinitionCustomizer;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
@@ -102,7 +103,7 @@ public final class BeanDefinitionBuilder {
* @param beanClass the {@code Class} of the bean that the definition is being created for
*/
public static BeanDefinitionBuilder rootBeanDefinition(Class<?> beanClass) {
return rootBeanDefinition(beanClass, null);
return rootBeanDefinition(beanClass, (String) null);
}
/**
@@ -117,6 +118,30 @@ public final class BeanDefinitionBuilder {
return builder;
}
/**
* Create a new {@code BeanDefinitionBuilder} used to construct a {@link RootBeanDefinition}.
* @param beanType the {@link ResolvableType type} of the bean that the definition is being created for
* @param instanceSupplier a callback for creating an instance of the bean
* @since 5.3.9
*/
public static <T> BeanDefinitionBuilder rootBeanDefinition(ResolvableType beanType, Supplier<T> instanceSupplier) {
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setTargetType(beanType);
beanDefinition.setInstanceSupplier(instanceSupplier);
return new BeanDefinitionBuilder(beanDefinition);
}
/**
* Create a new {@code BeanDefinitionBuilder} used to construct a {@link RootBeanDefinition}.
* @param beanClass the {@code Class} of the bean that the definition is being created for
* @param instanceSupplier a callback for creating an instance of the bean
* @since 5.3.9
* @see #rootBeanDefinition(ResolvableType, Supplier)
*/
public static <T> BeanDefinitionBuilder rootBeanDefinition(Class<T> beanClass, Supplier<T> instanceSupplier) {
return rootBeanDefinition(ResolvableType.forClass(beanClass), instanceSupplier);
}
/**
* Create a new {@code BeanDefinitionBuilder} used to construct a {@link ChildBeanDefinition}.
* @param parentName the name of the parent bean
@@ -331,6 +356,16 @@ public final class BeanDefinitionBuilder {
return this;
}
/**
* Set whether this bean is 'synthetic', that is, not defined by
* the application itself.
* @since 5.3.9
*/
public BeanDefinitionBuilder setSynthetic(boolean synthetic) {
this.beanDefinition.setSynthetic(synthetic);
return this;
}
/**
* Apply the given customizers to the underlying bean definition.
* @since 5.0
@@ -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.
@@ -277,12 +277,12 @@ class ConstructorResolver {
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"Could not resolve matching constructor on bean class [" + mbd.getBeanClassName() + "] " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"Ambiguous constructor matches found on bean class [" + mbd.getBeanClassName() + "] " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
@@ -608,7 +608,7 @@ class ConstructorResolver {
}
String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"No matching factory method found: " +
"No matching factory method found on class [" + factoryClass.getName() + "]: " +
(mbd.getFactoryBeanName() != null ?
"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
@@ -619,12 +619,12 @@ class ConstructorResolver {
}
else if (void.class == factoryMethodToUse.getReturnType()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid factory method '" + mbd.getFactoryMethodName() +
"': needs to have a non-void return type!");
"Invalid factory method '" + mbd.getFactoryMethodName() + "' on class [" +
factoryClass.getName() + "]: needs to have a non-void return type!");
}
else if (ambiguousFactoryMethods != null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous factory method matches found in bean '" + beanName + "' " +
"Ambiguous factory method matches found on class [" + factoryClass.getName() + "] " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousFactoryMethods);
}
@@ -61,6 +61,8 @@ import org.springframework.util.StringUtils;
@SuppressWarnings("serial")
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
private static final String DESTROY_METHOD_NAME = "destroy";
private static final String CLOSE_METHOD_NAME = "close";
private static final String SHUTDOWN_METHOD_NAME = "shutdown";
@@ -72,12 +74,11 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
private final String beanName;
private final boolean invokeDisposableBean;
private final boolean nonPublicAccessAllowed;
@Nullable
private final AccessControlContext acc;
private final boolean invokeDisposableBean;
private boolean invokeAutoCloseable;
@Nullable
private String destroyMethodName;
@@ -88,6 +89,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
@Nullable
private final List<DestructionAwareBeanPostProcessor> beanPostProcessors;
@Nullable
private final AccessControlContext acc;
/**
* Create a new DisposableBeanAdapter for the given bean.
@@ -103,38 +107,45 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean =
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
this.invokeDisposableBean = (bean instanceof DisposableBean &&
!beanDefinition.isExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
if (destroyMethodName != null &&
!(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
Method destroyMethod = determineDestroyMethod(destroyMethodName);
if (destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
else {
if (destroyMethod.getParameterCount() > 0) {
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
this.invokeAutoCloseable = (bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodName));
if (!this.invokeAutoCloseable) {
this.destroyMethodName = destroyMethodName;
Method destroyMethod = determineDestroyMethod(destroyMethodName);
if (destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
else {
if (destroyMethod.getParameterCount() > 0) {
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
}
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
}
this.destroyMethod = destroyMethod;
}
this.destroyMethod = destroyMethod;
}
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
this.acc = acc;
}
/**
@@ -149,26 +160,27 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = bean.getClass().getName();
this.invokeDisposableBean = (this.bean instanceof DisposableBean);
this.nonPublicAccessAllowed = true;
this.acc = acc;
this.invokeDisposableBean = (this.bean instanceof DisposableBean);
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
this.acc = acc;
}
/**
* Create a new DisposableBeanAdapter for the given bean.
*/
private DisposableBeanAdapter(Object bean, String beanName, boolean invokeDisposableBean,
boolean nonPublicAccessAllowed, @Nullable String destroyMethodName,
private DisposableBeanAdapter(Object bean, String beanName, boolean nonPublicAccessAllowed,
boolean invokeDisposableBean, boolean invokeAutoCloseable, @Nullable String destroyMethodName,
@Nullable List<DestructionAwareBeanPostProcessor> postProcessors) {
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean = invokeDisposableBean;
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
this.acc = null;
this.invokeDisposableBean = invokeDisposableBean;
this.invokeAutoCloseable = invokeAutoCloseable;
this.destroyMethodName = destroyMethodName;
this.beanPostProcessors = postProcessors;
this.acc = null;
}
@@ -211,7 +223,32 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
}
if (this.destroyMethod != null) {
if (this.invokeAutoCloseable) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking close() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((AutoCloseable) this.bean).close();
return null;
}, this.acc);
}
else {
((AutoCloseable) this.bean).close();
}
}
catch (Throwable ex) {
String msg = "Invocation of close method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
else if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
@@ -259,7 +296,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
args[0] = Boolean.TRUE;
}
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy method '" + this.destroyMethodName +
logger.trace("Invoking custom destroy method '" + this.destroyMethodName +
"' on bean with name '" + this.beanName + "'");
}
try {
@@ -282,7 +319,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
}
catch (InvocationTargetException ex) {
String msg = "Destroy method '" + this.destroyMethodName + "' on bean with name '" +
String msg = "Custom destroy method '" + this.destroyMethodName + "' on bean with name '" +
this.beanName + "' threw an exception";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex.getTargetException());
@@ -292,7 +329,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
}
catch (Throwable ex) {
logger.warn("Failed to invoke destroy method '" + this.destroyMethodName +
logger.warn("Failed to invoke custom destroy method '" + this.destroyMethodName +
"' on bean with name '" + this.beanName + "'", ex);
}
}
@@ -312,8 +349,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
}
}
return new DisposableBeanAdapter(this.bean, this.beanName, this.invokeDisposableBean,
this.nonPublicAccessAllowed, this.destroyMethodName, serializablePostProcessors);
return new DisposableBeanAdapter(
this.bean, this.beanName, this.nonPublicAccessAllowed, this.invokeDisposableBean,
this.invokeAutoCloseable, this.destroyMethodName, serializablePostProcessors);
}
@@ -323,10 +361,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
* @param beanDefinition the corresponding bean definition
*/
public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
if (bean instanceof DisposableBean || bean instanceof AutoCloseable) {
return true;
}
return inferDestroyMethodIfNecessary(bean, beanDefinition) != null;
return (bean instanceof DisposableBean || inferDestroyMethodIfNecessary(bean, beanDefinition) != null);
}
@@ -348,21 +383,27 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
String destroyMethodName = beanDefinition.resolvedDestroyMethodName;
if (destroyMethodName == null) {
destroyMethodName = beanDefinition.getDestroyMethodName();
boolean autoCloseable = (bean instanceof AutoCloseable);
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
(destroyMethodName == null && bean instanceof AutoCloseable)) {
// Only perform destroy method inference or Closeable detection
// in case of the bean not explicitly implementing DisposableBean
(destroyMethodName == null && autoCloseable)) {
// Only perform destroy method inference in case of the bean
// not explicitly implementing the DisposableBean interface
destroyMethodName = null;
if (!(bean instanceof DisposableBean)) {
try {
destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
if (autoCloseable) {
destroyMethodName = CLOSE_METHOD_NAME;
}
catch (NoSuchMethodException ex) {
else {
try {
destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex2) {
// no candidate destroy method found
catch (NoSuchMethodException ex) {
try {
destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex2) {
// no candidate destroy method found
}
}
}
}
@@ -21,7 +21,8 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Supplier;
@@ -422,15 +423,21 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
return this.factoryMethodToIntrospect;
}
/**
* Register an externally managed configuration method or field.
*/
public void registerExternallyManagedConfigMember(Member configMember) {
synchronized (this.postProcessingLock) {
if (this.externallyManagedConfigMembers == null) {
this.externallyManagedConfigMembers = new HashSet<>(1);
this.externallyManagedConfigMembers = new LinkedHashSet<>(1);
}
this.externallyManagedConfigMembers.add(configMember);
}
}
/**
* Check whether the given method or field is an externally managed configuration member.
*/
public boolean isExternallyManagedConfigMember(Member configMember) {
synchronized (this.postProcessingLock) {
return (this.externallyManagedConfigMembers != null &&
@@ -438,15 +445,33 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
}
/**
* Return all externally managed configuration methods and fields (as an immutable Set).
* @since 5.3.11
*/
public Set<Member> getExternallyManagedConfigMembers() {
synchronized (this.postProcessingLock) {
return (this.externallyManagedConfigMembers != null ?
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedConfigMembers)) :
Collections.emptySet());
}
}
/**
* Register an externally managed configuration initialization method.
*/
public void registerExternallyManagedInitMethod(String initMethod) {
synchronized (this.postProcessingLock) {
if (this.externallyManagedInitMethods == null) {
this.externallyManagedInitMethods = new HashSet<>(1);
this.externallyManagedInitMethods = new LinkedHashSet<>(1);
}
this.externallyManagedInitMethods.add(initMethod);
}
}
/**
* Check whether the given method name indicates an externally managed initialization method.
*/
public boolean isExternallyManagedInitMethod(String initMethod) {
synchronized (this.postProcessingLock) {
return (this.externallyManagedInitMethods != null &&
@@ -454,15 +479,33 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
}
/**
* Return all externally managed initialization methods (as an immutable Set).
* @since 5.3.11
*/
public Set<String> getExternallyManagedInitMethods() {
synchronized (this.postProcessingLock) {
return (this.externallyManagedInitMethods != null ?
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedInitMethods)) :
Collections.emptySet());
}
}
/**
* Register an externally managed configuration destruction method.
*/
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
synchronized (this.postProcessingLock) {
if (this.externallyManagedDestroyMethods == null) {
this.externallyManagedDestroyMethods = new HashSet<>(1);
this.externallyManagedDestroyMethods = new LinkedHashSet<>(1);
}
this.externallyManagedDestroyMethods.add(destroyMethod);
}
}
/**
* Check whether the given method name indicates an externally managed destruction method.
*/
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
synchronized (this.postProcessingLock) {
return (this.externallyManagedDestroyMethods != null &&
@@ -470,6 +513,18 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
}
/**
* Return all externally managed destruction methods (as an immutable Set).
* @since 5.3.11
*/
public Set<String> getExternallyManagedDestroyMethods() {
synchronized (this.postProcessingLock) {
return (this.externallyManagedDestroyMethods != null ?
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedDestroyMethods)) :
Collections.emptySet());
}
}
@Override
public RootBeanDefinition cloneBeanDefinition() {
@@ -39,7 +39,7 @@ import org.springframework.util.xml.XmlValidationModeDetector;
* when starting your JVM. For example, to use the Oracle {@link DocumentBuilder},
* you might start your application like as follows:
*
* <pre code="class">java -Djavax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory MyMainClass</pre>
* <pre class="code">java -Djavax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory MyMainClass</pre>
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -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.
@@ -64,24 +64,24 @@ public final class ParserContext {
}
public final XmlReaderContext getReaderContext() {
public XmlReaderContext getReaderContext() {
return this.readerContext;
}
public final BeanDefinitionRegistry getRegistry() {
public BeanDefinitionRegistry getRegistry() {
return this.readerContext.getRegistry();
}
public final BeanDefinitionParserDelegate getDelegate() {
public BeanDefinitionParserDelegate getDelegate() {
return this.delegate;
}
@Nullable
public final BeanDefinition getContainingBeanDefinition() {
public BeanDefinition getContainingBeanDefinition() {
return this.containingBeanDefinition;
}
public final boolean isNested() {
public boolean isNested() {
return (this.containingBeanDefinition != null);
}
@@ -71,13 +71,13 @@ public class PluggableSchemaResolver implements EntityResolver {
private final String schemaMappingsLocation;
/** Stores the mapping of schema URL -> local schema path. */
/** Stores the mapping of schema URL &rarr; local schema path. */
@Nullable
private volatile Map<String, String> schemaMappings;
/**
* Loads the schema URL -> schema file location mappings using the default
* Loads the schema URL &rarr; schema file location mappings using the default
* mapping file pattern "META-INF/spring.schemas".
* @param classLoader the ClassLoader to use for loading
* (can be {@code null}) to use the default ClassLoader)
@@ -89,7 +89,7 @@ public class PluggableSchemaResolver implements EntityResolver {
}
/**
* Loads the schema URL -> schema file location mappings using the given
* Loads the schema URL &rarr; schema file location mappings using the given
* mapping file pattern.
* @param classLoader the ClassLoader to use for loading
* (can be {@code null}) to use the default ClassLoader)
@@ -49,6 +49,7 @@ import org.springframework.lang.Nullable;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.SoftAssertions.assertSoftly;
/**
* Unit tests for {@link BeanUtils}.
@@ -85,19 +86,43 @@ class BeanUtilsTests {
}
@Test // gh-22531
void instantiateClassWithOptionalPrimitiveType() throws NoSuchMethodException {
Constructor<BeanWithPrimitiveTypes> ctor = BeanWithPrimitiveTypes.class.getDeclaredConstructor(int.class, boolean.class, String.class);
BeanWithPrimitiveTypes bean = BeanUtils.instantiateClass(ctor, null, null, "foo");
assertThat(bean.getCounter()).isEqualTo(0);
assertThat(bean.isFlag()).isEqualTo(false);
assertThat(bean.getValue()).isEqualTo("foo");
void instantiateClassWithFewerArgsThanParameters() throws NoSuchMethodException {
Constructor<BeanWithPrimitiveTypes> constructor = getBeanWithPrimitiveTypesConstructor();
assertThatExceptionOfType(BeanInstantiationException.class).isThrownBy(() ->
BeanUtils.instantiateClass(constructor, null, null, "foo"));
}
@Test // gh-22531
void instantiateClassWithMoreArgsThanParameters() throws NoSuchMethodException {
Constructor<BeanWithPrimitiveTypes> ctor = BeanWithPrimitiveTypes.class.getDeclaredConstructor(int.class, boolean.class, String.class);
Constructor<BeanWithPrimitiveTypes> constructor = getBeanWithPrimitiveTypesConstructor();
assertThatExceptionOfType(BeanInstantiationException.class).isThrownBy(() ->
BeanUtils.instantiateClass(ctor, null, null, "foo", null));
BeanUtils.instantiateClass(constructor, null, null, null, null, null, null, null, null, "foo", null));
}
@Test // gh-22531, gh-27390
void instantiateClassWithOptionalPrimitiveTypes() throws NoSuchMethodException {
Constructor<BeanWithPrimitiveTypes> constructor = getBeanWithPrimitiveTypesConstructor();
BeanWithPrimitiveTypes bean = BeanUtils.instantiateClass(constructor, null, null, null, null, null, null, null, null, "foo");
assertSoftly(softly -> {
softly.assertThat(bean.isFlag()).isFalse();
softly.assertThat(bean.getByteCount()).isEqualTo((byte) 0);
softly.assertThat(bean.getShortCount()).isEqualTo((short) 0);
softly.assertThat(bean.getIntCount()).isEqualTo(0);
softly.assertThat(bean.getLongCount()).isEqualTo(0L);
softly.assertThat(bean.getFloatCount()).isEqualTo(0F);
softly.assertThat(bean.getDoubleCount()).isEqualTo(0D);
softly.assertThat(bean.getCharacter()).isEqualTo('\0');
softly.assertThat(bean.getText()).isEqualTo("foo");
});
}
private Constructor<BeanWithPrimitiveTypes> getBeanWithPrimitiveTypesConstructor() throws NoSuchMethodException {
return BeanWithPrimitiveTypes.class.getConstructor(boolean.class, byte.class, short.class, int.class,
long.class, float.class, double.class, char.class, String.class);
}
@Test
@@ -628,30 +653,68 @@ class BeanUtilsTests {
private static class BeanWithPrimitiveTypes {
private int counter;
private boolean flag;
private byte byteCount;
private short shortCount;
private int intCount;
private long longCount;
private float floatCount;
private double doubleCount;
private char character;
private String text;
private String value;
@SuppressWarnings("unused")
public BeanWithPrimitiveTypes(int counter, boolean flag, String value) {
this.counter = counter;
this.flag = flag;
this.value = value;
}
public BeanWithPrimitiveTypes(boolean flag, byte byteCount, short shortCount, int intCount, long longCount,
float floatCount, double doubleCount, char character, String text) {
public int getCounter() {
return counter;
this.flag = flag;
this.byteCount = byteCount;
this.shortCount = shortCount;
this.intCount = intCount;
this.longCount = longCount;
this.floatCount = floatCount;
this.doubleCount = doubleCount;
this.character = character;
this.text = text;
}
public boolean isFlag() {
return flag;
}
public String getValue() {
return value;
public byte getByteCount() {
return byteCount;
}
public short getShortCount() {
return shortCount;
}
public int getIntCount() {
return intCount;
}
public long getLongCount() {
return longCount;
}
public float getFloatCount() {
return floatCount;
}
public double getDoubleCount() {
return doubleCount;
}
public char getCharacter() {
return character;
}
public String getText() {
return text;
}
}
private static class PrivateBeanWithPrivateConstructor {
@@ -38,7 +38,7 @@ public class BeanWrapperAutoGrowingTests {
@BeforeEach
public void setUp() {
public void setup() {
wrapper.setAutoGrowNestedPaths(true);
}
@@ -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.
@@ -16,7 +16,6 @@
package org.springframework.beans;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -46,10 +45,10 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* @author Chris Beams
* @since 18.01.2006
*/
public class BeanWrapperGenericsTests {
class BeanWrapperGenericsTests {
@Test
public void testGenericSet() {
void testGenericSet() {
GenericBean<?> gb = new GenericBean<>();
BeanWrapper bw = new BeanWrapperImpl(gb);
Set<String> input = new HashSet<>();
@@ -61,7 +60,7 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericLowerBoundedSet() {
void testGenericLowerBoundedSet() {
GenericBean<?> gb = new GenericBean<>();
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, true));
@@ -74,7 +73,7 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericSetWithConversionFailure() {
void testGenericSetWithConversionFailure() {
GenericBean<?> gb = new GenericBean<>();
BeanWrapper bw = new BeanWrapperImpl(gb);
Set<TestBean> input = new HashSet<>();
@@ -85,7 +84,7 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericList() throws MalformedURLException {
void testGenericList() throws Exception {
GenericBean<?> gb = new GenericBean<>();
BeanWrapper bw = new BeanWrapperImpl(gb);
List<String> input = new ArrayList<>();
@@ -97,7 +96,7 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericListElement() throws MalformedURLException {
void testGenericListElement() throws Exception {
GenericBean<?> gb = new GenericBean<>();
gb.setResourceList(new ArrayList<>());
BeanWrapper bw = new BeanWrapperImpl(gb);
@@ -106,29 +105,29 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericMap() {
void testGenericMap() {
GenericBean<?> gb = new GenericBean<>();
BeanWrapper bw = new BeanWrapperImpl(gb);
Map<String, String> input = new HashMap<>();
input.put("4", "5");
input.put("6", "7");
bw.setPropertyValue("shortMap", input);
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(new Short("6"))).isEqualTo(7);
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(Short.valueOf("6"))).isEqualTo(7);
}
@Test
public void testGenericMapElement() {
void testGenericMapElement() {
GenericBean<?> gb = new GenericBean<>();
gb.setShortMap(new HashMap<>());
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.setPropertyValue("shortMap[4]", "5");
assertThat(bw.getPropertyValue("shortMap[4]")).isEqualTo(5);
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
}
@Test
public void testGenericMapWithKeyType() {
void testGenericMapWithKeyType() {
GenericBean<?> gb = new GenericBean<>();
BeanWrapper bw = new BeanWrapperImpl(gb);
Map<String, String> input = new HashMap<>();
@@ -140,17 +139,17 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericMapElementWithKeyType() {
void testGenericMapElementWithKeyType() {
GenericBean<?> gb = new GenericBean<>();
gb.setLongMap(new HashMap<Long, Integer>());
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.setPropertyValue("longMap[4]", "5");
assertThat(gb.getLongMap().get(new Long("4"))).isEqualTo("5");
assertThat(gb.getLongMap().get(Long.valueOf("4"))).isEqualTo("5");
assertThat(bw.getPropertyValue("longMap[4]")).isEqualTo("5");
}
@Test
public void testGenericMapWithCollectionValue() {
void testGenericMapWithCollectionValue() {
GenericBean<?> gb = new GenericBean<>();
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.registerCustomEditor(Number.class, new CustomNumberEditor(Integer.class, false));
@@ -162,14 +161,12 @@ public class BeanWrapperGenericsTests {
value2.add(Boolean.TRUE);
input.put("2", value2);
bw.setPropertyValue("collectionMap", input);
boolean condition1 = gb.getCollectionMap().get(1) instanceof HashSet;
assertThat(condition1).isTrue();
boolean condition = gb.getCollectionMap().get(2) instanceof ArrayList;
assertThat(condition).isTrue();
assertThat(gb.getCollectionMap().get(1) instanceof HashSet).isTrue();
assertThat(gb.getCollectionMap().get(2) instanceof ArrayList).isTrue();
}
@Test
public void testGenericMapElementWithCollectionValue() {
void testGenericMapElementWithCollectionValue() {
GenericBean<?> gb = new GenericBean<>();
gb.setCollectionMap(new HashMap<>());
BeanWrapper bw = new BeanWrapperImpl(gb);
@@ -177,24 +174,23 @@ public class BeanWrapperGenericsTests {
HashSet<Integer> value1 = new HashSet<>();
value1.add(1);
bw.setPropertyValue("collectionMap[1]", value1);
boolean condition = gb.getCollectionMap().get(1) instanceof HashSet;
assertThat(condition).isTrue();
assertThat(gb.getCollectionMap().get(1) instanceof HashSet).isTrue();
}
@Test
public void testGenericMapFromProperties() {
void testGenericMapFromProperties() {
GenericBean<?> gb = new GenericBean<>();
BeanWrapper bw = new BeanWrapperImpl(gb);
Properties input = new Properties();
input.setProperty("4", "5");
input.setProperty("6", "7");
bw.setPropertyValue("shortMap", input);
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(new Short("6"))).isEqualTo(7);
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(Short.valueOf("6"))).isEqualTo(7);
}
@Test
public void testGenericListOfLists() throws MalformedURLException {
void testGenericListOfLists() {
GenericBean<String> gb = new GenericBean<>();
List<List<Integer>> list = new ArrayList<>();
list.add(new ArrayList<>());
@@ -206,7 +202,7 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericListOfListsWithElementConversion() throws MalformedURLException {
void testGenericListOfListsWithElementConversion() {
GenericBean<String> gb = new GenericBean<>();
List<List<Integer>> list = new ArrayList<>();
list.add(new ArrayList<>());
@@ -218,7 +214,7 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericListOfArrays() throws MalformedURLException {
void testGenericListOfArrays() {
GenericBean<String> gb = new GenericBean<>();
ArrayList<String[]> list = new ArrayList<>();
list.add(new String[] {"str1", "str2"});
@@ -230,7 +226,7 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericListOfArraysWithElementConversion() throws MalformedURLException {
void testGenericListOfArraysWithElementConversion() {
GenericBean<String> gb = new GenericBean<>();
ArrayList<String[]> list = new ArrayList<>();
list.add(new String[] {"str1", "str2"});
@@ -243,55 +239,55 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericListOfMaps() throws MalformedURLException {
void testGenericListOfMaps() {
GenericBean<String> gb = new GenericBean<>();
List<Map<Integer, Long>> list = new ArrayList<>();
list.add(new HashMap<>());
gb.setListOfMaps(list);
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.setPropertyValue("listOfMaps[0][10]", new Long(5));
assertThat(bw.getPropertyValue("listOfMaps[0][10]")).isEqualTo(new Long(5));
assertThat(gb.getListOfMaps().get(0).get(10)).isEqualTo(new Long(5));
bw.setPropertyValue("listOfMaps[0][10]", 5L);
assertThat(bw.getPropertyValue("listOfMaps[0][10]")).isEqualTo(5L);
assertThat(gb.getListOfMaps().get(0).get(10)).isEqualTo(Long.valueOf(5));
}
@Test
public void testGenericListOfMapsWithElementConversion() throws MalformedURLException {
void testGenericListOfMapsWithElementConversion() {
GenericBean<String> gb = new GenericBean<>();
List<Map<Integer, Long>> list = new ArrayList<>();
list.add(new HashMap<>());
gb.setListOfMaps(list);
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.setPropertyValue("listOfMaps[0][10]", "5");
assertThat(bw.getPropertyValue("listOfMaps[0][10]")).isEqualTo(new Long(5));
assertThat(gb.getListOfMaps().get(0).get(10)).isEqualTo(new Long(5));
assertThat(bw.getPropertyValue("listOfMaps[0][10]")).isEqualTo(5L);
assertThat(gb.getListOfMaps().get(0).get(10)).isEqualTo(Long.valueOf(5));
}
@Test
public void testGenericMapOfMaps() throws MalformedURLException {
void testGenericMapOfMaps() {
GenericBean<String> gb = new GenericBean<>();
Map<String, Map<Integer, Long>> map = new HashMap<>();
map.put("mykey", new HashMap<>());
gb.setMapOfMaps(map);
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.setPropertyValue("mapOfMaps[mykey][10]", new Long(5));
assertThat(bw.getPropertyValue("mapOfMaps[mykey][10]")).isEqualTo(new Long(5));
assertThat(gb.getMapOfMaps().get("mykey").get(10)).isEqualTo(new Long(5));
bw.setPropertyValue("mapOfMaps[mykey][10]", 5L);
assertThat(bw.getPropertyValue("mapOfMaps[mykey][10]")).isEqualTo(5L);
assertThat(gb.getMapOfMaps().get("mykey").get(10)).isEqualTo(Long.valueOf(5));
}
@Test
public void testGenericMapOfMapsWithElementConversion() throws MalformedURLException {
void testGenericMapOfMapsWithElementConversion() {
GenericBean<String> gb = new GenericBean<>();
Map<String, Map<Integer, Long>> map = new HashMap<>();
map.put("mykey", new HashMap<>());
gb.setMapOfMaps(map);
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.setPropertyValue("mapOfMaps[mykey][10]", "5");
assertThat(bw.getPropertyValue("mapOfMaps[mykey][10]")).isEqualTo(new Long(5));
assertThat(gb.getMapOfMaps().get("mykey").get(10)).isEqualTo(new Long(5));
assertThat(bw.getPropertyValue("mapOfMaps[mykey][10]")).isEqualTo(Long.valueOf(5));
assertThat(gb.getMapOfMaps().get("mykey").get(10)).isEqualTo(Long.valueOf(5));
}
@Test
public void testGenericMapOfLists() throws MalformedURLException {
void testGenericMapOfLists() {
GenericBean<String> gb = new GenericBean<>();
Map<Integer, List<Integer>> map = new HashMap<>();
map.put(1, new ArrayList<>());
@@ -303,7 +299,7 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericMapOfListsWithElementConversion() throws MalformedURLException {
void testGenericMapOfListsWithElementConversion() {
GenericBean<String> gb = new GenericBean<>();
Map<Integer, List<Integer>> map = new HashMap<>();
map.put(1, new ArrayList<>());
@@ -315,7 +311,7 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericTypeNestingMapOfInteger() throws Exception {
void testGenericTypeNestingMapOfInteger() {
Map<String, String> map = new HashMap<>();
map.put("testKey", "100");
@@ -324,14 +320,13 @@ public class BeanWrapperGenericsTests {
bw.setPropertyValue("mapOfInteger", map);
Object obj = gb.getMapOfInteger().get("testKey");
boolean condition = obj instanceof Integer;
assertThat(condition).isTrue();
assertThat(obj instanceof Integer).isTrue();
}
@Test
public void testGenericTypeNestingMapOfListOfInteger() throws Exception {
void testGenericTypeNestingMapOfListOfInteger() {
Map<String, List<String>> map = new HashMap<>();
List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
List<String> list = Arrays.asList("1", "2", "3");
map.put("testKey", list);
NestedGenericCollectionBean gb = new NestedGenericCollectionBean();
@@ -339,13 +334,12 @@ public class BeanWrapperGenericsTests {
bw.setPropertyValue("mapOfListOfInteger", map);
Object obj = gb.getMapOfListOfInteger().get("testKey").get(0);
boolean condition = obj instanceof Integer;
assertThat(condition).isTrue();
assertThat(obj instanceof Integer).isTrue();
assertThat(((Integer) obj).intValue()).isEqualTo(1);
}
@Test
public void testGenericTypeNestingListOfMapOfInteger() throws Exception {
void testGenericTypeNestingListOfMapOfInteger() {
List<Map<String, String>> list = new ArrayList<>();
Map<String, String> map = new HashMap<>();
map.put("testKey", "5");
@@ -356,15 +350,14 @@ public class BeanWrapperGenericsTests {
bw.setPropertyValue("listOfMapOfInteger", list);
Object obj = gb.getListOfMapOfInteger().get(0).get("testKey");
boolean condition = obj instanceof Integer;
assertThat(condition).isTrue();
assertThat(obj instanceof Integer).isTrue();
assertThat(((Integer) obj).intValue()).isEqualTo(5);
}
@Test
public void testGenericTypeNestingMapOfListOfListOfInteger() throws Exception {
void testGenericTypeNestingMapOfListOfListOfInteger() {
Map<String, List<List<String>>> map = new HashMap<>();
List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
List<String> list = Arrays.asList("1", "2", "3");
map.put("testKey", Collections.singletonList(list));
NestedGenericCollectionBean gb = new NestedGenericCollectionBean();
@@ -372,13 +365,12 @@ public class BeanWrapperGenericsTests {
bw.setPropertyValue("mapOfListOfListOfInteger", map);
Object obj = gb.getMapOfListOfListOfInteger().get("testKey").get(0).get(0);
boolean condition = obj instanceof Integer;
assertThat(condition).isTrue();
assertThat(obj instanceof Integer).isTrue();
assertThat(((Integer) obj).intValue()).isEqualTo(1);
}
@Test
public void testComplexGenericMap() {
void testComplexGenericMap() {
Map<List<String>, List<String>> inputMap = new HashMap<>();
List<String> inputKey = new ArrayList<>();
inputKey.add("1");
@@ -391,11 +383,11 @@ public class BeanWrapperGenericsTests {
bw.setPropertyValue("genericMap", inputMap);
assertThat(holder.getGenericMap().keySet().iterator().next().get(0)).isEqualTo(1);
assertThat(holder.getGenericMap().values().iterator().next().get(0)).isEqualTo(new Long(10));
assertThat(holder.getGenericMap().values().iterator().next().get(0)).isEqualTo(Long.valueOf(10));
}
@Test
public void testComplexGenericMapWithCollectionConversion() {
void testComplexGenericMapWithCollectionConversion() {
Map<Set<String>, Set<String>> inputMap = new HashMap<>();
Set<String> inputKey = new HashSet<>();
inputKey.add("1");
@@ -408,11 +400,11 @@ public class BeanWrapperGenericsTests {
bw.setPropertyValue("genericMap", inputMap);
assertThat(holder.getGenericMap().keySet().iterator().next().get(0)).isEqualTo(1);
assertThat(holder.getGenericMap().values().iterator().next().get(0)).isEqualTo(new Long(10));
assertThat(holder.getGenericMap().values().iterator().next().get(0)).isEqualTo(Long.valueOf(10));
}
@Test
public void testComplexGenericIndexedMapEntry() {
void testComplexGenericIndexedMapEntry() {
List<String> inputValue = new ArrayList<>();
inputValue.add("10");
@@ -421,11 +413,11 @@ public class BeanWrapperGenericsTests {
bw.setPropertyValue("genericIndexedMap[1]", inputValue);
assertThat(holder.getGenericIndexedMap().keySet().iterator().next()).isEqualTo(1);
assertThat(holder.getGenericIndexedMap().values().iterator().next().get(0)).isEqualTo(new Long(10));
assertThat(holder.getGenericIndexedMap().values().iterator().next().get(0)).isEqualTo(Long.valueOf(10));
}
@Test
public void testComplexGenericIndexedMapEntryWithCollectionConversion() {
void testComplexGenericIndexedMapEntryWithCollectionConversion() {
Set<String> inputValue = new HashSet<>();
inputValue.add("10");
@@ -434,11 +426,11 @@ public class BeanWrapperGenericsTests {
bw.setPropertyValue("genericIndexedMap[1]", inputValue);
assertThat(holder.getGenericIndexedMap().keySet().iterator().next()).isEqualTo(1);
assertThat(holder.getGenericIndexedMap().values().iterator().next().get(0)).isEqualTo(new Long(10));
assertThat(holder.getGenericIndexedMap().values().iterator().next().get(0)).isEqualTo(Long.valueOf(10));
}
@Test
public void testComplexDerivedIndexedMapEntry() {
void testComplexDerivedIndexedMapEntry() {
List<String> inputValue = new ArrayList<>();
inputValue.add("10");
@@ -447,11 +439,11 @@ public class BeanWrapperGenericsTests {
bw.setPropertyValue("derivedIndexedMap[1]", inputValue);
assertThat(holder.getDerivedIndexedMap().keySet().iterator().next()).isEqualTo(1);
assertThat(holder.getDerivedIndexedMap().values().iterator().next().get(0)).isEqualTo(new Long(10));
assertThat(holder.getDerivedIndexedMap().values().iterator().next().get(0)).isEqualTo(Long.valueOf(10));
}
@Test
public void testComplexDerivedIndexedMapEntryWithCollectionConversion() {
void testComplexDerivedIndexedMapEntryWithCollectionConversion() {
Set<String> inputValue = new HashSet<>();
inputValue.add("10");
@@ -460,11 +452,11 @@ public class BeanWrapperGenericsTests {
bw.setPropertyValue("derivedIndexedMap[1]", inputValue);
assertThat(holder.getDerivedIndexedMap().keySet().iterator().next()).isEqualTo(1);
assertThat(holder.getDerivedIndexedMap().values().iterator().next().get(0)).isEqualTo(new Long(10));
assertThat(holder.getDerivedIndexedMap().values().iterator().next().get(0)).isEqualTo(Long.valueOf(10));
}
@Test
public void testGenericallyTypedIntegerBean() throws Exception {
void testGenericallyTypedIntegerBean() {
GenericIntegerBean gb = new GenericIntegerBean();
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.setPropertyValue("genericProperty", "10");
@@ -475,7 +467,7 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testGenericallyTypedSetOfIntegerBean() throws Exception {
void testGenericallyTypedSetOfIntegerBean() {
GenericSetOfIntegerBean gb = new GenericSetOfIntegerBean();
BeanWrapper bw = new BeanWrapperImpl(gb);
bw.setPropertyValue("genericProperty", "10");
@@ -486,23 +478,23 @@ public class BeanWrapperGenericsTests {
}
@Test
public void testSettingGenericPropertyWithReadOnlyInterface() {
void testSettingGenericPropertyWithReadOnlyInterface() {
Bar bar = new Bar();
BeanWrapper bw = new BeanWrapperImpl(bar);
bw.setPropertyValue("version", "10");
assertThat(bar.getVersion()).isEqualTo(new Double(10.0));
assertThat(bar.getVersion()).isEqualTo(Double.valueOf(10.0));
}
@Test
public void testSettingLongPropertyWithGenericInterface() {
void testSettingLongPropertyWithGenericInterface() {
Promotion bean = new Promotion();
BeanWrapper bw = new BeanWrapperImpl(bean);
bw.setPropertyValue("id", "10");
assertThat(bean.getId()).isEqualTo(new Long(10));
assertThat(bean.getId()).isEqualTo(Long.valueOf(10));
}
@Test
public void testUntypedPropertyWithMapAtRuntime() {
void testUntypedPropertyWithMapAtRuntime() {
class Holder<D> {
private final D data;
public Holder(D data) {
@@ -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.
@@ -26,6 +26,7 @@ import org.springframework.beans.testfixture.beans.TestBean;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNoException;
/**
* Specific {@link BeanWrapperImpl} tests.
@@ -37,7 +38,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* @author Chris Beams
* @author Dave Syer
*/
public class BeanWrapperTests extends AbstractPropertyAccessorTests {
class BeanWrapperTests extends AbstractPropertyAccessorTests {
@Override
protected BeanWrapperImpl createAccessor(Object target) {
@@ -46,7 +47,7 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
@Test
public void setterDoesNotCallGetter() {
void setterDoesNotCallGetter() {
GetterBean target = new GetterBean();
BeanWrapper accessor = createAccessor(target);
accessor.setPropertyValue("name", "tom");
@@ -55,7 +56,7 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
}
@Test
public void getterSilentlyFailWithOldValueExtraction() {
void getterSilentlyFailWithOldValueExtraction() {
GetterBean target = new GetterBean();
BeanWrapper accessor = createAccessor(target);
accessor.setExtractOldValueForEditor(true); // This will call the getter
@@ -65,7 +66,7 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
}
@Test
public void aliasedSetterThroughDefaultMethod() {
void aliasedSetterThroughDefaultMethod() {
GetterBean target = new GetterBean();
BeanWrapper accessor = createAccessor(target);
accessor.setPropertyValue("aliasedName", "tom");
@@ -74,7 +75,7 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
}
@Test
public void setValidAndInvalidPropertyValuesShouldContainExceptionDetails() {
void setValidAndInvalidPropertyValuesShouldContainExceptionDetails() {
TestBean target = new TestBean();
String newName = "tony";
String invalidTouchy = ".valid";
@@ -91,12 +92,12 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
.getNewValue()).isEqualTo(invalidTouchy);
});
// Test validly set property matches
assertThat(target.getName().equals(newName)).as("Valid set property must stick").isTrue();
assertThat(target.getAge() == 0).as("Invalid set property must retain old value").isTrue();
assertThat(target.getName()).as("Valid set property must stick").isEqualTo(newName);
assertThat(target.getAge()).as("Invalid set property must retain old value").isEqualTo(0);
}
@Test
public void checkNotWritablePropertyHoldPossibleMatches() {
void checkNotWritablePropertyHoldPossibleMatches() {
TestBean target = new TestBean();
BeanWrapper accessor = createAccessor(target);
assertThatExceptionOfType(NotWritablePropertyException.class).isThrownBy(() ->
@@ -105,15 +106,15 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
}
@Test // Can't be shared; there is no such thing as a read-only field
public void setReadOnlyMapProperty() {
void setReadOnlyMapProperty() {
TypedReadOnlyMap map = new TypedReadOnlyMap(Collections.singletonMap("key", new TestBean()));
TypedReadOnlyMapClient target = new TypedReadOnlyMapClient();
BeanWrapper accessor = createAccessor(target);
accessor.setPropertyValue("map", map);
assertThatNoException().isThrownBy(() -> accessor.setPropertyValue("map", map));
}
@Test
public void notWritablePropertyExceptionContainsAlternativeMatch() {
void notWritablePropertyExceptionContainsAlternativeMatch() {
IntelliBean target = new IntelliBean();
BeanWrapper bw = createAccessor(target);
try {
@@ -121,12 +122,12 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
}
catch (NotWritablePropertyException ex) {
assertThat(ex.getPossibleMatches()).as("Possible matches not determined").isNotNull();
assertThat(ex.getPossibleMatches().length).as("Invalid amount of alternatives").isEqualTo(1);
assertThat(ex.getPossibleMatches()).as("Invalid amount of alternatives").hasSize(1);
}
}
@Test
public void notWritablePropertyExceptionContainsAlternativeMatches() {
void notWritablePropertyExceptionContainsAlternativeMatches() {
IntelliBean target = new IntelliBean();
BeanWrapper bw = createAccessor(target);
try {
@@ -134,23 +135,23 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
}
catch (NotWritablePropertyException ex) {
assertThat(ex.getPossibleMatches()).as("Possible matches not determined").isNotNull();
assertThat(ex.getPossibleMatches().length).as("Invalid amount of alternatives").isEqualTo(3);
assertThat(ex.getPossibleMatches()).as("Invalid amount of alternatives").hasSize(3);
}
}
@Override
@Test // Can't be shared: no type mismatch with a field
public void setPropertyTypeMismatch() {
void setPropertyTypeMismatch() {
PropertyTypeMismatch target = new PropertyTypeMismatch();
BeanWrapper accessor = createAccessor(target);
accessor.setPropertyValue("object", "a String");
assertThat(target.value).isEqualTo("a String");
assertThat(target.getObject() == 8).isTrue();
assertThat(target.getObject()).isEqualTo(8);
assertThat(accessor.getPropertyValue("object")).isEqualTo(8);
}
@Test
public void propertyDescriptors() {
void propertyDescriptors() {
TestBean target = new TestBean();
target.setSpouse(new TestBean());
BeanWrapper accessor = createAccessor(target);
@@ -166,7 +167,7 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
@Test
@SuppressWarnings("unchecked")
public void getPropertyWithOptional() {
void getPropertyWithOptional() {
GetterWithOptional target = new GetterWithOptional();
TestBean tb = new TestBean("x");
BeanWrapper accessor = createAccessor(target);
@@ -189,7 +190,7 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
}
@Test
public void getPropertyWithOptionalAndAutoGrow() {
void getPropertyWithOptionalAndAutoGrow() {
GetterWithOptional target = new GetterWithOptional();
BeanWrapper accessor = createAccessor(target);
accessor.setAutoGrowNestedPaths(true);
@@ -201,7 +202,7 @@ public class BeanWrapperTests extends AbstractPropertyAccessorTests {
}
@Test
public void incompletelyQuotedKeyLeadsToPropertyException() {
void incompletelyQuotedKeyLeadsToPropertyException() {
TestBean target = new TestBean();
BeanWrapper accessor = createAccessor(target);
assertThatExceptionOfType(NotWritablePropertyException.class).isThrownBy(() ->
@@ -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.
@@ -29,7 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Chris Beams
* @author Stephane Nicoll
*/
public class DirectFieldAccessorTests extends AbstractPropertyAccessorTests {
class DirectFieldAccessorTests extends AbstractPropertyAccessorTests {
@Override
protected DirectFieldAccessor createAccessor(Object target) {
@@ -38,7 +38,7 @@ public class DirectFieldAccessorTests extends AbstractPropertyAccessorTests {
@Test
public void withShadowedField() {
void withShadowedField() {
final StringBuilder sb = new StringBuilder();
TestBean target = new TestBean() {
@@ -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.
@@ -182,9 +182,9 @@ class DefaultListableBeanFactoryTests {
assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames.length).isEqualTo(0);
assertThat(beanNames).hasSize(0);
beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
assertThat(beanNames.length).isEqualTo(0);
assertThat(beanNames).hasSize(0);
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
@@ -216,9 +216,9 @@ class DefaultListableBeanFactoryTests {
assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames.length).isEqualTo(0);
assertThat(beanNames).hasSize(0);
beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
assertThat(beanNames.length).isEqualTo(0);
assertThat(beanNames).hasSize(0);
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
@@ -249,9 +249,9 @@ class DefaultListableBeanFactoryTests {
assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames.length).isEqualTo(0);
assertThat(beanNames).hasSize(0);
beanNames = lbf.getBeanNamesForAnnotation(SuppressWarnings.class);
assertThat(beanNames.length).isEqualTo(0);
assertThat(beanNames).hasSize(0);
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
@@ -283,7 +283,7 @@ class DefaultListableBeanFactoryTests {
assertThat(!DummyFactory.wasPrototypeCreated()).as("prototype not instantiated").isTrue();
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertThat(lbf.containsSingleton("x1")).isTrue();
assertThat(lbf.containsBean("x1")).isTrue();
@@ -337,7 +337,7 @@ class DefaultListableBeanFactoryTests {
TestBeanFactory.initialized = false;
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
@@ -349,7 +349,7 @@ class DefaultListableBeanFactoryTests {
assertThat(lbf.isTypeMatch("x1", TestBean.class)).isTrue();
assertThat(lbf.isTypeMatch("&x1", TestBean.class)).isFalse();
assertThat(lbf.getType("x1")).isEqualTo(TestBean.class);
assertThat(lbf.getType("&x1")).isEqualTo(null);
assertThat(lbf.getType("&x1")).isNull();
assertThat(TestBeanFactory.initialized).isFalse();
}
@@ -362,7 +362,7 @@ class DefaultListableBeanFactoryTests {
TestBeanFactory.initialized = false;
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
@@ -374,7 +374,7 @@ class DefaultListableBeanFactoryTests {
assertThat(lbf.isTypeMatch("x1", TestBean.class)).isTrue();
assertThat(lbf.isTypeMatch("&x1", TestBean.class)).isFalse();
assertThat(lbf.getType("x1")).isEqualTo(TestBean.class);
assertThat(lbf.getType("&x1")).isEqualTo(null);
assertThat(lbf.getType("&x1")).isNull();
assertThat(TestBeanFactory.initialized).isFalse();
}
@@ -389,7 +389,7 @@ class DefaultListableBeanFactoryTests {
TestBeanFactory.initialized = false;
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
@@ -401,7 +401,7 @@ class DefaultListableBeanFactoryTests {
assertThat(lbf.isTypeMatch("x1", TestBean.class)).isTrue();
assertThat(lbf.isTypeMatch("&x1", TestBean.class)).isFalse();
assertThat(lbf.getType("x1")).isEqualTo(TestBean.class);
assertThat(lbf.getType("&x1")).isEqualTo(null);
assertThat(lbf.getType("&x1")).isNull();
assertThat(TestBeanFactory.initialized).isFalse();
}
@@ -417,7 +417,7 @@ class DefaultListableBeanFactoryTests {
TestBeanFactory.initialized = false;
String[] beanNames = lbf.getBeanNamesForType(TestBean.class, true, false);
assertThat(beanNames.length).isEqualTo(1);
assertThat(beanNames).hasSize(1);
assertThat(beanNames[0]).isEqualTo("x1");
assertThat(lbf.containsSingleton("x1")).isFalse();
assertThat(lbf.containsBean("x1")).isTrue();
@@ -450,7 +450,7 @@ class DefaultListableBeanFactoryTests {
assertThat(lbf.isTypeMatch("x2", Object.class)).isTrue();
assertThat(lbf.isTypeMatch("&x2", Object.class)).isFalse();
assertThat(lbf.getType("x2")).isEqualTo(TestBean.class);
assertThat(lbf.getType("&x2")).isEqualTo(null);
assertThat(lbf.getType("&x2")).isNull();
assertThat(lbf.getAliases("x1").length).isEqualTo(1);
assertThat(lbf.getAliases("x1")[0]).isEqualTo("x2");
assertThat(lbf.getAliases("&x1").length).isEqualTo(1);
@@ -3030,7 +3030,7 @@ class DefaultListableBeanFactoryTests {
public Object convertIfNecessary(Object value, @Nullable Class requiredType) {
if (value instanceof String && Float.class.isAssignableFrom(requiredType)) {
try {
return new Float(this.numberFormat.parse((String) value).floatValue());
return this.numberFormat.parse((String) value).floatValue();
}
catch (ParseException ex) {
throw new TypeMismatchException(value, requiredType, ex);
@@ -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.
@@ -31,6 +31,7 @@ import static org.springframework.beans.factory.support.BeanDefinitionBuilder.ro
* invoking a factory method is not instructive to the user and rather misleading.
*
* @author Chris Beams
* @author Juergen Hoeller
*/
public class Spr5475Tests {
@@ -40,7 +41,8 @@ public class Spr5475Tests {
rootBeanDefinition(Foo.class)
.setFactoryMethod("noArgFactory")
.addConstructorArgValue("bogusArg").getBeanDefinition(),
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(String)'. " +
"Error creating bean with name 'foo': No matching factory method found on class " +
"[org.springframework.beans.factory.Spr5475Tests$Foo]: factory method 'noArgFactory(String)'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
@@ -51,7 +53,8 @@ public class Spr5475Tests {
.setFactoryMethod("noArgFactory")
.addConstructorArgValue("bogusArg1")
.addConstructorArgValue("bogusArg2".getBytes()).getBeanDefinition(),
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(String,byte[])'. " +
"Error creating bean with name 'foo': No matching factory method found on class " +
"[org.springframework.beans.factory.Spr5475Tests$Foo]: factory method 'noArgFactory(String,byte[])'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
@@ -65,7 +68,8 @@ public class Spr5475Tests {
def.setConstructorArgumentValues(cav);
assertExceptionMessageForMisconfiguredFactoryMethod(def,
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(CharSequence,byte[])'. " +
"Error creating bean with name 'foo': No matching factory method found on class " +
"[org.springframework.beans.factory.Spr5475Tests$Foo]: factory method 'noArgFactory(CharSequence,byte[])'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
@@ -17,22 +17,25 @@
package org.springframework.beans.factory.support;
import java.util.Arrays;
import java.util.function.Function;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.core.ResolvableType;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Rod Johnson
* @author Juergen Hoeller
* @author Stephane Nicoll
*/
public class BeanDefinitionBuilderTests {
class BeanDefinitionBuilderTests {
@Test
public void beanClassWithSimpleProperty() {
void builderWithBeanClassWithSimpleProperty() {
String[] dependsOn = new String[] { "A", "B", "C" };
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class);
bdb.setScope(BeanDefinition.SCOPE_PROTOTYPE);
@@ -49,7 +52,7 @@ public class BeanDefinitionBuilderTests {
}
@Test
public void beanClassWithFactoryMethod() {
void builderWithBeanClassAndFactoryMethod() {
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class, "create");
RootBeanDefinition rbd = (RootBeanDefinition) bdb.getBeanDefinition();
assertThat(rbd.hasBeanClass()).isTrue();
@@ -58,7 +61,7 @@ public class BeanDefinitionBuilderTests {
}
@Test
public void beanClassName() {
void builderWithBeanClassName() {
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class.getName());
RootBeanDefinition rbd = (RootBeanDefinition) bdb.getBeanDefinition();
assertThat(rbd.hasBeanClass()).isFalse();
@@ -66,7 +69,7 @@ public class BeanDefinitionBuilderTests {
}
@Test
public void beanClassNameWithFactoryMethod() {
void builderWithBeanClassNameAndFactoryMethod() {
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class.getName(), "create");
RootBeanDefinition rbd = (RootBeanDefinition) bdb.getBeanDefinition();
assertThat(rbd.hasBeanClass()).isFalse();
@@ -74,4 +77,78 @@ public class BeanDefinitionBuilderTests {
assertThat(rbd.getFactoryMethodName()).isEqualTo("create");
}
@Test
void builderWithResolvableTypeAndInstanceSupplier() {
ResolvableType type = ResolvableType.forClassWithGenerics(Function.class, Integer.class, String.class);
Function<Integer, String> function = i -> "value " + i;
RootBeanDefinition rbd = (RootBeanDefinition) BeanDefinitionBuilder
.rootBeanDefinition(type, () -> function).getBeanDefinition();
assertThat(rbd.getResolvableType()).isEqualTo(type);
assertThat(rbd.getInstanceSupplier()).isNotNull();
assertThat(rbd.getInstanceSupplier().get()).isInstanceOf(Function.class);
}
@Test
void builderWithBeanClassAndInstanceSupplier() {
RootBeanDefinition rbd = (RootBeanDefinition) BeanDefinitionBuilder
.rootBeanDefinition(String.class, () -> "test").getBeanDefinition();
assertThat(rbd.getResolvableType().resolve()).isEqualTo(String.class);
assertThat(rbd.getInstanceSupplier()).isNotNull();
assertThat(rbd.getInstanceSupplier().get()).isEqualTo("test");
}
@Test
void builderWithAutowireMode() {
assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE).getBeanDefinition().getAutowireMode())
.isEqualTo(RootBeanDefinition.AUTOWIRE_BY_TYPE);
}
@Test
void builderWithDependencyCheck() {
assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
.setDependencyCheck(RootBeanDefinition.DEPENDENCY_CHECK_ALL)
.getBeanDefinition().getDependencyCheck())
.isEqualTo(RootBeanDefinition.DEPENDENCY_CHECK_ALL);
}
@Test
void builderWithDependsOn() {
assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class).addDependsOn("test")
.addDependsOn("test2").getBeanDefinition().getDependsOn())
.containsExactly("test", "test2");
}
@Test
void builderWithPrimary() {
assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
.setPrimary(true).getBeanDefinition().isPrimary()).isTrue();
}
@Test
void builderWithRole() {
assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE).getBeanDefinition().getRole())
.isEqualTo(BeanDefinition.ROLE_INFRASTRUCTURE);
}
@Test
void builderWithSynthetic() {
assertThat(BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
.setSynthetic(true).getBeanDefinition().isSynthetic()).isTrue();
}
@Test
void builderWithCustomizers() {
BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class)
.applyCustomizers(builder -> {
builder.setFactoryMethodName("create");
builder.setRole(BeanDefinition.ROLE_SUPPORT);
})
.applyCustomizers(builder -> builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE))
.getBeanDefinition();
assertThat(beanDefinition.getFactoryMethodName()).isEqualTo("create");
assertThat(beanDefinition.getRole()).isEqualTo(BeanDefinition.ROLE_INFRASTRUCTURE);
}
}
@@ -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.
@@ -64,10 +64,10 @@ import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
* @author Sam Brannen
* @since 20.01.2006
*/
public class BeanFactoryGenericsTests {
class BeanFactoryGenericsTests {
@Test
public void testGenericSetProperty() {
void testGenericSetProperty() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
@@ -84,7 +84,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericListProperty() throws Exception {
void testGenericListProperty() throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
@@ -101,7 +101,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericListPropertyWithAutowiring() throws Exception {
void testGenericListPropertyWithAutowiring() throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerSingleton("resource1", new UrlResource("http://localhost:8080"));
bf.registerSingleton("resource2", new UrlResource("http://localhost:9090"));
@@ -116,7 +116,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericListPropertyWithInvalidElementType() {
void testGenericListPropertyWithInvalidElementType() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericIntegerBean.class);
@@ -134,7 +134,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericListPropertyWithOptionalAutowiring() {
void testGenericListPropertyWithOptionalAutowiring() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
@@ -146,7 +146,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericMapProperty() {
void testGenericMapProperty() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
@@ -158,12 +158,12 @@ public class BeanFactoryGenericsTests {
bf.registerBeanDefinition("genericBean", rbd);
GenericBean<?> gb = (GenericBean<?>) bf.getBean("genericBean");
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(new Short("6"))).isEqualTo(7);
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(Short.valueOf("6"))).isEqualTo(7);
}
@Test
public void testGenericListOfArraysProperty() {
void testGenericListOfArraysProperty() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("genericBeanTests.xml", getClass()));
@@ -171,14 +171,14 @@ public class BeanFactoryGenericsTests {
assertThat(gb.getListOfArrays().size()).isEqualTo(1);
String[] array = gb.getListOfArrays().get(0);
assertThat(array.length).isEqualTo(2);
assertThat(array).hasSize(2);
assertThat(array[0]).isEqualTo("value1");
assertThat(array[1]).isEqualTo("value2");
}
@Test
public void testGenericSetConstructor() {
void testGenericSetConstructor() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
@@ -195,7 +195,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericSetConstructorWithAutowiring() {
void testGenericSetConstructorWithAutowiring() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerSingleton("integer1", 4);
bf.registerSingleton("integer2", 5);
@@ -210,7 +210,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericSetConstructorWithOptionalAutowiring() {
void testGenericSetConstructorWithOptionalAutowiring() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
@@ -222,7 +222,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericSetListConstructor() throws Exception {
void testGenericSetListConstructor() throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
@@ -245,7 +245,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericSetListConstructorWithAutowiring() throws Exception {
void testGenericSetListConstructorWithAutowiring() throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerSingleton("integer1", 4);
bf.registerSingleton("integer2", 5);
@@ -264,7 +264,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericSetListConstructorWithOptionalAutowiring() throws Exception {
void testGenericSetListConstructorWithOptionalAutowiring() throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerSingleton("resource1", new UrlResource("http://localhost:8080"));
bf.registerSingleton("resource2", new UrlResource("http://localhost:9090"));
@@ -279,7 +279,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericSetMapConstructor() {
void testGenericSetMapConstructor() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
@@ -297,12 +297,12 @@ public class BeanFactoryGenericsTests {
assertThat(gb.getIntegerSet().contains(4)).isTrue();
assertThat(gb.getIntegerSet().contains(5)).isTrue();
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(new Short("6"))).isEqualTo(7);
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(Short.valueOf("6"))).isEqualTo(7);
}
@Test
public void testGenericMapResourceConstructor() throws Exception {
void testGenericMapResourceConstructor() throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
@@ -315,13 +315,13 @@ public class BeanFactoryGenericsTests {
bf.registerBeanDefinition("genericBean", rbd);
GenericBean<?> gb = (GenericBean<?>) bf.getBean("genericBean");
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(new Short("6"))).isEqualTo(7);
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(Short.valueOf("6"))).isEqualTo(7);
assertThat(gb.getResourceList().get(0)).isEqualTo(new UrlResource("http://localhost:8080"));
}
@Test
public void testGenericMapMapConstructor() {
void testGenericMapMapConstructor() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
@@ -338,16 +338,16 @@ public class BeanFactoryGenericsTests {
GenericBean<?> gb = (GenericBean<?>) bf.getBean("genericBean");
assertThat(gb.getShortMap()).isNotSameAs(gb.getPlainMap());
assertThat(gb.getPlainMap().size()).isEqualTo(2);
assertThat(gb.getPlainMap()).hasSize(2);
assertThat(gb.getPlainMap().get("1")).isEqualTo("0");
assertThat(gb.getPlainMap().get("2")).isEqualTo("3");
assertThat(gb.getShortMap().size()).isEqualTo(2);
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(new Short("6"))).isEqualTo(7);
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(Short.valueOf("6"))).isEqualTo(7);
}
@Test
public void testGenericMapMapConstructorWithSameRefAndConversion() {
void testGenericMapMapConstructorWithSameRefAndConversion() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
@@ -361,22 +361,22 @@ public class BeanFactoryGenericsTests {
GenericBean<?> gb = (GenericBean<?>) bf.getBean("genericBean");
assertThat(gb.getShortMap()).isNotSameAs(gb.getPlainMap());
assertThat(gb.getPlainMap().size()).isEqualTo(2);
assertThat(gb.getPlainMap()).hasSize(2);
assertThat(gb.getPlainMap().get("1")).isEqualTo("0");
assertThat(gb.getPlainMap().get("2")).isEqualTo("3");
assertThat(gb.getShortMap().size()).isEqualTo(2);
assertThat(gb.getShortMap().get(new Short("1"))).isEqualTo(0);
assertThat(gb.getShortMap().get(new Short("2"))).isEqualTo(3);
assertThat(gb.getShortMap().get(Short.valueOf("1"))).isEqualTo(0);
assertThat(gb.getShortMap().get(Short.valueOf("2"))).isEqualTo(3);
}
@Test
public void testGenericMapMapConstructorWithSameRefAndNoConversion() {
void testGenericMapMapConstructorWithSameRefAndNoConversion() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
Map<Short, Integer> input = new HashMap<>();
input.put(new Short((short) 1), 0);
input.put(new Short((short) 2), 3);
input.put((short) 1, 0);
input.put((short) 2, 3);
rbd.getConstructorArgumentValues().addGenericArgumentValue(input);
rbd.getConstructorArgumentValues().addGenericArgumentValue(input);
@@ -384,13 +384,13 @@ public class BeanFactoryGenericsTests {
GenericBean<?> gb = (GenericBean<?>) bf.getBean("genericBean");
assertThat(gb.getShortMap()).isSameAs(gb.getPlainMap());
assertThat(gb.getShortMap().size()).isEqualTo(2);
assertThat(gb.getShortMap().get(new Short("1"))).isEqualTo(0);
assertThat(gb.getShortMap().get(new Short("2"))).isEqualTo(3);
assertThat(gb.getShortMap()).hasSize(2);
assertThat(gb.getShortMap().get(Short.valueOf("1"))).isEqualTo(0);
assertThat(gb.getShortMap().get(Short.valueOf("2"))).isEqualTo(3);
}
@Test
public void testGenericMapWithKeyTypeConstructor() {
void testGenericMapWithKeyTypeConstructor() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
@@ -407,7 +407,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericMapWithCollectionValueConstructor() {
void testGenericMapWithCollectionValueConstructor() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
@Override
@@ -438,7 +438,7 @@ public class BeanFactoryGenericsTests {
@Test
public void testGenericSetFactoryMethod() {
void testGenericSetFactoryMethod() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
rbd.setFactoryMethodName("createInstance");
@@ -456,7 +456,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericSetListFactoryMethod() throws Exception {
void testGenericSetListFactoryMethod() throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
rbd.setFactoryMethodName("createInstance");
@@ -480,7 +480,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericSetMapFactoryMethod() {
void testGenericSetMapFactoryMethod() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
rbd.setFactoryMethodName("createInstance");
@@ -499,12 +499,12 @@ public class BeanFactoryGenericsTests {
assertThat(gb.getIntegerSet().contains(4)).isTrue();
assertThat(gb.getIntegerSet().contains(5)).isTrue();
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(new Short("6"))).isEqualTo(7);
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(Short.valueOf("6"))).isEqualTo(7);
}
@Test
public void testGenericMapResourceFactoryMethod() throws Exception {
void testGenericMapResourceFactoryMethod() throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
rbd.setFactoryMethodName("createInstance");
@@ -518,13 +518,13 @@ public class BeanFactoryGenericsTests {
bf.registerBeanDefinition("genericBean", rbd);
GenericBean<?> gb = (GenericBean<?>) bf.getBean("genericBean");
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(new Short("6"))).isEqualTo(7);
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(Short.valueOf("6"))).isEqualTo(7);
assertThat(gb.getResourceList().get(0)).isEqualTo(new UrlResource("http://localhost:8080"));
}
@Test
public void testGenericMapMapFactoryMethod() {
void testGenericMapMapFactoryMethod() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
rbd.setFactoryMethodName("createInstance");
@@ -543,12 +543,12 @@ public class BeanFactoryGenericsTests {
assertThat(gb.getPlainMap().get("1")).isEqualTo("0");
assertThat(gb.getPlainMap().get("2")).isEqualTo("3");
assertThat(gb.getShortMap().get(new Short("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(new Short("6"))).isEqualTo(7);
assertThat(gb.getShortMap().get(Short.valueOf("4"))).isEqualTo(5);
assertThat(gb.getShortMap().get(Short.valueOf("6"))).isEqualTo(7);
}
@Test
public void testGenericMapWithKeyTypeFactoryMethod() {
void testGenericMapWithKeyTypeFactoryMethod() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(GenericBean.class);
rbd.setFactoryMethodName("createInstance");
@@ -561,12 +561,12 @@ public class BeanFactoryGenericsTests {
bf.registerBeanDefinition("genericBean", rbd);
GenericBean<?> gb = (GenericBean<?>) bf.getBean("genericBean");
assertThat(gb.getLongMap().get(new Long("4"))).isEqualTo("5");
assertThat(gb.getLongMap().get(new Long("6"))).isEqualTo("7");
assertThat(gb.getLongMap().get(Long.valueOf("4"))).isEqualTo("5");
assertThat(gb.getLongMap().get(Long.valueOf("6"))).isEqualTo("7");
}
@Test
public void testGenericMapWithCollectionValueFactoryMethod() {
void testGenericMapWithCollectionValueFactoryMethod() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.addPropertyEditorRegistrar(new PropertyEditorRegistrar() {
@Override
@@ -597,7 +597,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericListBean() throws Exception {
void testGenericListBean() throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("genericBeanTests.xml", getClass()));
@@ -607,7 +607,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericSetBean() throws Exception {
void testGenericSetBean() throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("genericBeanTests.xml", getClass()));
@@ -617,18 +617,18 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericMapBean() throws Exception {
void testGenericMapBean() throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("genericBeanTests.xml", getClass()));
Map<?, ?> map = (Map<?, ?>) bf.getBean("map");
assertThat(map.size()).isEqualTo(1);
assertThat(map).hasSize(1);
assertThat(map.keySet().iterator().next()).isEqualTo(10);
assertThat(map.values().iterator().next()).isEqualTo(new URL("http://localhost:8080"));
}
@Test
public void testGenericallyTypedIntegerBean() {
void testGenericallyTypedIntegerBean() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("genericBeanTests.xml", getClass()));
@@ -639,7 +639,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericallyTypedSetOfIntegerBean() {
void testGenericallyTypedSetOfIntegerBean() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("genericBeanTests.xml", getClass()));
@@ -651,7 +651,7 @@ public class BeanFactoryGenericsTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
public void testSetBean() throws Exception {
void testSetBean() throws Exception {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("genericBeanTests.xml", getClass()));
@@ -671,7 +671,7 @@ public class BeanFactoryGenericsTests {
* <p>See SPR-9493
*/
@Test
public void parameterizedStaticFactoryMethod() {
void parameterizedStaticFactoryMethod() {
RootBeanDefinition rbd = new RootBeanDefinition(Mockito.class);
rbd.setFactoryMethodName("mock");
rbd.getConstructorArgumentValues().addGenericArgumentValue(Runnable.class);
@@ -682,7 +682,7 @@ public class BeanFactoryGenericsTests {
assertThat(bf.getType("mock")).isEqualTo(Runnable.class);
assertThat(bf.getType("mock")).isEqualTo(Runnable.class);
Map<String, Runnable> beans = bf.getBeansOfType(Runnable.class);
assertThat(beans.size()).isEqualTo(1);
assertThat(beans).hasSize(1);
}
/**
@@ -697,7 +697,7 @@ public class BeanFactoryGenericsTests {
* <p>See SPR-10411
*/
@Test
public void parameterizedInstanceFactoryMethod() {
void parameterizedInstanceFactoryMethod() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(MocksControl.class);
@@ -714,11 +714,11 @@ public class BeanFactoryGenericsTests {
assertThat(bf.getType("mock")).isEqualTo(Runnable.class);
assertThat(bf.getType("mock")).isEqualTo(Runnable.class);
Map<String, Runnable> beans = bf.getBeansOfType(Runnable.class);
assertThat(beans.size()).isEqualTo(1);
assertThat(beans).hasSize(1);
}
@Test
public void parameterizedInstanceFactoryMethodWithNonResolvedClassName() {
void parameterizedInstanceFactoryMethodWithNonResolvedClassName() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(MocksControl.class);
@@ -735,11 +735,11 @@ public class BeanFactoryGenericsTests {
assertThat(bf.getType("mock")).isEqualTo(Runnable.class);
assertThat(bf.getType("mock")).isEqualTo(Runnable.class);
Map<String, Runnable> beans = bf.getBeansOfType(Runnable.class);
assertThat(beans.size()).isEqualTo(1);
assertThat(beans).hasSize(1);
}
@Test
public void parameterizedInstanceFactoryMethodWithWrappedClassName() {
void parameterizedInstanceFactoryMethodWithWrappedClassName() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition();
@@ -754,11 +754,11 @@ public class BeanFactoryGenericsTests {
assertThat(bf.getType("mock")).isEqualTo(Runnable.class);
assertThat(bf.getType("mock")).isEqualTo(Runnable.class);
Map<String, Runnable> beans = bf.getBeansOfType(Runnable.class);
assertThat(beans.size()).isEqualTo(1);
assertThat(beans).hasSize(1);
}
@Test
public void parameterizedInstanceFactoryMethodWithInvalidClassName() {
void parameterizedInstanceFactoryMethodWithInvalidClassName() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(MocksControl.class);
@@ -775,11 +775,11 @@ public class BeanFactoryGenericsTests {
assertThat(bf.getType("mock")).isNull();
assertThat(bf.getType("mock")).isNull();
Map<String, Runnable> beans = bf.getBeansOfType(Runnable.class);
assertThat(beans.size()).isEqualTo(0);
assertThat(beans).hasSize(0);
}
@Test
public void parameterizedInstanceFactoryMethodWithIndexedArgument() {
void parameterizedInstanceFactoryMethodWithIndexedArgument() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
RootBeanDefinition rbd = new RootBeanDefinition(MocksControl.class);
@@ -796,11 +796,11 @@ public class BeanFactoryGenericsTests {
assertThat(bf.getType("mock")).isEqualTo(Runnable.class);
assertThat(bf.getType("mock")).isEqualTo(Runnable.class);
Map<String, Runnable> beans = bf.getBeansOfType(Runnable.class);
assertThat(beans.size()).isEqualTo(1);
assertThat(beans).hasSize(1);
}
@Test // SPR-16720
public void parameterizedInstanceFactoryMethodWithTempClassLoader() {
void parameterizedInstanceFactoryMethodWithTempClassLoader() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.setTempClassLoader(new OverridingClassLoader(getClass().getClassLoader()));
@@ -818,11 +818,11 @@ public class BeanFactoryGenericsTests {
assertThat(bf.getType("mock")).isEqualTo(Runnable.class);
assertThat(bf.getType("mock")).isEqualTo(Runnable.class);
Map<String, Runnable> beans = bf.getBeansOfType(Runnable.class);
assertThat(beans.size()).isEqualTo(1);
assertThat(beans).hasSize(1);
}
@Test
public void testGenericMatchingWithBeanNameDifferentiation() {
void testGenericMatchingWithBeanNameDifferentiation() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.setAutowireCandidateResolver(new GenericTypeAwareAutowireCandidateResolver());
@@ -838,15 +838,15 @@ public class BeanFactoryGenericsTests {
String[] numberStoreNames = bf.getBeanNamesForType(ResolvableType.forClass(NumberStore.class));
String[] doubleStoreNames = bf.getBeanNamesForType(ResolvableType.forClassWithGenerics(NumberStore.class, Double.class));
String[] floatStoreNames = bf.getBeanNamesForType(ResolvableType.forClassWithGenerics(NumberStore.class, Float.class));
assertThat(numberStoreNames.length).isEqualTo(2);
assertThat(numberStoreNames).hasSize(2);
assertThat(numberStoreNames[0]).isEqualTo("doubleStore");
assertThat(numberStoreNames[1]).isEqualTo("floatStore");
assertThat(doubleStoreNames.length).isEqualTo(0);
assertThat(floatStoreNames.length).isEqualTo(0);
assertThat(doubleStoreNames).hasSize(0);
assertThat(floatStoreNames).hasSize(0);
}
@Test
public void testGenericMatchingWithFullTypeDifferentiation() {
void testGenericMatchingWithFullTypeDifferentiation() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
bf.setAutowireCandidateResolver(new GenericTypeAwareAutowireCandidateResolver());
@@ -867,12 +867,12 @@ public class BeanFactoryGenericsTests {
String[] numberStoreNames = bf.getBeanNamesForType(ResolvableType.forClass(NumberStore.class));
String[] doubleStoreNames = bf.getBeanNamesForType(ResolvableType.forClassWithGenerics(NumberStore.class, Double.class));
String[] floatStoreNames = bf.getBeanNamesForType(ResolvableType.forClassWithGenerics(NumberStore.class, Float.class));
assertThat(numberStoreNames.length).isEqualTo(2);
assertThat(numberStoreNames).hasSize(2);
assertThat(numberStoreNames[0]).isEqualTo("store1");
assertThat(numberStoreNames[1]).isEqualTo("store2");
assertThat(doubleStoreNames.length).isEqualTo(1);
assertThat(doubleStoreNames).hasSize(1);
assertThat(doubleStoreNames[0]).isEqualTo("store1");
assertThat(floatStoreNames.length).isEqualTo(1);
assertThat(floatStoreNames).hasSize(1);
assertThat(floatStoreNames[0]).isEqualTo("store2");
ObjectProvider<NumberStore<?>> numberStoreProvider = bf.getBeanProvider(ResolvableType.forClass(NumberStore.class));
@@ -938,7 +938,7 @@ public class BeanFactoryGenericsTests {
}
@Test
public void testGenericMatchingWithUnresolvedOrderedStream() {
void testGenericMatchingWithUnresolvedOrderedStream() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
bf.setAutowireCandidateResolver(new GenericTypeAwareAutowireCandidateResolver());
@@ -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.
@@ -244,7 +244,7 @@ public class QualifierAnnotationAutowireBeanFactoryTests {
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
private static @interface TestQualifier {
private @interface TestQualifier {
}
}
@@ -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,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.support.security.support;
/**
@@ -27,4 +28,5 @@ public class CustomCallbackBean {
public void destroy() {
System.setProperty("security.destroy", "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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.support.security.support;
import org.springframework.beans.factory.DisposableBean;
@@ -26,4 +27,5 @@ public class DestroyBean implements DisposableBean {
public void destroy() throws Exception {
System.setProperty("security.destroy", "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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.support.security.support;
/**
@@ -33,4 +34,5 @@ public class FactoryBean {
System.getProperties();
return new Object();
}
}
@@ -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,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.support.security.support;
import org.springframework.beans.factory.InitializingBean;
@@ -26,4 +27,5 @@ public class InitBean implements InitializingBean {
public void afterPropertiesSet() throws Exception {
System.getProperties();
}
}
@@ -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,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.support.security.support;
/**
@@ -27,4 +28,5 @@ public class PropertyBean {
public void setProperty(Object property) {
}
}
@@ -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.
@@ -26,18 +26,18 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
*
* @author Rick Evans
*/
public class ClassNameBeanWiringInfoResolverTests {
class ClassNameBeanWiringInfoResolverTests {
@Test
public void resolveWiringInfoWithNullBeanInstance() throws Exception {
void resolveWiringInfoWithNullBeanInstance() throws Exception {
assertThatIllegalArgumentException().isThrownBy(() ->
new ClassNameBeanWiringInfoResolver().resolveWiringInfo(null));
}
@Test
public void resolveWiringInfo() {
void resolveWiringInfo() {
ClassNameBeanWiringInfoResolver resolver = new ClassNameBeanWiringInfoResolver();
Long beanInstance = new Long(1);
Long beanInstance = 1L;
BeanWiringInfo info = resolver.resolveWiringInfo(beanInstance);
assertThat(info).isNotNull();
assertThat(info.getBeanName()).as("Not resolving bean name to the class name of the supplied bean instance as per class contract.").isEqualTo(beanInstance.getClass().getName());
@@ -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.
@@ -64,10 +64,10 @@ import static org.assertj.core.api.Assertions.within;
* @author Chris Beams
* @since 10.06.2003
*/
public class CustomEditorTests {
class CustomEditorTests {
@Test
public void testComplexObject() {
void testComplexObject() {
TestBean tb = new TestBean();
String newName = "Rod";
String tbString = "Kerry_34";
@@ -80,12 +80,12 @@ public class CustomEditorTests {
pvs.addPropertyValue(new PropertyValue("touchy", "valid"));
pvs.addPropertyValue(new PropertyValue("spouse", tbString));
bw.setPropertyValues(pvs);
assertThat(tb.getSpouse() != null).as("spouse is non-null").isTrue();
assertThat(tb.getSpouse()).as("spouse is non-null").isNotNull();
assertThat(tb.getSpouse().getName().equals("Kerry") && tb.getSpouse().getAge() == 34).as("spouse name is Kerry and age is 34").isTrue();
}
@Test
public void testComplexObjectWithOldValueAccess() {
void testComplexObjectWithOldValueAccess() {
TestBean tb = new TestBean();
String newName = "Rod";
String tbString = "Kerry_34";
@@ -100,7 +100,7 @@ public class CustomEditorTests {
pvs.addPropertyValue(new PropertyValue("spouse", tbString));
bw.setPropertyValues(pvs);
assertThat(tb.getSpouse() != null).as("spouse is non-null").isTrue();
assertThat(tb.getSpouse()).as("spouse is non-null").isNotNull();
assertThat(tb.getSpouse().getName().equals("Kerry") && tb.getSpouse().getAge() == 34).as("spouse name is Kerry and age is 34").isTrue();
ITestBean spouse = tb.getSpouse();
@@ -109,7 +109,7 @@ public class CustomEditorTests {
}
@Test
public void testCustomEditorForSingleProperty() {
void testCustomEditorForSingleProperty() {
TestBean tb = new TestBean();
BeanWrapper bw = new BeanWrapperImpl(tb);
bw.registerCustomEditor(String.class, "name", new PropertyEditorSupport() {
@@ -127,7 +127,7 @@ public class CustomEditorTests {
}
@Test
public void testCustomEditorForAllStringProperties() {
void testCustomEditorForAllStringProperties() {
TestBean tb = new TestBean();
BeanWrapper bw = new BeanWrapperImpl(tb);
bw.registerCustomEditor(String.class, new PropertyEditorSupport() {
@@ -145,7 +145,7 @@ public class CustomEditorTests {
}
@Test
public void testCustomEditorForSingleNestedProperty() {
void testCustomEditorForSingleNestedProperty() {
TestBean tb = new TestBean();
tb.setSpouse(new TestBean());
BeanWrapper bw = new BeanWrapperImpl(tb);
@@ -164,7 +164,7 @@ public class CustomEditorTests {
}
@Test
public void testCustomEditorForAllNestedStringProperties() {
void testCustomEditorForAllNestedStringProperties() {
TestBean tb = new TestBean();
tb.setSpouse(new TestBean());
BeanWrapper bw = new BeanWrapperImpl(tb);
@@ -183,7 +183,7 @@ public class CustomEditorTests {
}
@Test
public void testDefaultBooleanEditorForPrimitiveType() {
void testDefaultBooleanEditorForPrimitiveType() {
BooleanTestBean tb = new BooleanTestBean();
BeanWrapper bw = new BeanWrapperImpl(tb);
@@ -229,7 +229,7 @@ public class CustomEditorTests {
}
@Test
public void testDefaultBooleanEditorForWrapperType() {
void testDefaultBooleanEditorForWrapperType() {
BooleanTestBean tb = new BooleanTestBean();
BeanWrapper bw = new BeanWrapperImpl(tb);
@@ -239,28 +239,28 @@ public class CustomEditorTests {
bw.setPropertyValue("bool2", "false");
assertThat(Boolean.FALSE.equals(bw.getPropertyValue("bool2"))).as("Correct bool2 value").isTrue();
boolean condition3 = !tb.getBool2().booleanValue();
boolean condition3 = !tb.getBool2();
assertThat(condition3).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "on");
assertThat(tb.getBool2().booleanValue()).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "off");
boolean condition2 = !tb.getBool2().booleanValue();
boolean condition2 = !tb.getBool2();
assertThat(condition2).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "yes");
assertThat(tb.getBool2().booleanValue()).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "no");
boolean condition1 = !tb.getBool2().booleanValue();
boolean condition1 = !tb.getBool2();
assertThat(condition1).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "1");
assertThat(tb.getBool2().booleanValue()).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "0");
boolean condition = !tb.getBool2().booleanValue();
boolean condition = !tb.getBool2();
assertThat(condition).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "");
@@ -268,7 +268,7 @@ public class CustomEditorTests {
}
@Test
public void testCustomBooleanEditorWithAllowEmpty() {
void testCustomBooleanEditorWithAllowEmpty() {
BooleanTestBean tb = new BooleanTestBean();
BeanWrapper bw = new BeanWrapperImpl(tb);
bw.registerCustomEditor(Boolean.class, new CustomBooleanEditor(true));
@@ -279,37 +279,37 @@ public class CustomEditorTests {
bw.setPropertyValue("bool2", "false");
assertThat(Boolean.FALSE.equals(bw.getPropertyValue("bool2"))).as("Correct bool2 value").isTrue();
boolean condition3 = !tb.getBool2().booleanValue();
boolean condition3 = !tb.getBool2();
assertThat(condition3).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "on");
assertThat(tb.getBool2().booleanValue()).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "off");
boolean condition2 = !tb.getBool2().booleanValue();
boolean condition2 = !tb.getBool2();
assertThat(condition2).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "yes");
assertThat(tb.getBool2().booleanValue()).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "no");
boolean condition1 = !tb.getBool2().booleanValue();
boolean condition1 = !tb.getBool2();
assertThat(condition1).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "1");
assertThat(tb.getBool2().booleanValue()).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "0");
boolean condition = !tb.getBool2().booleanValue();
boolean condition = !tb.getBool2();
assertThat(condition).as("Correct bool2 value").isTrue();
bw.setPropertyValue("bool2", "");
assertThat(bw.getPropertyValue("bool2") == null).as("Correct bool2 value").isTrue();
assertThat(tb.getBool2() == null).as("Correct bool2 value").isTrue();
assertThat(bw.getPropertyValue("bool2")).as("Correct bool2 value").isNull();
assertThat(tb.getBool2()).as("Correct bool2 value").isNull();
}
@Test
public void testCustomBooleanEditorWithSpecialTrueAndFalseStrings() throws Exception {
void testCustomBooleanEditorWithSpecialTrueAndFalseStrings() throws Exception {
String trueString = "pechorin";
String falseString = "nash";
@@ -333,7 +333,7 @@ public class CustomEditorTests {
}
@Test
public void testDefaultNumberEditor() {
void testDefaultNumberEditor() {
NumberTestBean tb = new NumberTestBean();
BeanWrapper bw = new BeanWrapperImpl(tb);
@@ -350,34 +350,34 @@ public class CustomEditorTests {
bw.setPropertyValue("double2", "6.1");
bw.setPropertyValue("bigDecimal", "4.5");
assertThat(new Short("1").equals(bw.getPropertyValue("short1"))).as("Correct short1 value").isTrue();
assertThat(Short.valueOf("1").equals(bw.getPropertyValue("short1"))).as("Correct short1 value").isTrue();
assertThat(tb.getShort1() == 1).as("Correct short1 value").isTrue();
assertThat(new Short("2").equals(bw.getPropertyValue("short2"))).as("Correct short2 value").isTrue();
assertThat(new Short("2").equals(tb.getShort2())).as("Correct short2 value").isTrue();
assertThat(new Integer("7").equals(bw.getPropertyValue("int1"))).as("Correct int1 value").isTrue();
assertThat(Short.valueOf("2").equals(bw.getPropertyValue("short2"))).as("Correct short2 value").isTrue();
assertThat(Short.valueOf("2").equals(tb.getShort2())).as("Correct short2 value").isTrue();
assertThat(Integer.valueOf("7").equals(bw.getPropertyValue("int1"))).as("Correct int1 value").isTrue();
assertThat(tb.getInt1() == 7).as("Correct int1 value").isTrue();
assertThat(new Integer("8").equals(bw.getPropertyValue("int2"))).as("Correct int2 value").isTrue();
assertThat(new Integer("8").equals(tb.getInt2())).as("Correct int2 value").isTrue();
assertThat(new Long("5").equals(bw.getPropertyValue("long1"))).as("Correct long1 value").isTrue();
assertThat(Integer.valueOf("8").equals(bw.getPropertyValue("int2"))).as("Correct int2 value").isTrue();
assertThat(Integer.valueOf("8").equals(tb.getInt2())).as("Correct int2 value").isTrue();
assertThat(Long.valueOf("5").equals(bw.getPropertyValue("long1"))).as("Correct long1 value").isTrue();
assertThat(tb.getLong1() == 5).as("Correct long1 value").isTrue();
assertThat(new Long("6").equals(bw.getPropertyValue("long2"))).as("Correct long2 value").isTrue();
assertThat(new Long("6").equals(tb.getLong2())).as("Correct long2 value").isTrue();
assertThat(Long.valueOf("6").equals(bw.getPropertyValue("long2"))).as("Correct long2 value").isTrue();
assertThat(Long.valueOf("6").equals(tb.getLong2())).as("Correct long2 value").isTrue();
assertThat(new BigInteger("3").equals(bw.getPropertyValue("bigInteger"))).as("Correct bigInteger value").isTrue();
assertThat(new BigInteger("3").equals(tb.getBigInteger())).as("Correct bigInteger value").isTrue();
assertThat(new Float("7.1").equals(bw.getPropertyValue("float1"))).as("Correct float1 value").isTrue();
assertThat(new Float("7.1").equals(new Float(tb.getFloat1()))).as("Correct float1 value").isTrue();
assertThat(new Float("8.1").equals(bw.getPropertyValue("float2"))).as("Correct float2 value").isTrue();
assertThat(new Float("8.1").equals(tb.getFloat2())).as("Correct float2 value").isTrue();
assertThat(new Double("5.1").equals(bw.getPropertyValue("double1"))).as("Correct double1 value").isTrue();
assertThat(Float.valueOf("7.1").equals(bw.getPropertyValue("float1"))).as("Correct float1 value").isTrue();
assertThat(Float.valueOf("7.1").equals(tb.getFloat1())).as("Correct float1 value").isTrue();
assertThat(Float.valueOf("8.1").equals(bw.getPropertyValue("float2"))).as("Correct float2 value").isTrue();
assertThat(Float.valueOf("8.1").equals(tb.getFloat2())).as("Correct float2 value").isTrue();
assertThat(Double.valueOf("5.1").equals(bw.getPropertyValue("double1"))).as("Correct double1 value").isTrue();
assertThat(tb.getDouble1() == 5.1).as("Correct double1 value").isTrue();
assertThat(new Double("6.1").equals(bw.getPropertyValue("double2"))).as("Correct double2 value").isTrue();
assertThat(new Double("6.1").equals(tb.getDouble2())).as("Correct double2 value").isTrue();
assertThat(Double.valueOf("6.1").equals(bw.getPropertyValue("double2"))).as("Correct double2 value").isTrue();
assertThat(Double.valueOf("6.1").equals(tb.getDouble2())).as("Correct double2 value").isTrue();
assertThat(new BigDecimal("4.5").equals(bw.getPropertyValue("bigDecimal"))).as("Correct bigDecimal value").isTrue();
assertThat(new BigDecimal("4.5").equals(tb.getBigDecimal())).as("Correct bigDecimal value").isTrue();
}
@Test
public void testCustomNumberEditorWithoutAllowEmpty() {
void testCustomNumberEditorWithoutAllowEmpty() {
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
NumberTestBean tb = new NumberTestBean();
BeanWrapper bw = new BeanWrapperImpl(tb);
@@ -407,34 +407,34 @@ public class CustomEditorTests {
bw.setPropertyValue("double2", "6,1");
bw.setPropertyValue("bigDecimal", "4,5");
assertThat(new Short("1").equals(bw.getPropertyValue("short1"))).as("Correct short1 value").isTrue();
assertThat(bw.getPropertyValue("short1")).as("Correct short1 value").isEqualTo(Short.valueOf("1"));
assertThat(tb.getShort1() == 1).as("Correct short1 value").isTrue();
assertThat(new Short("2").equals(bw.getPropertyValue("short2"))).as("Correct short2 value").isTrue();
assertThat(new Short("2").equals(tb.getShort2())).as("Correct short2 value").isTrue();
assertThat(new Integer("7").equals(bw.getPropertyValue("int1"))).as("Correct int1 value").isTrue();
assertThat(bw.getPropertyValue("short2")).as("Correct short2 value").isEqualTo(Short.valueOf("2"));
assertThat(tb.getShort2()).as("Correct short2 value").isEqualTo(Short.valueOf("2"));
assertThat(bw.getPropertyValue("int1")).as("Correct int1 value").isEqualTo(Integer.valueOf("7"));
assertThat(tb.getInt1() == 7).as("Correct int1 value").isTrue();
assertThat(new Integer("8").equals(bw.getPropertyValue("int2"))).as("Correct int2 value").isTrue();
assertThat(new Integer("8").equals(tb.getInt2())).as("Correct int2 value").isTrue();
assertThat(new Long("5").equals(bw.getPropertyValue("long1"))).as("Correct long1 value").isTrue();
assertThat(bw.getPropertyValue("int2")).as("Correct int2 value").isEqualTo(Integer.valueOf("8"));
assertThat(tb.getInt2()).as("Correct int2 value").isEqualTo(Integer.valueOf("8"));
assertThat(bw.getPropertyValue("long1")).as("Correct long1 value").isEqualTo(Long.valueOf("5"));
assertThat(tb.getLong1() == 5).as("Correct long1 value").isTrue();
assertThat(new Long("6").equals(bw.getPropertyValue("long2"))).as("Correct long2 value").isTrue();
assertThat(new Long("6").equals(tb.getLong2())).as("Correct long2 value").isTrue();
assertThat(bw.getPropertyValue("long2")).as("Correct long2 value").isEqualTo(Long.valueOf("6"));
assertThat(tb.getLong2()).as("Correct long2 value").isEqualTo(Long.valueOf("6"));
assertThat(new BigInteger("3").equals(bw.getPropertyValue("bigInteger"))).as("Correct bigInteger value").isTrue();
assertThat(new BigInteger("3").equals(tb.getBigInteger())).as("Correct bigInteger value").isTrue();
assertThat(new Float("7.1").equals(bw.getPropertyValue("float1"))).as("Correct float1 value").isTrue();
assertThat(new Float("7.1").equals(new Float(tb.getFloat1()))).as("Correct float1 value").isTrue();
assertThat(new Float("8.1").equals(bw.getPropertyValue("float2"))).as("Correct float2 value").isTrue();
assertThat(new Float("8.1").equals(tb.getFloat2())).as("Correct float2 value").isTrue();
assertThat(new Double("5.1").equals(bw.getPropertyValue("double1"))).as("Correct double1 value").isTrue();
assertThat(bw.getPropertyValue("float1")).as("Correct float1 value").isEqualTo(Float.valueOf("7.1"));
assertThat(Float.valueOf(tb.getFloat1())).as("Correct float1 value").isEqualTo(Float.valueOf("7.1"));
assertThat(bw.getPropertyValue("float2")).as("Correct float2 value").isEqualTo(Float.valueOf("8.1"));
assertThat(tb.getFloat2()).as("Correct float2 value").isEqualTo(Float.valueOf("8.1"));
assertThat(bw.getPropertyValue("double1")).as("Correct double1 value").isEqualTo(Double.valueOf("5.1"));
assertThat(tb.getDouble1() == 5.1).as("Correct double1 value").isTrue();
assertThat(new Double("6.1").equals(bw.getPropertyValue("double2"))).as("Correct double2 value").isTrue();
assertThat(new Double("6.1").equals(tb.getDouble2())).as("Correct double2 value").isTrue();
assertThat(bw.getPropertyValue("double2")).as("Correct double2 value").isEqualTo(Double.valueOf("6.1"));
assertThat(tb.getDouble2()).as("Correct double2 value").isEqualTo(Double.valueOf("6.1"));
assertThat(new BigDecimal("4.5").equals(bw.getPropertyValue("bigDecimal"))).as("Correct bigDecimal value").isTrue();
assertThat(new BigDecimal("4.5").equals(tb.getBigDecimal())).as("Correct bigDecimal value").isTrue();
}
@Test
public void testCustomNumberEditorWithAllowEmpty() {
void testCustomNumberEditorWithAllowEmpty() {
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
NumberTestBean tb = new NumberTestBean();
BeanWrapper bw = new BeanWrapperImpl(tb);
@@ -443,10 +443,10 @@ public class CustomEditorTests {
bw.setPropertyValue("long1", "5");
bw.setPropertyValue("long2", "6");
assertThat(new Long("5").equals(bw.getPropertyValue("long1"))).as("Correct long1 value").isTrue();
assertThat(Long.valueOf("5").equals(bw.getPropertyValue("long1"))).as("Correct long1 value").isTrue();
assertThat(tb.getLong1() == 5).as("Correct long1 value").isTrue();
assertThat(new Long("6").equals(bw.getPropertyValue("long2"))).as("Correct long2 value").isTrue();
assertThat(new Long("6").equals(tb.getLong2())).as("Correct long2 value").isTrue();
assertThat(Long.valueOf("6").equals(bw.getPropertyValue("long2"))).as("Correct long2 value").isTrue();
assertThat(Long.valueOf("6").equals(tb.getLong2())).as("Correct long2 value").isTrue();
bw.setPropertyValue("long2", "");
assertThat(bw.getPropertyValue("long2") == null).as("Correct long2 value").isTrue();
@@ -458,7 +458,7 @@ public class CustomEditorTests {
}
@Test
public void testCustomNumberEditorWithFrenchBigDecimal() throws Exception {
void testCustomNumberEditorWithFrenchBigDecimal() throws Exception {
NumberFormat nf = NumberFormat.getNumberInstance(Locale.FRENCH);
NumberTestBean tb = new NumberTestBean();
BeanWrapper bw = new BeanWrapperImpl(tb);
@@ -475,14 +475,14 @@ public class CustomEditorTests {
}
@Test
public void testParseShortGreaterThanMaxValueWithoutNumberFormat() {
void testParseShortGreaterThanMaxValueWithoutNumberFormat() {
CustomNumberEditor editor = new CustomNumberEditor(Short.class, true);
assertThatExceptionOfType(NumberFormatException.class).as("greater than Short.MAX_VALUE + 1").isThrownBy(() ->
editor.setAsText(String.valueOf(Short.MAX_VALUE + 1)));
}
@Test
public void testByteArrayPropertyEditor() {
void testByteArrayPropertyEditor() {
PrimitiveArrayBean bean = new PrimitiveArrayBean();
BeanWrapper bw = new BeanWrapperImpl(bean);
bw.setPropertyValue("byteArray", "myvalue");
@@ -490,7 +490,7 @@ public class CustomEditorTests {
}
@Test
public void testCharArrayPropertyEditor() {
void testCharArrayPropertyEditor() {
PrimitiveArrayBean bean = new PrimitiveArrayBean();
BeanWrapper bw = new BeanWrapperImpl(bean);
bw.setPropertyValue("charArray", "myvalue");
@@ -498,7 +498,7 @@ public class CustomEditorTests {
}
@Test
public void testCharacterEditor() {
void testCharacterEditor() {
CharBean cb = new CharBean();
BeanWrapper bw = new BeanWrapperImpl(cb);
@@ -520,78 +520,78 @@ public class CustomEditorTests {
}
@Test
public void testCharacterEditorWithAllowEmpty() {
void testCharacterEditorWithAllowEmpty() {
CharBean cb = new CharBean();
BeanWrapper bw = new BeanWrapperImpl(cb);
bw.registerCustomEditor(Character.class, new CharacterEditor(true));
bw.setPropertyValue("myCharacter", new Character('c'));
assertThat(cb.getMyCharacter()).isEqualTo(new Character('c'));
bw.setPropertyValue("myCharacter", 'c');
assertThat(cb.getMyCharacter()).isEqualTo(Character.valueOf('c'));
bw.setPropertyValue("myCharacter", "c");
assertThat(cb.getMyCharacter()).isEqualTo(new Character('c'));
assertThat(cb.getMyCharacter()).isEqualTo(Character.valueOf('c'));
bw.setPropertyValue("myCharacter", "\u0041");
assertThat(cb.getMyCharacter()).isEqualTo(new Character('A'));
assertThat(cb.getMyCharacter()).isEqualTo(Character.valueOf('A'));
bw.setPropertyValue("myCharacter", " ");
assertThat(cb.getMyCharacter()).isEqualTo(new Character(' '));
assertThat(cb.getMyCharacter()).isEqualTo(Character.valueOf(' '));
bw.setPropertyValue("myCharacter", "");
assertThat(cb.getMyCharacter()).isNull();
}
@Test
public void testCharacterEditorSetAsTextWithStringLongerThanOneCharacter() throws Exception {
void testCharacterEditorSetAsTextWithStringLongerThanOneCharacter() throws Exception {
PropertyEditor charEditor = new CharacterEditor(false);
assertThatIllegalArgumentException().isThrownBy(() ->
charEditor.setAsText("ColdWaterCanyon"));
}
@Test
public void testCharacterEditorGetAsTextReturnsEmptyStringIfValueIsNull() throws Exception {
void testCharacterEditorGetAsTextReturnsEmptyStringIfValueIsNull() throws Exception {
PropertyEditor charEditor = new CharacterEditor(false);
assertThat(charEditor.getAsText()).isEqualTo("");
assertThat(charEditor.getAsText()).isEmpty();
charEditor = new CharacterEditor(true);
charEditor.setAsText(null);
assertThat(charEditor.getAsText()).isEqualTo("");
assertThat(charEditor.getAsText()).isEmpty();
charEditor.setAsText("");
assertThat(charEditor.getAsText()).isEqualTo("");
assertThat(charEditor.getAsText()).isEmpty();
charEditor.setAsText(" ");
assertThat(charEditor.getAsText()).isEqualTo(" ");
}
@Test
public void testCharacterEditorSetAsTextWithNullNotAllowingEmptyAsNull() throws Exception {
void testCharacterEditorSetAsTextWithNullNotAllowingEmptyAsNull() throws Exception {
PropertyEditor charEditor = new CharacterEditor(false);
assertThatIllegalArgumentException().isThrownBy(() ->
charEditor.setAsText(null));
}
@Test
public void testClassEditor() {
void testClassEditor() {
PropertyEditor classEditor = new ClassEditor();
classEditor.setAsText(TestBean.class.getName());
assertThat(classEditor.getValue()).isEqualTo(TestBean.class);
assertThat(classEditor.getAsText()).isEqualTo(TestBean.class.getName());
classEditor.setAsText(null);
assertThat(classEditor.getAsText()).isEqualTo("");
assertThat(classEditor.getAsText()).isEmpty();
classEditor.setAsText("");
assertThat(classEditor.getAsText()).isEqualTo("");
assertThat(classEditor.getAsText()).isEmpty();
classEditor.setAsText("\t ");
assertThat(classEditor.getAsText()).isEqualTo("");
assertThat(classEditor.getAsText()).isEmpty();
}
@Test
public void testClassEditorWithNonExistentClass() throws Exception {
void testClassEditorWithNonExistentClass() throws Exception {
PropertyEditor classEditor = new ClassEditor();
assertThatIllegalArgumentException().isThrownBy(() ->
classEditor.setAsText("hairdresser.on.Fire"));
}
@Test
public void testClassEditorWithArray() {
void testClassEditorWithArray() {
PropertyEditor classEditor = new ClassEditor();
classEditor.setAsText("org.springframework.beans.testfixture.beans.TestBean[]");
assertThat(classEditor.getValue()).isEqualTo(TestBean[].class);
@@ -602,7 +602,7 @@ public class CustomEditorTests {
* SPR_2165 - ClassEditor is inconsistent with multidimensional arrays
*/
@Test
public void testGetAsTextWithTwoDimensionalArray() throws Exception {
void testGetAsTextWithTwoDimensionalArray() throws Exception {
String[][] chessboard = new String[8][8];
ClassEditor editor = new ClassEditor();
editor.setValue(chessboard.getClass());
@@ -613,7 +613,7 @@ public class CustomEditorTests {
* SPR_2165 - ClassEditor is inconsistent with multidimensional arrays
*/
@Test
public void testGetAsTextWithRidiculousMultiDimensionalArray() throws Exception {
void testGetAsTextWithRidiculousMultiDimensionalArray() throws Exception {
String[][][][][] ridiculousChessboard = new String[8][4][0][1][3];
ClassEditor editor = new ClassEditor();
editor.setValue(ridiculousChessboard.getClass());
@@ -621,7 +621,7 @@ public class CustomEditorTests {
}
@Test
public void testFileEditor() {
void testFileEditor() {
PropertyEditor fileEditor = new FileEditor();
fileEditor.setAsText("file:myfile.txt");
assertThat(fileEditor.getValue()).isEqualTo(new File("myfile.txt"));
@@ -629,7 +629,7 @@ public class CustomEditorTests {
}
@Test
public void testFileEditorWithRelativePath() {
void testFileEditorWithRelativePath() {
PropertyEditor fileEditor = new FileEditor();
try {
fileEditor.setAsText("myfile.txt");
@@ -641,7 +641,7 @@ public class CustomEditorTests {
}
@Test
public void testFileEditorWithAbsolutePath() {
void testFileEditorWithAbsolutePath() {
PropertyEditor fileEditor = new FileEditor();
// testing on Windows
if (new File("C:/myfile.txt").isAbsolute()) {
@@ -656,18 +656,18 @@ public class CustomEditorTests {
}
@Test
public void testLocaleEditor() {
void testLocaleEditor() {
PropertyEditor localeEditor = new LocaleEditor();
localeEditor.setAsText("en_CA");
assertThat(localeEditor.getValue()).isEqualTo(Locale.CANADA);
assertThat(localeEditor.getAsText()).isEqualTo("en_CA");
localeEditor = new LocaleEditor();
assertThat(localeEditor.getAsText()).isEqualTo("");
assertThat(localeEditor.getAsText()).isEmpty();
}
@Test
public void testPatternEditor() {
void testPatternEditor() {
final String REGEX = "a.*";
PropertyEditor patternEditor = new PatternEditor();
@@ -676,15 +676,15 @@ public class CustomEditorTests {
assertThat(patternEditor.getAsText()).isEqualTo(REGEX);
patternEditor = new PatternEditor();
assertThat(patternEditor.getAsText()).isEqualTo("");
assertThat(patternEditor.getAsText()).isEmpty();
patternEditor = new PatternEditor();
patternEditor.setAsText(null);
assertThat(patternEditor.getAsText()).isEqualTo("");
assertThat(patternEditor.getAsText()).isEmpty();
}
@Test
public void testCustomBooleanEditor() {
void testCustomBooleanEditor() {
CustomBooleanEditor editor = new CustomBooleanEditor(false);
editor.setAsText("true");
@@ -696,15 +696,15 @@ public class CustomEditorTests {
assertThat(editor.getAsText()).isEqualTo("false");
editor.setValue(null);
assertThat(editor.getValue()).isEqualTo(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getValue()).isNull();
assertThat(editor.getAsText()).isEmpty();
assertThatIllegalArgumentException().isThrownBy(() ->
editor.setAsText(null));
}
@Test
public void testCustomBooleanEditorWithEmptyAsNull() {
void testCustomBooleanEditorWithEmptyAsNull() {
CustomBooleanEditor editor = new CustomBooleanEditor(true);
editor.setAsText("true");
@@ -716,34 +716,34 @@ public class CustomEditorTests {
assertThat(editor.getAsText()).isEqualTo("false");
editor.setValue(null);
assertThat(editor.getValue()).isEqualTo(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getValue()).isNull();
assertThat(editor.getAsText()).isEmpty();
}
@Test
public void testCustomDateEditor() {
void testCustomDateEditor() {
CustomDateEditor editor = new CustomDateEditor(null, false);
editor.setValue(null);
assertThat(editor.getValue()).isEqualTo(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getValue()).isNull();
assertThat(editor.getAsText()).isEmpty();
}
@Test
public void testCustomDateEditorWithEmptyAsNull() {
void testCustomDateEditorWithEmptyAsNull() {
CustomDateEditor editor = new CustomDateEditor(null, true);
editor.setValue(null);
assertThat(editor.getValue()).isEqualTo(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getValue()).isNull();
assertThat(editor.getAsText()).isEmpty();
}
@Test
public void testCustomDateEditorWithExactDateLength() {
void testCustomDateEditorWithExactDateLength() {
int maxLength = 10;
String validDate = "01/01/2005";
String invalidDate = "01/01/05";
assertThat(validDate.length() == maxLength).isTrue();
assertThat(invalidDate.length() == maxLength).isFalse();
assertThat(validDate).hasSize(maxLength);
assertThat(invalidDate.length()).isNotEqualTo(maxLength);
CustomDateEditor editor = new CustomDateEditor(new SimpleDateFormat("MM/dd/yyyy"), true, maxLength);
editor.setAsText(validDate);
@@ -753,39 +753,39 @@ public class CustomEditorTests {
}
@Test
public void testCustomNumberEditor() {
void testCustomNumberEditor() {
CustomNumberEditor editor = new CustomNumberEditor(Integer.class, false);
editor.setAsText("5");
assertThat(editor.getValue()).isEqualTo(5);
assertThat(editor.getAsText()).isEqualTo("5");
editor.setValue(null);
assertThat(editor.getValue()).isEqualTo(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getValue()).isNull();
assertThat(editor.getAsText()).isEmpty();
}
@Test
public void testCustomNumberEditorWithHex() {
void testCustomNumberEditorWithHex() {
CustomNumberEditor editor = new CustomNumberEditor(Integer.class, false);
editor.setAsText("0x" + Integer.toHexString(64));
assertThat(editor.getValue()).isEqualTo(64);
}
@Test
public void testCustomNumberEditorWithEmptyAsNull() {
void testCustomNumberEditorWithEmptyAsNull() {
CustomNumberEditor editor = new CustomNumberEditor(Integer.class, true);
editor.setAsText("5");
assertThat(editor.getValue()).isEqualTo(5);
assertThat(editor.getAsText()).isEqualTo("5");
editor.setAsText("");
assertThat(editor.getValue()).isEqualTo(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getValue()).isNull();
assertThat(editor.getAsText()).isEmpty();
editor.setValue(null);
assertThat(editor.getValue()).isEqualTo(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getValue()).isNull();
assertThat(editor.getAsText()).isEmpty();
}
@Test
public void testStringTrimmerEditor() {
void testStringTrimmerEditor() {
StringTrimmerEditor editor = new StringTrimmerEditor(false);
editor.setAsText("test");
assertThat(editor.getValue()).isEqualTo("test");
@@ -795,15 +795,15 @@ public class CustomEditorTests {
assertThat(editor.getAsText()).isEqualTo("test");
editor.setAsText("");
assertThat(editor.getValue()).isEqualTo("");
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getAsText()).isEmpty();
editor.setValue(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getAsText()).isEmpty();
editor.setAsText(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getAsText()).isEmpty();
}
@Test
public void testStringTrimmerEditorWithEmptyAsNull() {
void testStringTrimmerEditorWithEmptyAsNull() {
StringTrimmerEditor editor = new StringTrimmerEditor(true);
editor.setAsText("test");
assertThat(editor.getValue()).isEqualTo("test");
@@ -812,14 +812,14 @@ public class CustomEditorTests {
assertThat(editor.getValue()).isEqualTo("test");
assertThat(editor.getAsText()).isEqualTo("test");
editor.setAsText(" ");
assertThat(editor.getValue()).isEqualTo(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getValue()).isNull();
assertThat(editor.getAsText()).isEmpty();
editor.setValue(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getAsText()).isEmpty();
}
@Test
public void testStringTrimmerEditorWithCharsToDelete() {
void testStringTrimmerEditorWithCharsToDelete() {
StringTrimmerEditor editor = new StringTrimmerEditor("\r\n\f", false);
editor.setAsText("te\ns\ft");
assertThat(editor.getValue()).isEqualTo("test");
@@ -829,13 +829,13 @@ public class CustomEditorTests {
assertThat(editor.getAsText()).isEqualTo("test");
editor.setAsText("");
assertThat(editor.getValue()).isEqualTo("");
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getAsText()).isEmpty();
editor.setValue(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getAsText()).isEmpty();
}
@Test
public void testStringTrimmerEditorWithCharsToDeleteAndEmptyAsNull() {
void testStringTrimmerEditorWithCharsToDeleteAndEmptyAsNull() {
StringTrimmerEditor editor = new StringTrimmerEditor("\r\n\f", true);
editor.setAsText("te\ns\ft");
assertThat(editor.getValue()).isEqualTo("test");
@@ -844,14 +844,14 @@ public class CustomEditorTests {
assertThat(editor.getValue()).isEqualTo("test");
assertThat(editor.getAsText()).isEqualTo("test");
editor.setAsText(" \n\f ");
assertThat(editor.getValue()).isEqualTo(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getValue()).isNull();
assertThat(editor.getAsText()).isEmpty();
editor.setValue(null);
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getAsText()).isEmpty();
}
@Test
public void testIndexedPropertiesWithCustomEditorForType() {
void testIndexedPropertiesWithCustomEditorForType() {
IndexedTestBean bean = new IndexedTestBean();
BeanWrapper bw = new BeanWrapperImpl(bean);
bw.registerCustomEditor(String.class, new PropertyEditorSupport() {
@@ -904,7 +904,7 @@ public class CustomEditorTests {
}
@Test
public void testIndexedPropertiesWithCustomEditorForProperty() {
void testIndexedPropertiesWithCustomEditorForProperty() {
IndexedTestBean bean = new IndexedTestBean(false);
BeanWrapper bw = new BeanWrapperImpl(bean);
bw.registerCustomEditor(String.class, "array.name", new PropertyEditorSupport() {
@@ -971,7 +971,7 @@ public class CustomEditorTests {
}
@Test
public void testIndexedPropertiesWithIndividualCustomEditorForProperty() {
void testIndexedPropertiesWithIndividualCustomEditorForProperty() {
IndexedTestBean bean = new IndexedTestBean(false);
BeanWrapper bw = new BeanWrapperImpl(bean);
bw.registerCustomEditor(String.class, "array[0].name", new PropertyEditorSupport() {
@@ -1056,7 +1056,7 @@ public class CustomEditorTests {
}
@Test
public void testNestedIndexedPropertiesWithCustomEditorForProperty() {
void testNestedIndexedPropertiesWithCustomEditorForProperty() {
IndexedTestBean bean = new IndexedTestBean();
TestBean tb0 = bean.getArray()[0];
TestBean tb1 = bean.getArray()[1];
@@ -1140,7 +1140,7 @@ public class CustomEditorTests {
}
@Test
public void testNestedIndexedPropertiesWithIndexedCustomEditorForProperty() {
void testNestedIndexedPropertiesWithIndexedCustomEditorForProperty() {
IndexedTestBean bean = new IndexedTestBean();
TestBean tb0 = bean.getArray()[0];
TestBean tb1 = bean.getArray()[1];
@@ -1191,7 +1191,7 @@ public class CustomEditorTests {
}
@Test
public void testIndexedPropertiesWithDirectAccessAndPropertyEditors() {
void testIndexedPropertiesWithDirectAccessAndPropertyEditors() {
IndexedTestBean bean = new IndexedTestBean();
BeanWrapper bw = new BeanWrapperImpl(bean);
bw.registerCustomEditor(TestBean.class, "array", new PropertyEditorSupport() {
@@ -1245,7 +1245,7 @@ public class CustomEditorTests {
}
@Test
public void testIndexedPropertiesWithDirectAccessAndSpecificPropertyEditors() {
void testIndexedPropertiesWithDirectAccessAndSpecificPropertyEditors() {
IndexedTestBean bean = new IndexedTestBean();
BeanWrapper bw = new BeanWrapperImpl(bean);
bw.registerCustomEditor(TestBean.class, "array[0]", new PropertyEditorSupport() {
@@ -1332,7 +1332,7 @@ public class CustomEditorTests {
}
@Test
public void testIndexedPropertiesWithListPropertyEditor() {
void testIndexedPropertiesWithListPropertyEditor() {
IndexedTestBean bean = new IndexedTestBean();
BeanWrapper bw = new BeanWrapperImpl(bean);
bw.registerCustomEditor(List.class, "list", new PropertyEditorSupport() {
@@ -1350,7 +1350,7 @@ public class CustomEditorTests {
}
@Test
public void testConversionToOldCollections() throws PropertyVetoException {
void testConversionToOldCollections() throws PropertyVetoException {
OldCollectionsBean tb = new OldCollectionsBean();
BeanWrapper bw = new BeanWrapperImpl(tb);
bw.registerCustomEditor(Vector.class, new CustomCollectionEditor(Vector.class));
@@ -1367,7 +1367,7 @@ public class CustomEditorTests {
}
@Test
public void testUninitializedArrayPropertyWithCustomEditor() {
void testUninitializedArrayPropertyWithCustomEditor() {
IndexedTestBean bean = new IndexedTestBean(false);
BeanWrapper bw = new BeanWrapperImpl(bean);
PropertyEditor pe = new CustomNumberEditor(Integer.class, true);
@@ -1383,7 +1383,7 @@ public class CustomEditorTests {
}
@Test
public void testArrayToArrayConversion() throws PropertyVetoException {
void testArrayToArrayConversion() throws PropertyVetoException {
IndexedTestBean tb = new IndexedTestBean();
BeanWrapper bw = new BeanWrapperImpl(tb);
bw.registerCustomEditor(TestBean.class, new PropertyEditorSupport() {
@@ -1399,7 +1399,7 @@ public class CustomEditorTests {
}
@Test
public void testArrayToStringConversion() throws PropertyVetoException {
void testArrayToStringConversion() throws PropertyVetoException {
TestBean tb = new TestBean();
BeanWrapper bw = new BeanWrapperImpl(tb);
bw.registerCustomEditor(String.class, new PropertyEditorSupport() {
@@ -1408,16 +1408,16 @@ public class CustomEditorTests {
setValue("-" + text + "-");
}
});
bw.setPropertyValue("name", new String[] {"a", "b"});
bw.setPropertyValue("name", new String[]{"a", "b"});
assertThat(tb.getName()).isEqualTo("-a,b-");
}
@Test
public void testClassArrayEditorSunnyDay() throws Exception {
void testClassArrayEditorSunnyDay() throws Exception {
ClassArrayEditor classArrayEditor = new ClassArrayEditor();
classArrayEditor.setAsText("java.lang.String,java.util.HashMap");
Class<?>[] classes = (Class<?>[]) classArrayEditor.getValue();
assertThat(classes.length).isEqualTo(2);
assertThat(classes).hasSize(2);
assertThat(classes[0]).isEqualTo(String.class);
assertThat(classes[1]).isEqualTo(HashMap.class);
assertThat(classArrayEditor.getAsText()).isEqualTo("java.lang.String,java.util.HashMap");
@@ -1426,11 +1426,11 @@ public class CustomEditorTests {
}
@Test
public void testClassArrayEditorSunnyDayWithArrayTypes() throws Exception {
void testClassArrayEditorSunnyDayWithArrayTypes() throws Exception {
ClassArrayEditor classArrayEditor = new ClassArrayEditor();
classArrayEditor.setAsText("java.lang.String[],java.util.Map[],int[],float[][][]");
Class<?>[] classes = (Class<?>[]) classArrayEditor.getValue();
assertThat(classes.length).isEqualTo(4);
assertThat(classes).hasSize(4);
assertThat(classes[0]).isEqualTo(String[].class);
assertThat(classes[1]).isEqualTo(Map[].class);
assertThat(classes[2]).isEqualTo(int[].class);
@@ -1441,31 +1441,31 @@ public class CustomEditorTests {
}
@Test
public void testClassArrayEditorSetAsTextWithNull() throws Exception {
void testClassArrayEditorSetAsTextWithNull() throws Exception {
ClassArrayEditor editor = new ClassArrayEditor();
editor.setAsText(null);
assertThat(editor.getValue()).isNull();
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getAsText()).isEmpty();
}
@Test
public void testClassArrayEditorSetAsTextWithEmptyString() throws Exception {
void testClassArrayEditorSetAsTextWithEmptyString() throws Exception {
ClassArrayEditor editor = new ClassArrayEditor();
editor.setAsText("");
assertThat(editor.getValue()).isNull();
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getAsText()).isEmpty();
}
@Test
public void testClassArrayEditorSetAsTextWithWhitespaceString() throws Exception {
void testClassArrayEditorSetAsTextWithWhitespaceString() throws Exception {
ClassArrayEditor editor = new ClassArrayEditor();
editor.setAsText("\n");
assertThat(editor.getValue()).isNull();
assertThat(editor.getAsText()).isEqualTo("");
assertThat(editor.getAsText()).isEmpty();
}
@Test
public void testCharsetEditor() throws Exception {
void testCharsetEditor() throws Exception {
CharsetEditor editor = new CharsetEditor();
String name = "UTF-8";
editor.setAsText(name);
@@ -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,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.testfixture.beans;
/**
@@ -65,4 +66,5 @@ public class DummyBean {
public TestBean getSpouse() {
return spouse;
}
}
@@ -1,9 +1,9 @@
description = "Spring Context Indexer"
dependencies {
testCompile(project(":spring-context"))
testCompile("javax.inject:javax.inject")
testCompile("javax.annotation:javax.annotation-api")
testCompile("javax.transaction:javax.transaction-api")
testCompile("org.eclipse.persistence:javax.persistence")
testImplementation(project(":spring-context"))
testImplementation("javax.inject:javax.inject")
testImplementation("javax.annotation:javax.annotation-api")
testImplementation("javax.transaction:javax.transaction-api")
testImplementation("org.eclipse.persistence:javax.persistence")
}
@@ -1,9 +1,9 @@
description = "Spring Context Support"
dependencies {
compile(project(":spring-beans"))
compile(project(":spring-context"))
compile(project(":spring-core"))
api(project(":spring-beans"))
api(project(":spring-context"))
api(project(":spring-core"))
optional(project(":spring-jdbc")) // for Quartz support
optional(project(":spring-tx")) // for Quartz support
optional("javax.activation:javax.activation-api")
@@ -14,18 +14,18 @@ dependencies {
optional("org.quartz-scheduler:quartz")
optional("org.codehaus.fabric3.api:commonj")
optional("org.freemarker:freemarker")
testCompile(project(":spring-context"))
testCompile(testFixtures(project(":spring-beans")))
testCompile(testFixtures(project(":spring-context")))
testCompile(testFixtures(project(":spring-core")))
testCompile(testFixtures(project(":spring-tx")))
testCompile("org.hsqldb:hsqldb")
testCompile("org.hibernate:hibernate-validator")
testCompile("javax.annotation:javax.annotation-api")
testRuntime("org.ehcache:jcache")
testRuntime("org.ehcache:ehcache")
testRuntime("org.glassfish:javax.el")
testRuntime("com.sun.mail:javax.mail")
testImplementation(project(":spring-context"))
testImplementation(testFixtures(project(":spring-beans")))
testImplementation(testFixtures(project(":spring-context")))
testImplementation(testFixtures(project(":spring-core")))
testImplementation(testFixtures(project(":spring-tx")))
testImplementation("org.hsqldb:hsqldb")
testImplementation("org.hibernate:hibernate-validator")
testImplementation("javax.annotation:javax.annotation-api")
testRuntimeOnly("org.ehcache:jcache")
testRuntimeOnly("org.ehcache:ehcache")
testRuntimeOnly("org.glassfish:javax.el")
testRuntimeOnly("com.sun.mail:javax.mail")
testFixturesApi("org.junit.jupiter:junit-jupiter-api")
testFixturesImplementation("org.assertj:assertj-core")
testFixturesImplementation("org.mockito:mockito-core")
@@ -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.
@@ -138,7 +138,7 @@ abstract class AbstractJCacheOperation<A extends Annotation> implements JCacheOp
@Override
public String toString() {
return getOperationDescription().append("]").toString();
return getOperationDescription().append(']').toString();
}
/**
@@ -148,7 +148,7 @@ abstract class AbstractJCacheOperation<A extends Annotation> implements JCacheOp
protected StringBuilder getOperationDescription() {
StringBuilder result = new StringBuilder();
result.append(getClass().getSimpleName());
result.append("[");
result.append('[');
result.append(this.methodDetails);
return result;
}
@@ -896,7 +896,7 @@ public class MimeMessageHelper {
* <p><b>NOTE:</b> Invoke {@code addInline} <i>after</i> {@link #setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "&lt;myId&gt;".
* in the body part, surrounded by angle brackets: e.g. "myId" &rarr; "&lt;myId&gt;".
* Can be referenced in HTML source via src="cid:myId" expressions.
* @param dataSource the {@code javax.activation.DataSource} to take
* the content from, determining the InputStream and the content type
@@ -923,7 +923,7 @@ public class MimeMessageHelper {
* <p><b>NOTE:</b> Invoke {@code addInline} <i>after</i> {@link #setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "&lt;myId&gt;".
* in the body part, surrounded by angle brackets: e.g. "myId" &rarr; "&lt;myId&gt;".
* Can be referenced in HTML source via src="cid:myId" expressions.
* @param file the File resource to take the content from
* @throws MessagingException in case of errors
@@ -950,7 +950,7 @@ public class MimeMessageHelper {
* <p><b>NOTE:</b> Invoke {@code addInline} <i>after</i> {@link #setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "&lt;myId&gt;".
* in the body part, surrounded by angle brackets: e.g. "myId" &rarr; "&lt;myId&gt;".
* Can be referenced in HTML source via src="cid:myId" expressions.
* @param resource the resource to take the content from
* @throws MessagingException in case of errors
@@ -976,7 +976,7 @@ public class MimeMessageHelper {
* <p><b>NOTE:</b> Invoke {@code addInline} <i>after</i> {@code setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "&lt;myId&gt;".
* in the body part, surrounded by angle brackets: e.g. "myId" &rarr; "&lt;myId&gt;".
* Can be referenced in HTML source via src="cid:myId" expressions.
* @param inputStreamSource the resource to take the content from
* @param contentType the content type to use for the element
+19 -19
View File
@@ -4,10 +4,10 @@ apply plugin: "groovy"
apply plugin: "kotlin"
dependencies {
compile(project(":spring-aop"))
compile(project(":spring-beans"))
compile(project(":spring-core"))
compile(project(":spring-expression"))
api(project(":spring-aop"))
api(project(":spring-beans"))
api(project(":spring-core"))
api(project(":spring-expression"))
optional(project(":spring-instrument"))
optional("javax.annotation:javax.annotation-api")
optional("javax.ejb:javax.ejb-api")
@@ -26,22 +26,22 @@ dependencies {
optional("org.jetbrains.kotlin:kotlin-reflect")
optional("org.jetbrains.kotlin:kotlin-stdlib")
optional("org.reactivestreams:reactive-streams")
testCompile(testFixtures(project(":spring-aop")))
testCompile(testFixtures(project(":spring-beans")))
testCompile(testFixtures(project(":spring-core")))
testCompile("io.projectreactor:reactor-core")
testCompile("org.codehaus.groovy:groovy-jsr223")
testCompile("org.codehaus.groovy:groovy-test")
testCompile("org.codehaus.groovy:groovy-xml")
testCompile("org.apache.commons:commons-pool2")
testCompile("javax.inject:javax.inject-tck")
testCompile("org.awaitility:awaitility")
testRuntime("javax.xml.bind:jaxb-api")
testRuntime("org.glassfish:javax.el")
testImplementation(testFixtures(project(":spring-aop")))
testImplementation(testFixtures(project(":spring-beans")))
testImplementation(testFixtures(project(":spring-core")))
testImplementation("io.projectreactor:reactor-core")
testImplementation("org.codehaus.groovy:groovy-jsr223")
testImplementation("org.codehaus.groovy:groovy-test")
testImplementation("org.codehaus.groovy:groovy-xml")
testImplementation("org.apache.commons:commons-pool2")
testImplementation("org.awaitility:awaitility")
testImplementation("javax.inject:javax.inject-tck")
testRuntimeOnly("javax.xml.bind:jaxb-api")
testRuntimeOnly("org.glassfish:javax.el")
// Substitute for javax.management:jmxremote_optional:1.0.1_04 (not available on Maven Central)
testRuntime("org.glassfish.external:opendmk_jmxremote_optional_jar")
testRuntime("org.javamoney:moneta")
testRuntime("org.junit.vintage:junit-vintage-engine") // for @Inject TCK
testRuntimeOnly("org.glassfish.external:opendmk_jmxremote_optional_jar")
testRuntimeOnly("org.javamoney:moneta")
testRuntimeOnly("org.junit.vintage:junit-vintage-engine") // for @Inject TCK
testFixturesApi("org.junit.jupiter:junit-jupiter-api")
testFixturesImplementation(testFixtures(project(":spring-beans")))
testFixturesImplementation("com.google.code.findbugs:jsr305")
@@ -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.
@@ -38,9 +38,11 @@ import org.springframework.core.annotation.AliasFor;
* replace the default one (see {@link #keyGenerator}).
*
* <p>If no value is found in the cache for the computed key, the target method
* will be invoked and the returned value stored in the associated cache. Note
* that Java8's {@code Optional} return types are automatically handled and its
* content is stored in the cache if present.
* will be invoked and the returned value will be stored in the associated cache.
* Note that {@link java.util.Optional} return types are unwrapped automatically.
* If an {@code Optional} value is {@linkplain java.util.Optional#isPresent()
* present}, it will be stored in the associated cache. If an {@code Optional}
* value is not present, {@code null} will be stored in the associated cache.
*
* <p>This annotation may be used as a <em>meta-annotation</em> to create custom
* <em>composed annotations</em> with attribute overrides.
@@ -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.
@@ -244,17 +244,21 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
private static void registerCacheAspect(Element element, ParserContext parserContext) {
if (!parserContext.getRegistry().containsBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)) {
Object eleSource = parserContext.extractSource(element);
RootBeanDefinition def = new RootBeanDefinition();
def.setBeanClassName(JCACHE_ASPECT_CLASS_NAME);
def.setFactoryMethodName("aspectOf");
BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, eleSource);
String sourceName =
parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
def.getPropertyValues().add("cacheOperationSource", new RuntimeBeanReference(sourceName));
Object source = parserContext.extractSource(element);
parserContext.registerBeanComponent(new BeanComponentDefinition(sourceDef, sourceName));
parserContext.registerBeanComponent(new BeanComponentDefinition(def, CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME));
BeanDefinition cacheOperationSourceDef = createJCacheOperationSourceBeanDefinition(element, source);
String cacheOperationSourceName = parserContext.getReaderContext().registerWithGeneratedName(cacheOperationSourceDef);
RootBeanDefinition jcacheAspectDef = new RootBeanDefinition();
jcacheAspectDef.setBeanClassName(JCACHE_ASPECT_CLASS_NAME);
jcacheAspectDef.setFactoryMethodName("aspectOf");
jcacheAspectDef.getPropertyValues().add("cacheOperationSource", new RuntimeBeanReference(cacheOperationSourceName));
parserContext.getRegistry().registerBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME, jcacheAspectDef);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
compositeDef.addNestedComponent(new BeanComponentDefinition(cacheOperationSourceDef, cacheOperationSourceName));
compositeDef.addNestedComponent(new BeanComponentDefinition(jcacheAspectDef, CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME));
parserContext.registerComponent(compositeDef);
}
}

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