Compare commits

..

1 Commits

Author SHA1 Message Date
Spring Buildmaster d9a9686b45 Release v5.3.4 2021-02-16 10:43:46 +00:00
621 changed files with 5114 additions and 12103 deletions
-3
View File
@@ -41,6 +41,3 @@ out
test-output
atlassian-ide-plugin.xml
.gradletasknamecache
# VS Code
.vscode/
+7 -4
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 `main` branch and submit pull requests against it
1. Always check out the `master` 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.
@@ -125,7 +125,10 @@ The reference documentation is in the [src/docs/asciidoc](src/docs/asciidoc) dir
edit source files, and submit directly from GitHub.
When making changes locally, execute `./gradlew asciidoctor` and then browse the result under
`build/docs/ref-docs/html5/index.html`.
`build/asciidoc/html5/index.html`.
Asciidoctor also supports live editing. For more details see
[AsciiDoc Tooling](https://docs.asciidoctor.org/asciidoctor/latest/tooling/).
Asciidoctor also supports live editing. For more details read
[Editing AsciiDoc with Live Preview](https://asciidoctor.org/docs/editing-asciidoc-with-live-preview/).
Note that if you choose the
[System Monitor](https://asciidoctor.org/docs/editing-asciidoc-with-live-preview/#using-a-system-monitor)
option, you can find a Guardfile under `src/docs/asciidoc`.
-4
View File
@@ -25,10 +25,6 @@ See the [Micro-Benchmarks](https://github.com/spring-projects/spring-framework/w
See the [Build from Source](https://github.com/spring-projects/spring-framework/wiki/Build-from-Source) Wiki page and the [CONTRIBUTING.md](CONTRIBUTING.md) file.
## Continuous Integration Builds
Information regarding CI builds can be found in the [Spring Framework Concourse pipeline](ci/README.adoc) documentation.
## Stay in Touch
Follow [@SpringCentral](https://twitter.com/springcentral), [@SpringFramework](https://twitter.com/springframework), and its [team members](https://twitter.com/springframework/lists/team/members) on Twitter. In-depth articles can be found at [The Spring Blog](https://spring.io/blog/), and releases are announced via our [news feed](https://spring.io/blog/category/news).
+55 -51
View File
@@ -1,7 +1,7 @@
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.21' apply false
id 'org.jetbrains.kotlin.jvm' version '1.4.30' 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'
@@ -9,9 +9,8 @@ plugins {
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.21" apply false
id "org.unbroken-dome.xjc" version '2.0.0' apply false
id "me.champeau.gradle.jmh" version "0.5.2" apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.4.30" apply false
}
ext {
@@ -27,19 +26,18 @@ configure(allprojects) { project ->
dependencyManagement {
imports {
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.4"
mavenBom "io.netty:netty-bom:4.1.65.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.9"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10"
mavenBom "io.rsocket:rsocket-bom:1.1.1"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.43.v20210629"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.21"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.1"
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.1"
mavenBom "org.junit:junit-bom:5.7.2"
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.1"
mavenBom "io.netty:netty-bom:4.1.59.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.4"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR8"
mavenBom "io.rsocket:rsocket-bom:1.1.0"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.36.v20210114"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.4.30"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.4.2"
mavenBom "org.junit:junit-bom:5.7.1"
}
dependencies {
dependencySet(group: 'org.apache.logging.log4j', version: '2.14.1') {
dependencySet(group: 'org.apache.logging.log4j', version: '2.14.0') {
entry 'log4j-api'
entry 'log4j-core'
entry 'log4j-jul'
@@ -51,12 +49,12 @@ configure(allprojects) { project ->
}
dependency "com.google.code.findbugs:jsr305:3.0.2"
dependencySet(group: 'org.aspectj', version: '1.9.7') {
dependencySet(group: 'org.aspectj', version: '1.9.6') {
entry 'aspectjrt'
entry 'aspectjtools'
entry 'aspectjweaver'
}
dependencySet(group: 'org.codehaus.groovy', version: '3.0.8') {
dependencySet(group: 'org.codehaus.groovy', version: '3.0.7') {
entry 'groovy'
entry 'groovy-jsr223'
entry 'groovy-templates' // requires findbugs for warning-free compilation
@@ -67,18 +65,18 @@ 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.reactivex.rxjava3:rxjava:3.0.10"
dependency "io.projectreactor.tools:blockhound:1.0.4.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") {
dependency "com.fasterxml:aalto-xml:1.2.2"
dependency("com.fasterxml.woodstox:woodstox-core:6.2.3") {
exclude group: "stax", name: "stax-api"
}
dependency "com.google.code.gson:gson:2.8.7"
dependency "com.google.protobuf:protobuf-java-util:3.17.3"
dependency "com.google.code.gson:gson:2.8.6"
dependency "com.google.protobuf:protobuf-java-util:3.14.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.15") {
exclude group: "xpp3", name: "xpp3_min"
exclude group: "xmlpull", name: "xmlpull"
}
@@ -91,16 +89,20 @@ configure(allprojects) { project ->
entry 'jibx-run'
}
dependency "org.ogce:xpp3:1.1.6"
dependency "org.yaml:snakeyaml:1.29"
dependency "org.yaml:snakeyaml:1.27"
dependencySet(group: 'org.jetbrains.kotlinx', version: '1.0.0') {
entry 'kotlinx-serialization-core'
entry 'kotlinx-serialization-json'
}
dependency "com.h2database:h2:1.4.200"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.1"
dependency "com.github.librepdf:openpdf:1.3.26"
dependency "com.github.ben-manes.caffeine:caffeine:2.8.8"
dependency "com.github.librepdf:openpdf:1.3.25"
dependency "com.rometools:rome:1.15.0"
dependency "commons-io:commons-io:2.5"
dependency "io.vavr:vavr:0.10.3"
dependency "net.sf.jopt-simple:jopt-simple:5.0.4"
dependencySet(group: 'org.apache.activemq', version: '5.16.2') {
dependencySet(group: 'org.apache.activemq', version: '5.16.0') {
entry 'activemq-broker'
entry('activemq-kahadb-store') {
exclude group: "org.springframework", name: "spring-context"
@@ -115,30 +117,30 @@ configure(allprojects) { project ->
}
dependency "org.apache.poi:poi-ooxml:4.1.2"
dependency "org.apache-extras.beanshell:bsh:2.0b6"
dependency "org.freemarker:freemarker:2.3.31"
dependency "org.hsqldb:hsqldb:2.5.2"
dependency "org.freemarker:freemarker:2.3.30"
dependency "org.hsqldb:hsqldb:2.5.1"
dependency "org.quartz-scheduler:quartz:2.3.2"
dependency "org.codehaus.fabric3.api:commonj:1.1.0"
dependency "net.sf.ehcache:ehcache:2.10.6"
dependency "org.ehcache:jcache:1.0.1"
dependency "org.ehcache:ehcache:3.4.0"
dependency "org.hibernate:hibernate-core:5.4.32.Final"
dependency "org.hibernate:hibernate-core:5.4.28.Final"
dependency "org.hibernate:hibernate-validator:6.2.0.Final"
dependency "org.webjars:webjars-locator-core:0.47"
dependency "org.webjars:webjars-locator-core:0.46"
dependency "org.webjars:underscorejs:1.8.3"
dependencySet(group: 'org.apache.tomcat', version: '9.0.50') {
dependencySet(group: 'org.apache.tomcat', version: '9.0.43') {
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.50') {
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.43') {
entry 'tomcat-embed-core'
entry 'tomcat-embed-websocket'
}
dependencySet(group: 'io.undertow', version: '2.2.8.Final') {
dependencySet(group: 'io.undertow', version: '2.2.4.Final') {
entry 'undertow-core'
entry('undertow-websockets-jsr') {
exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec"
@@ -159,11 +161,11 @@ configure(allprojects) { project ->
dependency("org.apache.httpcomponents:httpasyncclient:4.1.4") {
exclude group: "commons-logging", name: "commons-logging"
}
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.9"
dependency 'org.apache.httpcomponents.client5:httpclient5:5.0.3'
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.0.3'
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.5"
dependency "org.jruby:jruby:9.2.19.0"
dependency "org.jruby:jruby:9.2.13.0"
dependency "org.python:jython-standalone:2.7.1"
dependency "org.mozilla:rhino:1.7.11"
@@ -186,28 +188,28 @@ configure(allprojects) { project ->
dependency("de.bechte.junit:junit-hierarchicalcontextrunner:4.12.1") {
exclude group: "junit", name: "junit"
}
dependency "org.testng:testng:7.4.0"
dependency "org.testng:testng:7.3.0"
dependency "org.hamcrest:hamcrest:2.1"
dependency "org.awaitility:awaitility:3.1.6"
dependency "org.assertj:assertj-core:3.20.2"
dependency "org.assertj:assertj-core:3.19.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: '3.7.7') {
entry('mockito-core') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
entry 'mockito-junit-jupiter'
}
dependency "io.mockk:mockk:1.11.0"
dependency "io.mockk:mockk:1.10.2"
dependency("net.sourceforge.htmlunit:htmlunit:2.51.0") {
dependency("net.sourceforge.htmlunit:htmlunit:2.47.1") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:htmlunit-driver:2.51.0") {
dependency("org.seleniumhq.selenium:htmlunit-driver:2.47.1") {
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.4.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.9"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.8"
dependency "org.javamoney:moneta:1.3"
dependency "com.sun.activation:javax.activation:1.2.0"
@@ -307,21 +309,23 @@ configure([rootProject] + javaProjects) { project ->
apply plugin: "java-test-fixtures"
apply plugin: "checkstyle"
apply plugin: 'org.springframework.build.compile'
apply from: "${rootDir}/gradle/toolchains.gradle"
apply from: "${rootDir}/gradle/custom-java-home.gradle"
apply from: "${rootDir}/gradle/ide.gradle"
pluginManager.withPlugin("kotlin") {
apply plugin: "org.jetbrains.dokka"
compileKotlin {
kotlinOptions {
jvmTarget = "1.8"
languageVersion = "1.3"
apiVersion = "1.3"
freeCompilerArgs = ["-Xjsr305=strict", "-Xsuppress-version-warnings", "-Xopt-in=kotlin.RequiresOptIn"]
freeCompilerArgs = ["-Xjsr305=strict"]
allWarningsAsErrors = true
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs = ["-Xjsr305=strict"]
}
}
@@ -336,7 +340,7 @@ configure([rootProject] + javaProjects) { project ->
}
checkstyle {
toolVersion = "8.44"
toolVersion = "8.39"
configDirectory.set(rootProject.file("src/checkstyle"))
}
@@ -375,10 +379,10 @@ configure([rootProject] + javaProjects) { project ->
"https://fasterxml.github.io/jackson-core/javadoc/2.10/",
"https://fasterxml.github.io/jackson-databind/javadoc/2.10/",
"https://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.10/",
"https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/",
"https://hc.apache.org/httpcomponents-client-ga/httpclient/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/"
"https://junit.org/junit5/docs/5.7.1/api/"
] as String[]
}
+8 -2
View File
@@ -8,10 +8,16 @@ They are declared in the `build.gradle` file in this folder.
### Compiler conventions
The `org.springframework.build.compile` plugin applies the Java compiler conventions to the build.
By default, the build compiles sources with Java `1.8` source and target compatibility.
You can test a different source compatibility version on the CLI with a project property like:
```
./gradlew test -PjavaSourceVersion=11
```
## Build Plugins
### Optional dependencies
## Optional dependencies
The `org.springframework.build.optional-dependencies` plugin creates a new `optional`
Gradle configuration - it adds the dependencies to the project's compile and runtime classpath
@@ -19,7 +25,7 @@ but doesn't affect the classpath of dependent projects.
This plugin does not provide a `provided` configuration, as the native `compileOnly` and `testCompileOnly`
configurations are preferred.
### API Diff
## API Diff
This plugin uses the [Gradle JApiCmp](https://github.com/melix/japicmp-gradle-plugin) plugin
to generate API Diff reports for each Spring Framework module. This plugin is applied once on the root
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,21 +20,31 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.gradle.api.JavaVersion;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.plugins.JavaLibraryPlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.compile.JavaCompile;
/**
* {@link Plugin} that applies conventions for compiling Java sources in Spring Framework.
* <p>One can override the default Java source compatibility version
* with a dedicated property on the CLI: {@code "./gradlew test -PjavaSourceVersion=11"}.
*
* @author Brian Clozel
* @author Sam Brannen
*/
public class CompilerConventionsPlugin implements Plugin<Project> {
/**
* The project property that can be used to switch the Java source
* compatibility version for building source and test classes.
*/
public static final String JAVA_SOURCE_VERSION_PROPERTY = "javaSourceVersion";
public static final JavaVersion DEFAULT_COMPILER_VERSION = JavaVersion.VERSION_1_8;
private static final List<String> COMPILER_ARGS;
private static final List<String> TEST_COMPILER_ARGS;
@@ -59,7 +69,7 @@ public class CompilerConventionsPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getPlugins().withType(JavaLibraryPlugin.class, javaPlugin -> applyJavaCompileConventions(project));
project.getPlugins().withType(JavaPlugin.class, javaPlugin -> applyJavaCompileConventions(project));
}
/**
@@ -69,6 +79,15 @@ public class CompilerConventionsPlugin implements Plugin<Project> {
*/
private void applyJavaCompileConventions(Project project) {
JavaPluginConvention java = project.getConvention().getPlugin(JavaPluginConvention.class);
if (project.hasProperty(JAVA_SOURCE_VERSION_PROPERTY)) {
JavaVersion javaSourceVersion = JavaVersion.toVersion(project.property(JAVA_SOURCE_VERSION_PROPERTY));
java.setSourceCompatibility(javaSourceVersion);
}
else {
java.setSourceCompatibility(DEFAULT_COMPILER_VERSION);
}
java.setTargetCompatibility(DEFAULT_COMPILER_VERSION);
project.getTasks().withType(JavaCompile.class)
.matching(compileTask -> compileTask.getName().equals(JavaPlugin.COMPILE_JAVA_TASK_NAME))
.forEach(compileTask -> {
+3 -9
View File
@@ -1,8 +1,7 @@
== Spring Framework Concourse pipeline
The Spring Framework uses https://concourse-ci.org/[Concourse] for its CI build and other automated tasks.
The Spring team has a dedicated Concourse instance available at https://ci.spring.io with a build pipeline
for https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x[Spring Framework 5.3.x].
The Spring Framework is using https://concourse-ci.org/[Concourse] for its CI build and other automated tasks.
The Spring team has a dedicated Concourse instance available at https://ci.spring.io.
=== Setting up your development environment
@@ -26,17 +25,13 @@ spring https://ci.spring.io spring-framework Wed, 25 Mar 20
----
=== Pipeline configuration and structure
The build pipelines are described in `pipeline.yml` file.
This file is listing Concourse resources, i.e. build inputs and outputs such as container images, artifact repositories, source repositories, notification services, etc.
It also describes jobs (a job is a sequence of inputs, tasks and outputs); jobs are organized by groups.
The `pipeline.yml` definition contains `((parameters))` which are loaded from the `parameters.yml` file or from our https://docs.cloudfoundry.org/credhub/[credhub instance].
You'll find in this folder the following resources:
* `pipeline.yml` the build pipeline
* `parameters.yml` the build parameters used for the pipeline
* `images/` holds the container images definitions used in this pipeline
@@ -46,7 +41,6 @@ You'll find in this folder the following resources:
=== Updating the build pipeline
Updating files on the repository is not enough to update the build pipeline, as changes need to be applied.
The pipeline can be deployed using the following command:
[source]
@@ -54,4 +48,4 @@ The pipeline can be deployed using the following command:
$ fly -t spring set-pipeline -p spring-framework-5.3.x -c ci/pipeline.yml -l ci/parameters.yml
----
NOTE: This assumes that you have credhub integration configured with the appropriate secrets.
NOTE: This assumes that you have credhub integration configured with the appropriate secrets.
+3 -4
View File
@@ -1,10 +1,9 @@
logging:
level:
io.spring.concourse: DEBUG
distribute:
optional-deployments:
- '.*\.zip'
spring:
main:
banner-mode: off
sonatype:
exclude:
- 'build-info\.json'
- '.*\.zip'
+7 -14
View File
@@ -12,27 +12,20 @@ ln -fs /usr/share/zoneinfo/UTC /etc/localtime
dpkg-reconfigure --frontend noninteractive tzdata
rm -rf /var/lib/apt/lists/*
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/concourse-java.sh > /opt/concourse-java.sh
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.3/concourse-java.sh > /opt/concourse-java.sh
curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.3.2/concourse-release-scripts-0.3.2.jar
curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.2.1/concourse-release-scripts-0.2.1.jar
###########################################################
# JAVA
###########################################################
JDK_URL=$( ./get-jdk-url.sh $1 )
mkdir -p /opt/openjdk
pushd /opt/openjdk > /dev/null
for jdk in java8 java11 java15
do
JDK_URL=$( /get-jdk-url.sh $jdk )
mkdir $jdk
pushd $jdk > /dev/null
curl -L ${JDK_URL} | tar zx --strip-components=1
test -f bin/java
test -f bin/javac
popd > /dev/null
done
popd
cd /opt/openjdk
curl -L ${JDK_URL} | tar zx --strip-components=1
test -f /opt/openjdk/bin/java
test -f /opt/openjdk/bin/javac
###########################################################
# GRADLE ENTERPRISE
@@ -4,8 +4,5 @@ ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
RUN ./setup.sh java8
ENV JAVA_HOME /opt/openjdk/java8
ENV JDK11 /opt/openjdk/java11
ENV JDK15 /opt/openjdk/java15
ENV JAVA_HOME /opt/openjdk
ENV PATH $JAVA_HOME/bin:$PATH
@@ -0,0 +1,8 @@
FROM ubuntu:focal-20210119
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
RUN ./setup.sh java11
ENV JAVA_HOME /opt/openjdk
ENV PATH $JAVA_HOME/bin:$PATH
@@ -0,0 +1,8 @@
FROM ubuntu:focal-20210119
ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
RUN ./setup.sh java15
ENV JAVA_HOME /opt/openjdk
ENV PATH $JAVA_HOME/bin:$PATH
+4 -3
View File
@@ -5,9 +5,10 @@ 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"
milestone: "5.3.x"
branch: "master"
build-name: "spring-framework"
pipeline-name: "spring-framework"
concourse-url: "https://ci.spring.io"
task-timeout: 1h00m
bintray-subject: "spring"
bintray-repo: "jars"
task-timeout: 1h00m
+88 -109
View File
@@ -1,29 +1,21 @@
anchors:
git-repo-resource-source: &git-repo-resource-source
uri: ((github-repo))
username: ((github-username))
password: ((github-password))
branch: ((branch))
gradle-enterprise-task-params: &gradle-enterprise-task-params
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
sonatype-task-params: &sonatype-task-params
SONATYPE_USERNAME: ((sonatype-username))
SONATYPE_PASSWORD: ((sonatype-password))
SONATYPE_URL: ((sonatype-url))
SONATYPE_STAGING_PROFILE_ID: ((sonatype-staging-profile-id))
artifactory-task-params: &artifactory-task-params
ARTIFACTORY_SERVER: ((artifactory-server))
ARTIFACTORY_USERNAME: ((artifactory-username))
ARTIFACTORY_PASSWORD: ((artifactory-password))
build-project-task-params: &build-project-task-params
BRANCH: ((branch))
<<: *gradle-enterprise-task-params
bintray-task-params: &bintray-task-params
BINTRAY_SUBJECT: ((bintray-subject))
BINTRAY_REPO: ((bintray-repo))
BINTRAY_USERNAME: ((bintray-username))
BINTRAY_API_KEY: ((bintray-api-key))
docker-resource-source: &docker-resource-source
username: ((docker-hub-username))
password: ((docker-hub-password))
tag: ((milestone))
tag: 5.3.x
gradle-enterprise-task-params: &gradle-enterprise-task-params
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
slack-fail-params: &slack-fail-params
text: >
:concourse-failed: <https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}|${BUILD_PIPELINE_NAME} ${BUILD_JOB_NAME} failed!>
@@ -32,6 +24,9 @@ anchors:
silent: true
icon_emoji: ":concourse:"
username: concourse-ci
sonatype-task-params: &sonatype-task-params
SONATYPE_USER_TOKEN: ((sonatype-user-token))
SONATYPE_PASSWORD_TOKEN: ((sonatype-user-token-password))
changelog-task-params: &changelog-task-params
name: generated-changelog/tag
tag: generated-changelog/tag
@@ -45,28 +40,27 @@ resource_types:
type: registry-image
source:
repository: springio/artifactory-resource
tag: 0.0.13
tag: 0.0.12
- name: github-status-resource
type: registry-image
source:
repository: dpb587/github-status-resource
tag: master
- name: pull-request
type: registry-image
source:
repository: teliaoss/github-pr-resource
tag: v0.23.0
- name: slack-notification
type: registry-image
source:
repository: cfcommunity/slack-notification-resource
tag: latest
resources:
- name: git-repo
type: git
icon: github
source:
<<: *git-repo-resource-source
uri: ((github-repo))
username: ((github-username))
password: ((github-password))
branch: ((branch))
- name: every-morning
type: time
icon: alarm
@@ -81,12 +75,24 @@ resources:
uri: ((github-repo))
branch: ((branch))
paths: ["ci/images/*"]
- name: ci-image
- name: spring-framework-ci-image
type: docker-image
icon: docker
source:
<<: *docker-resource-source
repository: ((docker-hub-organization))/spring-framework-ci
repository: ((docker-hub-organization))/spring-framework-ci-image
- name: spring-framework-jdk11-ci-image
type: docker-image
icon: docker
source:
<<: *docker-resource-source
repository: ((docker-hub-organization))/spring-framework-jdk11-ci-image
- name: spring-framework-jdk15-ci-image
type: docker-image
icon: docker
source:
<<: *docker-resource-source
repository: ((docker-hub-organization))/spring-framework-jdk15-ci-image
- name: artifactory-repo
type: artifactory-resource
icon: package-variant
@@ -95,14 +101,6 @@ resources:
username: ((artifactory-username))
password: ((artifactory-password))
build_name: ((build-name))
- name: git-pull-request
type: pull-request
icon: source-pull
source:
access_token: ((github-ci-pull-request-token))
repository: ((github-repo-name))
base_branch: ((branch))
ignore_paths: ["ci/*"]
- name: repo-status-build
type: github-status-resource
icon: eye-check-outline
@@ -149,33 +147,43 @@ resources:
repository: spring-framework
access_token: ((github-ci-release-token))
pre_release: false
jobs:
- name: build-ci-images
- name: build-spring-framework-ci-images
plan:
- get: ci-images-git-repo
trigger: true
- in_parallel:
- put: ci-image
- put: spring-framework-ci-image
params:
build: ci-images-git-repo/ci/images
dockerfile: ci-images-git-repo/ci/images/ci-image/Dockerfile
dockerfile: ci-images-git-repo/ci/images/spring-framework-ci-image/Dockerfile
- put: spring-framework-jdk11-ci-image
params:
build: ci-images-git-repo/ci/images
dockerfile: ci-images-git-repo/ci/images/spring-framework-jdk11-ci-image/Dockerfile
- put: spring-framework-jdk15-ci-image
params:
build: ci-images-git-repo/ci/images
dockerfile: ci-images-git-repo/ci/images/spring-framework-jdk15-ci-image/Dockerfile
- name: build
serial: true
public: true
plan:
- get: ci-image
- get: spring-framework-ci-image
- get: git-repo
trigger: true
- put: repo-status-build
params: { state: "pending", commit: "git-repo" }
- do:
- task: build-project
image: ci-image
file: git-repo/ci/tasks/build-project.yml
privileged: true
timeout: ((task-timeout))
image: spring-framework-ci-image
file: git-repo/ci/tasks/build-project.yml
params:
<<: *build-project-task-params
BRANCH: ((branch))
<<: *gradle-enterprise-task-params
on_failure:
do:
- put: repo-status-build
@@ -187,8 +195,6 @@ jobs:
params: { state: "success", commit: "git-repo" }
- put: artifactory-repo
params: &artifactory-params
signing_key: ((signing-key))
signing_passphrase: ((signing-passphrase))
repo: libs-snapshot-local
folder: distribution-repository
build_uri: "https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}"
@@ -220,7 +226,7 @@ jobs:
serial: true
public: true
plan:
- get: ci-image
- get: spring-framework-jdk11-ci-image
- get: git-repo
- get: every-morning
trigger: true
@@ -228,13 +234,13 @@ jobs:
params: { state: "pending", commit: "git-repo" }
- do:
- task: check-project
image: ci-image
file: git-repo/ci/tasks/check-project.yml
privileged: true
timeout: ((task-timeout))
image: spring-framework-jdk11-ci-image
file: git-repo/ci/tasks/check-project.yml
params:
TEST_TOOLCHAIN: 11
<<: *build-project-task-params
BRANCH: ((branch))
<<: *gradle-enterprise-task-params
on_failure:
do:
- put: repo-status-jdk11-build
@@ -248,21 +254,21 @@ jobs:
serial: true
public: true
plan:
- get: ci-image
- get: spring-framework-jdk15-ci-image
- get: git-repo
- get: every-morning
trigger: true
- put: repo-status-jdk15-build
params: { state: "pending", commit: "git-repo" }
- do:
- task: check-project
image: ci-image
file: git-repo/ci/tasks/check-project.yml
privileged: true
timeout: ((task-timeout))
params:
TEST_TOOLCHAIN: 15
<<: *build-project-task-params
- task: check-project
privileged: true
timeout: ((task-timeout))
image: spring-framework-jdk15-ci-image
file: git-repo/ci/tasks/check-project.yml
params:
BRANCH: ((branch))
<<: *gradle-enterprise-task-params
on_failure:
do:
- put: repo-status-jdk15-build
@@ -272,45 +278,14 @@ jobs:
<<: *slack-fail-params
- put: repo-status-jdk15-build
params: { state: "success", commit: "git-repo" }
- name: build-pull-requests
serial: true
public: true
plan:
- get: ci-image
- get: git-repo
resource: git-pull-request
trigger: true
version: every
- do:
- put: git-pull-request
params:
path: git-repo
status: pending
- task: build-pr
image: ci-image
file: git-repo/ci/tasks/build-pr.yml
privileged: true
timeout: ((task-timeout))
params:
<<: *build-project-task-params
on_success:
put: git-pull-request
params:
path: git-repo
status: success
on_failure:
put: git-pull-request
params:
path: git-repo
status: failure
- name: stage-milestone
serial: true
plan:
- get: ci-image
- get: spring-framework-ci-image
- get: git-repo
trigger: false
- task: stage
image: ci-image
image: spring-framework-ci-image
file: git-repo/ci/tasks/stage-version.yml
params:
RELEASE_TYPE: M
@@ -325,7 +300,7 @@ jobs:
- name: promote-milestone
serial: true
plan:
- get: ci-image
- get: spring-framework-ci-image
- get: git-repo
trigger: false
- get: artifactory-repo
@@ -335,7 +310,7 @@ jobs:
download_artifacts: false
save_build_info: true
- task: promote
image: ci-image
image: spring-framework-ci-image
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: M
@@ -351,11 +326,11 @@ jobs:
- name: stage-rc
serial: true
plan:
- get: ci-image
- get: spring-framework-ci-image
- get: git-repo
trigger: false
- task: stage
image: ci-image
image: spring-framework-ci-image
file: git-repo/ci/tasks/stage-version.yml
params:
RELEASE_TYPE: RC
@@ -370,7 +345,7 @@ jobs:
- name: promote-rc
serial: true
plan:
- get: ci-image
- get: spring-framework-ci-image
- get: git-repo
trigger: false
- get: artifactory-repo
@@ -380,7 +355,7 @@ jobs:
download_artifacts: false
save_build_info: true
- task: promote
image: ci-image
image: spring-framework-ci-image
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: RC
@@ -396,11 +371,11 @@ jobs:
- name: stage-release
serial: true
plan:
- get: ci-image
- get: spring-framework-ci-image
- get: git-repo
trigger: false
- task: stage
image: ci-image
image: spring-framework-ci-image
file: git-repo/ci/tasks/stage-version.yml
params:
RELEASE_TYPE: RELEASE
@@ -415,26 +390,26 @@ jobs:
- name: promote-release
serial: true
plan:
- get: ci-image
- get: spring-framework-ci-image
- get: git-repo
trigger: false
- get: artifactory-repo
trigger: false
passed: [stage-release]
params:
download_artifacts: true
download_artifacts: false
save_build_info: true
- task: promote
image: ci-image
image: spring-framework-ci-image
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: RELEASE
<<: *artifactory-task-params
<<: *sonatype-task-params
- name: create-github-release
<<: *bintray-task-params
- name: sync-to-maven-central
serial: true
plan:
- get: ci-image
- get: spring-framework-ci-image
- get: git-repo
- get: artifactory-repo
trigger: true
@@ -442,6 +417,12 @@ jobs:
params:
download_artifacts: false
save_build_info: true
- task: sync-to-maven-central
image: spring-framework-ci-image
file: git-repo/ci/tasks/sync-to-maven-central.yml
params:
<<: *bintray-task-params
<<: *sonatype-task-params
- task: generate-changelog
file: git-repo/ci/tasks/generate-changelog.yml
params:
@@ -455,8 +436,6 @@ groups:
- name: "builds"
jobs: ["build", "jdk11-build", "jdk15-build"]
- name: "releases"
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"]
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone","promote-rc", "promote-release", "sync-to-maven-central"]
- name: "ci-images"
jobs: ["build-ci-images"]
- name: "pull-requests"
jobs: [ "build-pull-requests" ]
jobs: ["build-spring-framework-ci-images"]
-8
View File
@@ -1,8 +0,0 @@
#!/bin/bash
set -e
source $(dirname $0)/common.sh
pushd git-repo > /dev/null
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 check
popd > /dev/null
+1 -2
View File
@@ -4,6 +4,5 @@ set -e
source $(dirname $0)/common.sh
pushd git-repo > /dev/null
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK11,JDK15 \
-PmainToolchain=${MAIN_TOOLCHAIN} -PtestToolchain=${TEST_TOOLCHAIN} --no-daemon --max-workers=4 check
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 check
popd > /dev/null
+1 -1
View File
@@ -2,7 +2,7 @@
set -e
CONFIG_DIR=git-repo/ci/config
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
version=$( cat version/version )
java -jar /github-changelog-generator.jar \
--spring.config.location=${CONFIG_DIR}/changelog-generator.yml \
+2 -4
View File
@@ -6,13 +6,11 @@ CONFIG_DIR=git-repo/ci/config
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
export BUILD_INFO_LOCATION=$(pwd)/artifactory-repo/build-info.json
java -jar /opt/concourse-release-scripts.jar \
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
publishToCentral $RELEASE_TYPE $BUILD_INFO_LOCATION artifactory-repo || { exit 1; }
java -jar /opt/concourse-release-scripts.jar promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
java -jar /opt/concourse-release-scripts.jar \
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
distribute $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
echo "Promotion complete"
echo $version > version/version
-19
View File
@@ -1,19 +0,0 @@
---
platform: linux
inputs:
- name: git-repo
caches:
- path: gradle
params:
BRANCH:
CI: true
GRADLE_ENTERPRISE_ACCESS_KEY:
GRADLE_ENTERPRISE_CACHE_USERNAME:
GRADLE_ENTERPRISE_CACHE_PASSWORD:
GRADLE_ENTERPRISE_URL: https://ge.spring.io
run:
path: bash
args:
- -ec
- |
${PWD}/git-repo/ci/scripts/build-pr.sh
-2
View File
@@ -10,8 +10,6 @@ caches:
params:
BRANCH:
CI: true
MAIN_TOOLCHAIN:
TEST_TOOLCHAIN:
GRADLE_ENTERPRISE_ACCESS_KEY:
GRADLE_ENTERPRISE_CACHE_USERNAME:
GRADLE_ENTERPRISE_CACHE_PASSWORD:
+3 -3
View File
@@ -1,13 +1,13 @@
---
platform: linux
image_resource:
type: registry-image
type: docker-image
source:
repository: springio/github-changelog-generator
tag: '0.0.6'
tag: '0.0.4'
inputs:
- name: git-repo
- name: artifactory-repo
- name: version
outputs:
- name: generated-changelog
params:
+4 -4
View File
@@ -10,9 +10,9 @@ params:
ARTIFACTORY_SERVER:
ARTIFACTORY_USERNAME:
ARTIFACTORY_PASSWORD:
SONATYPE_USER:
SONATYPE_PASSWORD:
SONATYPE_URL:
SONATYPE_STAGING_PROFILE_ID:
BINTRAY_SUBJECT:
BINTRAY_REPO:
BINTRAY_USERNAME:
BINTRAY_API_KEY:
run:
path: git-repo/ci/scripts/promote-version.sh
+16
View File
@@ -0,0 +1,16 @@
---
platform: linux
inputs:
- name: git-repo
- name: artifactory-repo
outputs:
- name: version
params:
BINTRAY_REPO:
BINTRAY_SUBJECT:
BINTRAY_USERNAME:
BINTRAY_API_KEY:
SONATYPE_USER_TOKEN:
SONATYPE_PASSWORD_TOKEN:
run:
path: git-repo/ci/scripts/sync-to-maven-central.sh
+1 -1
View File
@@ -1,4 +1,4 @@
version=5.3.9
version=5.3.4
org.gradle.jvmargs=-Xmx1536M
org.gradle.caching=true
org.gradle.parallel=true
+80
View File
@@ -0,0 +1,80 @@
// -----------------------------------------------------------------------------
//
// This script adds support for the following two JVM system properties
// that control the build for alternative JDKs (i.e., a JDK other than
// the one used to launch the Gradle process).
//
// - customJavaHome: absolute path to the alternate JDK installation to
// use to compile Java code and execute tests. This system property
// is also used in spring-oxm.gradle to determine whether JiBX is
// supported.
//
// - customJavaSourceVersion: Java version supplied to the `--release`
// command line flag to control the Java source and target
// compatibility version. Supported versions include 9 or higher.
// Do not set this system property if Java 8 should be used.
//
// Examples:
//
// ./gradlew -DcustomJavaHome=/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home test
//
// ./gradlew --no-build-cache -DcustomJavaHome=/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home test
//
// ./gradlew -DcustomJavaHome=/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home -DcustomJavaSourceVersion=14 test
//
//
// Credits: inspired by work from Marc Philipp and Stephane Nicoll
//
// -----------------------------------------------------------------------------
import org.gradle.internal.os.OperatingSystem
// import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile
def customJavaHome = System.getProperty("customJavaHome")
if (customJavaHome) {
def customJavaHomeDir = new File(customJavaHome)
def customJavaSourceVersion = System.getProperty("customJavaSourceVersion")
tasks.withType(JavaCompile) {
logger.info("Java home for " + it.name + " task in " + project.name + ": " + customJavaHomeDir)
options.forkOptions.javaHome = customJavaHomeDir
inputs.property("customJavaHome", customJavaHome)
if (customJavaSourceVersion) {
options.compilerArgs += [ "--release", customJavaSourceVersion]
inputs.property("customJavaSourceVersion", customJavaSourceVersion)
}
}
tasks.withType(GroovyCompile) {
logger.info("Java home for " + it.name + " task in " + project.name + ": " + customJavaHomeDir)
options.forkOptions.javaHome = customJavaHomeDir
inputs.property("customJavaHome", customJavaHome)
if (customJavaSourceVersion) {
options.compilerArgs += [ "--release", customJavaSourceVersion]
inputs.property("customJavaSourceVersion", customJavaSourceVersion)
}
}
/*
tasks.withType(KotlinJvmCompile) {
logger.info("Java home for " + it.name + " task in " + project.name + ": " + customJavaHome)
kotlinOptions.jdkHome = customJavaHomeDir
inputs.property("customJavaHome", customJavaHome)
}
*/
tasks.withType(Test) {
def javaExecutable = customJavaHome + "/bin/java"
if (OperatingSystem.current().isWindows()) {
javaExecutable += ".exe"
}
logger.info("Java executable for " + it.name + " task in " + project.name + ": " + javaExecutable)
executable = javaExecutable
inputs.property("customJavaHome", customJavaHome)
if (customJavaSourceVersion) {
inputs.property("customJavaSourceVersion", customJavaSourceVersion)
}
}
}
+1 -13
View File
@@ -103,12 +103,9 @@ dokka {
externalDocumentationLink {
url = new URL("https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/")
}
/*
This link causes errors, removing to fix the build.
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/")
}
@@ -130,8 +127,6 @@ 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'
@@ -148,11 +143,7 @@ asciidoctorj {
'highlightjs-theme': 'googlecode',
stylesdir: 'css/',
stylesheet: 'stylesheet.css',
'spring-version': project.version,
'spring-framework-main-code': 'https://github.com/spring-projects/spring-framework/tree/main',
'doc-root': docRoot,
'docs-spring-framework': docsSpringFramework,
'api-spring-framework': "${docsSpringFramework}/javadoc-api/org/springframework"
'spring-version': project.version
])
}
@@ -163,9 +154,6 @@ asciidoctorj {
asciidoctor {
baseDirFollowsSourceDir()
configurations 'asciidoctorExt'
attributes([
noheader: '' // custom header in docinfo-header.html
])
sources {
include '*.adoc'
}
+18
View File
@@ -108,3 +108,21 @@ task eclipseBuildship(type: Copy) {
tasks["eclipseJdt"].dependsOn(eclipseJdtPrepare)
tasks["cleanEclipse"].dependsOn(cleanEclipseJdtUi)
tasks["eclipse"].dependsOn(eclipseSettings, eclipseWstComponent)
// Filter 'build' folder
eclipse.project.file.withXml {
def node = it.asNode()
def filteredResources = node.get("filteredResources")
if(filteredResources) {
node.remove(filteredResources)
}
def filterNode = node.appendNode("filteredResources").appendNode("filter")
filterNode.appendNode("id", "1359048889071")
filterNode.appendNode("name", "")
filterNode.appendNode("type", "30")
def matcherNode = filterNode.appendNode("matcher")
matcherNode.appendNode("id", "org.eclipse.ui.ide.multiFilter")
matcherNode.appendNode("arguments", "1.0-projectRelativePath-matches-false-false-build")
}
+3 -4
View File
@@ -1,15 +1,14 @@
apply plugin: 'java-library'
apply plugin: 'org.springframework.build.compile'
apply plugin: 'org.springframework.build.optional-dependencies'
// Uncomment the following for Shadow support in the jmhJar block.
// Currently commented out due to ZipException: archive is not a ZIP archive
// apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'me.champeau.jmh'
apply plugin: 'me.champeau.gradle.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 'org.openjdk.jmh:jmh-core:1.25'
jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.25'
jmh 'net.sf.jopt-simple:jopt-simple:4.6'
}
-182
View File
@@ -1,182 +0,0 @@
/**
* Apply the JVM Toolchain conventions
* See https://docs.gradle.org/current/userguide/toolchains.html
*
* One can choose the toolchain to use for compiling the MAIN sources and/or compiling
* and running the TEST sources. These options apply to Java, Kotlin and Groovy sources
* when available.
* {@code "./gradlew check -PmainToolchain=8 -PtestToolchain=11"} will use:
* <ul>
* <li>a JDK8 toolchain for compiling the main SourceSet
* <li>a JDK11 toolchain for compiling and running the test SourceSet
* </ul>
*
* By default, the build will fall back to using the current JDK and 1.8 language level for all sourceSets.
*
* Gradle will automatically detect JDK distributions in well-known locations.
* The following command will list the detected JDKs on the host.
* {@code
* $ ./gradlew -q javaToolchains
* }
*
* We can also configure ENV variables and let Gradle know about them:
* {@code
* $ echo JDK11
* /opt/openjdk/java11
* $ echo JDK15
* /opt/openjdk/java15
* $ ./gradlew -Porg.gradle.java.installations.fromEnv=JDK11,JDK15 check
* }
*
* @author Brian Clozel
* @author Sam Brannen
*/
def mainToolchainConfigured() {
return project.hasProperty('mainToolchain') && project.mainToolchain
}
def testToolchainConfigured() {
return project.hasProperty('testToolchain') && project.testToolchain
}
def mainToolchainLanguageVersion() {
if (mainToolchainConfigured()) {
return JavaLanguageVersion.of(project.mainToolchain.toString())
}
return JavaLanguageVersion.of(8)
}
def testToolchainLanguageVersion() {
if (testToolchainConfigured()) {
return JavaLanguageVersion.of(project.testToolchain.toString())
}
return mainToolchainLanguageVersion()
}
plugins.withType(JavaPlugin) {
// Configure the Java Toolchain if the 'mainToolchain' is configured
if (mainToolchainConfigured()) {
java {
toolchain {
languageVersion = mainToolchainLanguageVersion()
}
}
}
else {
// Fallback to JDK8
java {
sourceCompatibility = JavaVersion.VERSION_1_8
}
}
// Configure a specific Java Toolchain for compiling and running tests if the 'testToolchain' property is defined
if (testToolchainConfigured()) {
def testLanguageVersion = testToolchainLanguageVersion()
tasks.withType(JavaCompile).matching { it.name.contains("Test") }.configureEach {
javaCompiler = javaToolchains.compilerFor {
languageVersion = testLanguageVersion
}
}
tasks.withType(Test).configureEach{
javaLauncher = javaToolchains.launcherFor {
languageVersion = testLanguageVersion
}
}
}
}
plugins.withType(GroovyPlugin) {
// Fallback to JDK8
if (!mainToolchainConfigured()) {
compileGroovy {
sourceCompatibility = JavaVersion.VERSION_1_8
}
}
}
pluginManager.withPlugin("kotlin") {
// Configure the Kotlin compiler if the 'mainToolchain' property is defined
if (mainToolchainConfigured()) {
def mainLanguageVersion = mainToolchainLanguageVersion()
def compiler = javaToolchains.compilerFor {
languageVersion = mainLanguageVersion
}
// See https://kotlinlang.org/docs/gradle.html#attributes-specific-for-jvm
def javaVersion = mainLanguageVersion.toString() == '8' ? '1.8' : mainLanguageVersion.toString()
compileKotlin {
kotlinOptions {
jvmTarget = javaVersion
jdkHome = compiler.get().metadata.installationPath.asFile.absolutePath
}
}
// Compile the test classes with the same version, 'testToolchain' will override if defined
compileTestKotlin {
kotlinOptions {
jvmTarget = javaVersion
jdkHome = compiler.get().metadata.installationPath.asFile.absolutePath
}
}
}
else {
// Fallback to JDK8
compileKotlin {
kotlinOptions {
jvmTarget = '1.8'
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = '1.8'
}
}
}
if (testToolchainConfigured()) {
def testLanguageVersion = testToolchainLanguageVersion()
def compiler = javaToolchains.compilerFor {
languageVersion = testLanguageVersion
}
// See https://kotlinlang.org/docs/gradle.html#attributes-specific-for-jvm
def javaVersion = testLanguageVersion.toString() == '8' ? '1.8' : testLanguageVersion.toString()
compileTestKotlin {
kotlinOptions {
jvmTarget = javaVersion
jdkHome = compiler.get().metadata.installationPath.asFile.absolutePath
}
}
}
}
// Configure the JMH plugin to use the toolchain for generating and running JMH bytecode
pluginManager.withPlugin("me.champeau.jmh") {
if (mainToolchainConfigured() || testToolchainConfigured()) {
tasks.matching { it.name.contains('jmh') && it.hasProperty('javaLauncher') }.configureEach {
javaLauncher.set(javaToolchains.launcherFor {
languageVersion.set(testToolchainLanguageVersion())
})
}
tasks.withType(JavaCompile).matching { it.name.contains("Jmh") }.configureEach {
javaCompiler = javaToolchains.compilerFor {
languageVersion = testToolchainLanguageVersion()
}
}
}
}
// Store resolved Toolchain JVM information as custom values in the build scan.
rootProject.ext {
resolvedMainToolchain = false
resolvedTestToolchain = false
}
gradle.taskGraph.afterTask { Task task, TaskState state ->
if (mainToolchainConfigured() && !resolvedMainToolchain && task instanceof JavaCompile && task.javaCompiler.isPresent()) {
def metadata = task.javaCompiler.get().metadata
task.project.buildScan.value('Main toolchain', "$metadata.vendor $metadata.languageVersion ($metadata.installationPath)")
resolvedMainToolchain = true
}
if (testToolchainConfigured() && !resolvedTestToolchain && task instanceof Test && task.javaLauncher.isPresent()) {
def metadata = task.javaLauncher.get().metadata
task.project.buildScan.value('Test toolchain', "$metadata.vendor $metadata.languageVersion ($metadata.installationPath)")
resolvedTestToolchain = true
}
}
+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-6.8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+7 -1
View File
@@ -6,7 +6,7 @@ pluginManagement {
}
plugins {
id "com.gradle.enterprise" version "3.6.1"
id "com.gradle.enterprise" version "3.5.1"
id "io.spring.ge.conventions" version "0.0.7"
}
@@ -45,6 +45,12 @@ rootProject.children.each {project ->
settings.gradle.projectsLoaded {
gradleEnterprise {
buildScan {
if (settings.gradle.rootProject.hasProperty('customJavaHome')) {
value("Custom JAVA_HOME", settings.gradle.rootProject.getProperty('customJavaHome'))
}
if (settings.gradle.rootProject.hasProperty('customJavaSourceVersion')) {
value("Custom Java Source Version", settings.gradle.rootProject.getProperty('customJavaSourceVersion'))
}
File buildDir = settings.gradle.rootProject.getBuildDir()
buildDir.mkdirs()
new File(buildDir, "build-scan-uri.txt").text = "(build scan not generated)"
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2012 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 org.aopalliance.aop.Advice;
* <p>Introductions are often <b>mixins</b>, enabling the building of composite
* objects that can achieve many of the goals of multiple inheritance in Java.
*
* <p>Compared to {@link IntroductionInfo}, this interface allows an advice to
* <p>Compared to {qlink IntroductionInfo}, this interface allows an advice to
* implement a range of interfaces that is not necessarily known in advance.
* Thus an {@link IntroductionAdvisor} can be used to specify which interfaces
* will be exposed in an advised object.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 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-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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-2021 the original author or authors.
* Copyright 2002-2020 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-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import java.util.concurrent.ConcurrentHashMap;
import org.springframework.aop.Advisor;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.SmartClassLoader;
import org.springframework.lang.Nullable;
/**
@@ -90,13 +89,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSu
}
proxyFactory.addAdvisor(this.advisor);
customizeProxyFactory(proxyFactory);
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != bean.getClass().getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
return proxyFactory.getProxy(classLoader);
return proxyFactory.getProxy(getProxyClassLoader());
}
// No proxy needed.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 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,9 +19,7 @@ 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;
@@ -31,9 +29,7 @@ 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.
@@ -48,11 +44,6 @@ import org.springframework.util.ReflectionUtils;
*/
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
@@ -139,23 +130,34 @@ public abstract class AopProxyUtils {
specifiedInterfaces = advised.getProxiedInterfaces();
}
}
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);
}
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++;
}
if (!advised.isInterfaceProxied(SpringProxy.class)) {
proxiedInterfaces.add(SpringProxy.class);
if (addAdvised) {
nonUserIfcCount++;
}
if (!advised.isOpaque() && !advised.isInterfaceProxied(Advised.class)) {
proxiedInterfaces.add(Advised.class);
if (addDecoratingProxy) {
nonUserIfcCount++;
}
if (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class)) {
proxiedInterfaces.add(DecoratingProxy.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++;
}
return ClassUtils.toClassArray(proxiedInterfaces);
if (addAdvised) {
proxiedInterfaces[index] = Advised.class;
index++;
}
if (addDecoratingProxy) {
proxiedInterfaces[index] = DecoratingProxy.class;
}
return proxiedInterfaces;
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
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;
@@ -47,7 +46,6 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.core.SmartClassLoader;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -441,17 +439,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
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 (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
@@ -470,12 +458,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
proxyFactory.setPreFiltered(true);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
return proxyFactory.getProxy(classLoader);
return proxyFactory.getProxy(getProxyClassLoader());
}
/**
@@ -520,10 +503,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
if (specificInterceptors.length > 0) {
// specificInterceptors may equal PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS
allInterceptors.addAll(Arrays.asList(specificInterceptors));
}
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -71,8 +71,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
if (introductionInfo != null) {
Class<?>[] introducedInterfaces = introductionInfo.getInterfaces();
if (introducedInterfaces.length == 0) {
throw new IllegalArgumentException(
"IntroductionInfo defines no interfaces to introduce: " + introductionInfo);
throw new IllegalArgumentException("IntroductionAdviceSupport implements no interfaces");
}
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-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -183,7 +183,7 @@ public class ProxyFactoryTests {
}
@Test
public void testGetsAllInterfaces() {
public void testGetsAllInterfaces() throws Exception {
// Extend to get new interface
class TestBeanSubclass extends TestBean implements Comparable<Object> {
@Override
@@ -240,16 +240,6 @@ 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.
*/
+2
View File
@@ -23,6 +23,8 @@ sourceSets {
}
compileGroovy {
sourceCompatibility = 1.8
targetCompatibility = 1.8
options.compilerArgs += "-Werror"
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 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.
@@ -305,10 +305,8 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
Class<?> componentType = propValue.getClass().getComponentType();
Object newArray = Array.newInstance(componentType, arrayIndex + 1);
System.arraycopy(propValue, 0, newArray, 0, length);
int lastKeyIndex = tokens.canonicalName.lastIndexOf('[');
String propName = tokens.canonicalName.substring(0, lastKeyIndex);
setPropertyValue(propName, newArray);
propValue = getPropertyValue(propName);
setPropertyValue(tokens.actualName, newArray);
propValue = getPropertyValue(tokens.actualName);
}
Array.set(propValue, arrayIndex, convertedValue);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 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,6 +41,8 @@ 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;
@@ -73,6 +75,8 @@ 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();
@@ -547,6 +551,9 @@ 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;
}
}
@@ -557,6 +564,10 @@ 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;
}
@@ -568,6 +579,10 @@ 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;
}
@@ -247,14 +247,14 @@ class TypeConverterDelegate {
// Definitely doesn't match: throw IllegalArgumentException/IllegalStateException
StringBuilder msg = new StringBuilder();
msg.append("Cannot convert value of type '").append(ClassUtils.getDescriptiveType(newValue));
msg.append("' to required type '").append(ClassUtils.getQualifiedName(requiredType)).append('\'');
msg.append("' to required type '").append(ClassUtils.getQualifiedName(requiredType)).append("'");
if (propertyName != null) {
msg.append(" for property '").append(propertyName).append('\'');
msg.append(" for property '").append(propertyName).append("'");
}
if (editor != null) {
msg.append(": PropertyEditor [").append(editor.getClass().getName()).append(
"] returned inappropriate value of type '").append(
ClassUtils.getDescriptiveType(convertedValue)).append('\'');
ClassUtils.getDescriptiveType(convertedValue)).append("'");
throw new IllegalArgumentException(msg.toString());
}
else {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -84,7 +84,7 @@ import org.springframework.lang.Nullable;
* (only applicable when running in a web application context)
* <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
* <li>InitializingBean's {@code afterPropertiesSet}
* <li>a custom {@code init-method} definition
* <li>a custom init-method definition
* <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
* </ol>
*
@@ -92,7 +92,7 @@ import org.springframework.lang.Nullable;
* <ol>
* <li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
* <li>DisposableBean's {@code destroy}
* <li>a custom {@code destroy-method} definition
* <li>a custom destroy-method definition
* </ol>
*
* @author Rod Johnson
@@ -102,8 +102,6 @@ import org.springframework.lang.Nullable;
* @see BeanNameAware#setBeanName
* @see BeanClassLoaderAware#setBeanClassLoader
* @see BeanFactoryAware#setBeanFactory
* @see org.springframework.context.EnvironmentAware#setEnvironment
* @see org.springframework.context.EmbeddedValueResolverAware#setEmbeddedValueResolver
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader
* @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher
* @see org.springframework.context.MessageSourceAware#setMessageSource
@@ -113,7 +111,6 @@ import org.springframework.lang.Nullable;
* @see InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
* @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor#postProcessBeforeDestruction
* @see DisposableBean#destroy
* @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 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-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,16 +36,15 @@ import org.springframework.util.StringValueResolver;
* Example XML bean definition:
*
* <pre class="code">
* &lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
* &lt;property name="driverClassName" value="${driver}" /&gt;
* &lt;property name="url" value="jdbc:${dbname}" /&gt;
* &lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"/&gt;
* &lt;property name="driverClassName" value="${driver}"/&gt;
* &lt;property name="url" value="jdbc:${dbname}"/&gt;
* &lt;/bean&gt;
* </pre>
*
* Example properties file:
*
* <pre class="code">
* driver=com.mysql.jdbc.Driver
* <pre class="code">driver=com.mysql.jdbc.Driver
* dbname=mysql:mydb</pre>
*
* Annotated bean definitions may take advantage of property replacement using
@@ -57,8 +56,7 @@ import org.springframework.util.StringValueResolver;
* in bean references. Furthermore, placeholder values can also cross-reference
* other placeholders, like:
*
* <pre class="code">
* rootPath=myrootdir
* <pre class="code">rootPath=myrootdir
* subPath=${rootPath}/subdir</pre>
*
* In contrast to {@link PropertyOverrideConfigurer}, subclasses of this type allow
@@ -73,13 +71,13 @@ import org.springframework.util.StringValueResolver;
*
* <p>Default property values can be defined globally for each configurer instance
* via the {@link #setProperties properties} property, or on a property-by-property basis
* using the value separator which is {@code ":"} by default and customizable via
* {@link #setValueSeparator(String)}.
* using the default value separator which is {@code ":"} by default and
* customizable via {@link #setValueSeparator(String)}.
*
* <p>Example XML property with default value:
*
* <pre class="code">
* &lt;property name="url" value="jdbc:${dbname:defaultdb}" /&gt;
* <property name="url" value="jdbc:${dbname:defaultdb}"/>
* </pre>
*
* @author Chris Beams
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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 (Map.Entry<?, ?> entity : namedArgs.entrySet()) {
String propName = (String) entity.getKey();
setProperty(propName, entity.getValue());
for (Object o : namedArgs.keySet()) {
String propName = (String) o;
setProperty(propName, namedArgs.get(propName));
}
}
// factory method syntax
@@ -894,7 +894,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
}
/**
* Return if there are property values defined for this bean.
* Return if there are property values values defined for this bean.
* @since 5.0.2
*/
@Override
@@ -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-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@ 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;
@@ -103,7 +102,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, (String) null);
return rootBeanDefinition(beanClass, null);
}
/**
@@ -118,30 +117,6 @@ 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
@@ -356,16 +331,6 @@ 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-2021 the original author or authors.
* Copyright 2002-2020 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.
@@ -35,7 +35,6 @@ import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -245,10 +244,8 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
return (bean.equals(null) ? null : bean);
}
else {
// Find target bean matching the (potentially generic) method return type
ResolvableType genericReturnType = ResolvableType.forMethodReturnType(method);
return (argsToUse != null ? this.owner.getBeanProvider(genericReturnType).getObject(argsToUse) :
this.owner.getBeanProvider(genericReturnType).getObject());
return (argsToUse != null ? this.owner.getBean(method.getReturnType(), argsToUse) :
this.owner.getBean(method.getReturnType()));
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 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 on bean class [" + mbd.getBeanClassName() + "] " +
"Could not resolve matching constructor " +
"(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 on bean class [" + mbd.getBeanClassName() + "] " +
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(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 on class [" + factoryClass.getName() + "]: " +
"No matching factory method found: " +
(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() + "' on class [" +
factoryClass.getName() + "]: needs to have a non-void return type!");
"Invalid factory method '" + mbd.getFactoryMethodName() +
"': needs to have a non-void return type!");
}
else if (ambiguousFactoryMethods != null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous factory method matches found on class [" + factoryClass.getName() + "] " +
"Ambiguous factory method matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousFactoryMethods);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,25 +19,17 @@ package org.springframework.beans.factory.support;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/**
* Represents an override of a method that looks up an object in the same IoC context,
* either by bean name or by bean type (based on the declared method return type).
* Represents an override of a method that looks up an object in the same IoC context.
*
* <p>Methods eligible for lookup override may declare arguments in which case the
* given arguments are passed to the bean retrieval operation.
* <p>Methods eligible for lookup override must not have arguments.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 1.1
* @see org.springframework.beans.factory.BeanFactory#getBean(String)
* @see org.springframework.beans.factory.BeanFactory#getBean(Class)
* @see org.springframework.beans.factory.BeanFactory#getBean(String, Object...)
* @see org.springframework.beans.factory.BeanFactory#getBean(Class, Object...)
* @see org.springframework.beans.factory.BeanFactory#getBeanProvider(ResolvableType)
*/
public class LookupOverride extends MethodOverride {
@@ -51,8 +43,8 @@ public class LookupOverride extends MethodOverride {
/**
* Construct a new LookupOverride.
* @param methodName the name of the method to override
* @param beanName the name of the bean in the current {@code BeanFactory} that the
* overridden method should return (may be {@code null} for type-based bean retrieval)
* @param beanName the name of the bean in the current {@code BeanFactory}
* that the overridden method should return (may be {@code null})
*/
public LookupOverride(String methodName, @Nullable String beanName) {
super(methodName);
@@ -61,9 +53,9 @@ public class LookupOverride extends MethodOverride {
/**
* Construct a new LookupOverride.
* @param method the method declaration to override
* @param beanName the name of the bean in the current {@code BeanFactory} that the
* overridden method should return (may be {@code null} for type-based bean retrieval)
* @param method the method to override
* @param beanName the name of the bean in the current {@code BeanFactory}
* that the overridden method should return (may be {@code null})
*/
public LookupOverride(Method method, @Nullable String beanName) {
super(method.getName());
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2012 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,8 +19,9 @@ package org.springframework.beans.factory.support;
import java.lang.reflect.Method;
/**
* Interface to be implemented by classes that can reimplement any method on an
* IoC-managed object: the <b>Method Injection</b> form of Dependency Injection.
* Interface to be implemented by classes that can reimplement any method
* on an IoC-managed object: the <b>Method Injection</b> form of
* Dependency Injection.
*
* <p>Such methods may be (but need not be) abstract, in which case the
* container will create a concrete subclass to instantiate.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Extension of {@link MethodOverride} that represents an arbitrary
* Extension of MethodOverride that represents an arbitrary
* override of a method by the IoC container.
*
* <p>Any non-final method can be overridden, irrespective of its
@@ -45,7 +45,7 @@ public class ReplaceOverride extends MethodOverride {
/**
* Construct a new ReplaceOverride.
* @param methodName the name of the method to override
* @param methodReplacerBeanName the bean name of the {@link MethodReplacer}
* @param methodReplacerBeanName the bean name of the MethodReplacer
*/
public ReplaceOverride(String methodName, String methodReplacerBeanName) {
super(methodName);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2012 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.
@@ -23,9 +23,9 @@ import org.springframework.util.StringUtils;
/**
* Editor for {@code java.util.Locale}, to directly populate a Locale property.
*
* <p>Expects the same syntax as Locale's {@code toString()}, i.e. language +
* <p>Expects the same syntax as Locale's {@code toString}, i.e. language +
* optionally country + optionally variant, separated by "_" (e.g. "en", "en_US").
* Also accepts spaces as separators, as an alternative to underscores.
* Also accepts spaces as separators, as alternative to underscores.
*
* @author Juergen Hoeller
* @since 26.05.2003
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,8 +26,8 @@ import java.nio.file.Paths;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;
/**
* Editor for {@code java.nio.file.Path}, to directly populate a Path
@@ -74,7 +74,7 @@ public class PathEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
boolean nioPathCandidate = !text.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX);
boolean nioPathCandidate = !text.startsWith(ResourceLoader.CLASSPATH_URL_PREFIX);
if (nioPathCandidate && !text.startsWith("/")) {
try {
URI uri = new URI(text);
@@ -85,13 +85,9 @@ public class PathEditor extends PropertyEditorSupport {
return;
}
}
catch (URISyntaxException ex) {
// Not a valid URI; potentially a Windows-style path after
// a file prefix (let's try as Spring resource location)
nioPathCandidate = !text.startsWith(ResourceUtils.FILE_URL_PREFIX);
}
catch (FileSystemNotFoundException ex) {
// URI scheme not registered for NIO (let's try URL
catch (URISyntaxException | FileSystemNotFoundException ex) {
// Not a valid URI (let's try as Spring resource location),
// or a URI scheme not registered for NIO (let's try URL
// protocol handlers via Spring's resource mechanism).
}
}
@@ -101,7 +97,7 @@ public class PathEditor extends PropertyEditorSupport {
if (resource == null) {
setValue(null);
}
else if (nioPathCandidate && !resource.exists()) {
else if (!resource.exists() && nioPathCandidate) {
setValue(Paths.get(text).normalize());
}
else {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,6 +44,8 @@ public class PropertyComparator<T> implements Comparator<T> {
private final SortDefinition sortDefinition;
private final BeanWrapperImpl beanWrapper = new BeanWrapperImpl(false);
/**
* Create a new PropertyComparator for the given SortDefinition.
@@ -113,9 +115,8 @@ public class PropertyComparator<T> implements Comparator<T> {
// (similar to JSTL EL). If the property doesn't exist in the
// first place, let the exception through.
try {
BeanWrapperImpl beanWrapper = new BeanWrapperImpl(false);
beanWrapper.setWrappedInstance(obj);
return beanWrapper.getPropertyValue(this.sortDefinition.getProperty());
this.beanWrapper.setWrappedInstance(obj);
return this.beanWrapper.getPropertyValue(this.sortDefinition.getProperty());
}
catch (BeansException ex) {
logger.debug("PropertyComparator could not access property - treating as null for sorting", ex);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,7 +28,6 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Keith Donald
* @author Juergen Hoeller
* @author Sam Brannen
*/
public class BeanWrapperAutoGrowingTests {
@@ -67,6 +66,11 @@ public class BeanWrapperAutoGrowingTests {
assertThat(bean.getArray()[0]).isInstanceOf(Bean.class);
}
private void assertNotNull(Object propertyValue) {
assertThat(propertyValue).isNotNull();
}
@Test
public void setPropertyValueAutoGrowArray() {
wrapper.setPropertyValue("array[0].prop", "test");
@@ -89,39 +93,12 @@ public class BeanWrapperAutoGrowingTests {
}
@Test
public void getPropertyValueAutoGrow2dArray() {
public void getPropertyValueAutoGrowMultiDimensionalArray() {
assertNotNull(wrapper.getPropertyValue("multiArray[0][0]"));
assertThat(bean.getMultiArray()[0].length).isEqualTo(1);
assertThat(bean.getMultiArray()[0][0]).isInstanceOf(Bean.class);
}
@Test
public void getPropertyValueAutoGrow3dArray() {
assertNotNull(wrapper.getPropertyValue("threeDimensionalArray[1][2][3]"));
assertThat(bean.getThreeDimensionalArray()[1].length).isEqualTo(3);
assertThat(bean.getThreeDimensionalArray()[1][2][3]).isInstanceOf(Bean.class);
}
@Test
public void setPropertyValueAutoGrow2dArray() {
Bean newBean = new Bean();
newBean.setProp("enigma");
wrapper.setPropertyValue("multiArray[2][3]", newBean);
assertThat(bean.getMultiArray()[2][3])
.isInstanceOf(Bean.class)
.extracting(Bean::getProp).isEqualTo("enigma");
}
@Test
public void setPropertyValueAutoGrow3dArray() {
Bean newBean = new Bean();
newBean.setProp("enigma");
wrapper.setPropertyValue("threeDimensionalArray[2][3][4]", newBean);
assertThat(bean.getThreeDimensionalArray()[2][3][4])
.isInstanceOf(Bean.class)
.extracting(Bean::getProp).isEqualTo("enigma");
}
@Test
public void getPropertyValueAutoGrowList() {
assertNotNull(wrapper.getPropertyValue("list[0]"));
@@ -154,7 +131,7 @@ public class BeanWrapperAutoGrowingTests {
public void getPropertyValueAutoGrowListFailsAgainstLimit() {
wrapper.setAutoGrowCollectionLimit(2);
assertThatExceptionOfType(InvalidPropertyException.class).isThrownBy(() ->
wrapper.getPropertyValue("list[4]"))
assertNotNull(wrapper.getPropertyValue("list[4]")))
.withRootCauseInstanceOf(IndexOutOfBoundsException.class);
}
@@ -184,11 +161,6 @@ public class BeanWrapperAutoGrowingTests {
}
private static void assertNotNull(Object propertyValue) {
assertThat(propertyValue).isNotNull();
}
@SuppressWarnings("rawtypes")
public static class Bean {
@@ -202,8 +174,6 @@ public class BeanWrapperAutoGrowingTests {
private Bean[][] multiArray;
private Bean[][][] threeDimensionalArray;
private List<Bean> list;
private List<List<Bean>> multiList;
@@ -244,14 +214,6 @@ public class BeanWrapperAutoGrowingTests {
this.multiArray = multiArray;
}
public Bean[][][] getThreeDimensionalArray() {
return threeDimensionalArray;
}
public void setThreeDimensionalArray(Bean[][][] threeDimensionalArray) {
this.threeDimensionalArray = threeDimensionalArray;
}
public List<Bean> getList() {
return list;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,14 +18,14 @@ package org.springframework.beans;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@@ -36,21 +36,23 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Chris Beams
* @since 08.03.2004
*/
class ConcurrentBeanWrapperTests {
public class ConcurrentBeanWrapperTests {
private final Log logger = LogFactory.getLog(getClass());
private final Set<TestRun> set = ConcurrentHashMap.newKeySet();
private Set<TestRun> set = Collections.synchronizedSet(new HashSet<TestRun>());
private Throwable ex = null;
@RepeatedTest(100)
void testSingleThread() {
performSet();
@Test
public void testSingleThread() {
for (int i = 0; i < 100; i++) {
performSet();
}
}
@Test
void testConcurrent() {
public void testConcurrent() {
for (int i = 0; i < 10; i++) {
TestRun run = new TestRun(this);
set.add(run);
@@ -80,7 +82,7 @@ class ConcurrentBeanWrapperTests {
Properties p = (Properties) System.getProperties().clone();
assertThat(p).as("The System properties must not be empty").isNotEmpty();
assertThat(p.size() != 0).as("The System properties must not be empty").isTrue();
for (Iterator<?> i = p.entrySet().iterator(); i.hasNext();) {
i.next();
@@ -109,7 +111,7 @@ class ConcurrentBeanWrapperTests {
private ConcurrentBeanWrapperTests test;
TestRun(ConcurrentBeanWrapperTests test) {
public TestRun(ConcurrentBeanWrapperTests test) {
this.test = test;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,7 +31,6 @@ 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 {
@@ -41,8 +40,7 @@ public class Spr5475Tests {
rootBeanDefinition(Foo.class)
.setFactoryMethod("noArgFactory")
.addConstructorArgValue("bogusArg").getBeanDefinition(),
"Error creating bean with name 'foo': No matching factory method found on class " +
"[org.springframework.beans.factory.Spr5475Tests$Foo]: factory method 'noArgFactory(String)'. " +
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(String)'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
@@ -53,8 +51,7 @@ public class Spr5475Tests {
.setFactoryMethod("noArgFactory")
.addConstructorArgValue("bogusArg1")
.addConstructorArgValue("bogusArg2".getBytes()).getBeanDefinition(),
"Error creating bean with name 'foo': No matching factory method found on class " +
"[org.springframework.beans.factory.Spr5475Tests$Foo]: factory method 'noArgFactory(String,byte[])'. " +
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(String,byte[])'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
@@ -68,8 +65,7 @@ public class Spr5475Tests {
def.setConstructorArgumentValues(cav);
assertExceptionMessageForMisconfiguredFactoryMethod(def,
"Error creating bean with name 'foo': No matching factory method found on class " +
"[org.springframework.beans.factory.Spr5475Tests$Foo]: factory method 'noArgFactory(CharSequence,byte[])'. " +
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(CharSequence,byte[])'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 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.
@@ -121,18 +121,6 @@ public class LookupAnnotationTests {
assertThat(beanFactory.getBean(BeanConsumer.class).abstractBean).isSameAs(bean);
}
@Test
public void testWithGenericBean() {
beanFactory.registerBeanDefinition("numberBean", new RootBeanDefinition(NumberBean.class));
beanFactory.registerBeanDefinition("doubleStore", new RootBeanDefinition(DoubleStore.class));
beanFactory.registerBeanDefinition("floatStore", new RootBeanDefinition(FloatStore.class));
NumberBean bean = (NumberBean) beanFactory.getBean("numberBean");
assertThat(bean).isNotNull();
assertThat(beanFactory.getBean(DoubleStore.class)).isSameAs(bean.getDoubleStore());
assertThat(beanFactory.getBean(FloatStore.class)).isSameAs(bean.getFloatStore());
}
public static abstract class AbstractBean {
@@ -159,26 +147,4 @@ public class LookupAnnotationTests {
AbstractBean abstractBean;
}
public static class NumberStore<T extends Number> {
}
public static class DoubleStore extends NumberStore<Double> {
}
public static class FloatStore extends NumberStore<Float> {
}
public static abstract class NumberBean {
@Lookup
public abstract NumberStore<Double> getDoubleStore();
@Lookup
public abstract NumberStore<Float> getFloatStore();
}
}
@@ -141,7 +141,6 @@ class YamlProcessorTests {
}
@Test
@SuppressWarnings("unchecked")
void standardTypesSupportedByDefault() throws Exception {
setYaml("value: !!set\n ? first\n ? second");
this.processor.process((properties, map) -> {
@@ -17,25 +17,22 @@
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
*/
class BeanDefinitionBuilderTests {
public class BeanDefinitionBuilderTests {
@Test
void builderWithBeanClassWithSimpleProperty() {
public void beanClassWithSimpleProperty() {
String[] dependsOn = new String[] { "A", "B", "C" };
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class);
bdb.setScope(BeanDefinition.SCOPE_PROTOTYPE);
@@ -52,7 +49,7 @@ class BeanDefinitionBuilderTests {
}
@Test
void builderWithBeanClassAndFactoryMethod() {
public void beanClassWithFactoryMethod() {
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class, "create");
RootBeanDefinition rbd = (RootBeanDefinition) bdb.getBeanDefinition();
assertThat(rbd.hasBeanClass()).isTrue();
@@ -61,7 +58,7 @@ class BeanDefinitionBuilderTests {
}
@Test
void builderWithBeanClassName() {
public void beanClassName() {
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class.getName());
RootBeanDefinition rbd = (RootBeanDefinition) bdb.getBeanDefinition();
assertThat(rbd.hasBeanClass()).isFalse();
@@ -69,7 +66,7 @@ class BeanDefinitionBuilderTests {
}
@Test
void builderWithBeanClassNameAndFactoryMethod() {
public void beanClassNameWithFactoryMethod() {
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class.getName(), "create");
RootBeanDefinition rbd = (RootBeanDefinition) bdb.getBeanDefinition();
assertThat(rbd.hasBeanClass()).isFalse();
@@ -77,78 +74,4 @@ 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-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,7 +36,7 @@ public class LookupMethodTests {
@BeforeEach
public void setup() {
public void setUp() {
beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(new ClassPathResource("lookupMethodTests.xml", getClass()));
@@ -83,8 +83,8 @@ public class LookupMethodTests {
public void testWithThreeArgsShouldFail() {
AbstractBean bean = (AbstractBean) beanFactory.getBean("abstractBean");
assertThat(bean).isNotNull();
assertThatExceptionOfType(AbstractMethodError.class).as("does not have a three arg constructor")
.isThrownBy(() -> bean.getThreeArguments("name", 1, 2));
assertThatExceptionOfType(AbstractMethodError.class).as("does not have a three arg constructor").isThrownBy(() ->
bean.getThreeArguments("name", 1, 2));
}
@Test
@@ -97,21 +97,6 @@ public class LookupMethodTests {
assertThat(expected.isJedi()).isTrue();
}
@Test
public void testWithGenericBean() {
RootBeanDefinition bd = new RootBeanDefinition(NumberBean.class);
bd.getMethodOverrides().addOverride(new LookupOverride("getDoubleStore", null));
bd.getMethodOverrides().addOverride(new LookupOverride("getFloatStore", null));
beanFactory.registerBeanDefinition("numberBean", bd);
beanFactory.registerBeanDefinition("doubleStore", new RootBeanDefinition(DoubleStore.class));
beanFactory.registerBeanDefinition("floatStore", new RootBeanDefinition(FloatStore.class));
NumberBean bean = (NumberBean) beanFactory.getBean("numberBean");
assertThat(bean).isNotNull();
assertThat(beanFactory.getBean(DoubleStore.class)).isSameAs(bean.getDoubleStore());
assertThat(beanFactory.getBean(FloatStore.class)).isSameAs(bean.getFloatStore());
}
public static abstract class AbstractBean {
@@ -126,24 +111,4 @@ public class LookupMethodTests {
public abstract TestBean getThreeArguments(String name, int age, int anotherArg);
}
public static class NumberStore<T extends Number> {
}
public static class DoubleStore extends NumberStore<Double> {
}
public static class FloatStore extends NumberStore<Float> {
}
public static abstract class NumberBean {
public abstract NumberStore<Double> getDoubleStore();
public abstract NumberStore<Float> getFloatStore();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -244,7 +244,7 @@ public class QualifierAnnotationAutowireBeanFactoryTests {
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
private @interface TestQualifier {
private static @interface TestQualifier {
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,78 +34,57 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
public class PathEditorTests {
@Test
public void testClasspathPathName() {
public void testClasspathPathName() throws Exception {
PropertyEditor pathEditor = new PathEditor();
pathEditor.setAsText("classpath:" + ClassUtils.classPackageAsResourcePath(getClass()) + "/" +
ClassUtils.getShortName(getClass()) + ".class");
Object value = pathEditor.getValue();
assertThat(value instanceof Path).isTrue();
boolean condition = value instanceof Path;
assertThat(condition).isTrue();
Path path = (Path) value;
assertThat(path.toFile().exists()).isTrue();
}
@Test
public void testWithNonExistentResource() {
public void testWithNonExistentResource() throws Exception {
PropertyEditor propertyEditor = new PathEditor();
assertThatIllegalArgumentException().isThrownBy(() ->
propertyEditor.setAsText("classpath:/no_way_this_file_is_found.doc"));
}
@Test
public void testWithNonExistentPath() {
public void testWithNonExistentPath() throws Exception {
PropertyEditor pathEditor = new PathEditor();
pathEditor.setAsText("file:/no_way_this_file_is_found.doc");
Object value = pathEditor.getValue();
assertThat(value instanceof Path).isTrue();
boolean condition1 = value instanceof Path;
assertThat(condition1).isTrue();
Path path = (Path) value;
assertThat(!path.toFile().exists()).isTrue();
boolean condition = !path.toFile().exists();
assertThat(condition).isTrue();
}
@Test
public void testAbsolutePath() {
public void testAbsolutePath() throws Exception {
PropertyEditor pathEditor = new PathEditor();
pathEditor.setAsText("/no_way_this_file_is_found.doc");
Object value = pathEditor.getValue();
assertThat(value instanceof Path).isTrue();
boolean condition1 = value instanceof Path;
assertThat(condition1).isTrue();
Path path = (Path) value;
assertThat(!path.toFile().exists()).isTrue();
boolean condition = !path.toFile().exists();
assertThat(condition).isTrue();
}
@Test
public void testWindowsAbsolutePath() {
PropertyEditor pathEditor = new PathEditor();
pathEditor.setAsText("C:\\no_way_this_file_is_found.doc");
Object value = pathEditor.getValue();
assertThat(value instanceof Path).isTrue();
Path path = (Path) value;
assertThat(!path.toFile().exists()).isTrue();
}
@Test
public void testWindowsAbsoluteFilePath() {
PropertyEditor pathEditor = new PathEditor();
try {
pathEditor.setAsText("file://C:\\no_way_this_file_is_found.doc");
Object value = pathEditor.getValue();
assertThat(value instanceof Path).isTrue();
Path path = (Path) value;
assertThat(!path.toFile().exists()).isTrue();
}
catch (IllegalArgumentException ex) {
if (File.separatorChar == '\\') { // on Windows, otherwise silently ignore
throw ex;
}
}
}
@Test
public void testUnqualifiedPathNameFound() {
public void testUnqualifiedPathNameFound() throws Exception {
PropertyEditor pathEditor = new PathEditor();
String fileName = ClassUtils.classPackageAsResourcePath(getClass()) + "/" +
ClassUtils.getShortName(getClass()) + ".class";
pathEditor.setAsText(fileName);
Object value = pathEditor.getValue();
assertThat(value instanceof Path).isTrue();
boolean condition = value instanceof Path;
assertThat(condition).isTrue();
Path path = (Path) value;
File file = path.toFile();
assertThat(file.exists()).isTrue();
@@ -117,13 +96,14 @@ public class PathEditorTests {
}
@Test
public void testUnqualifiedPathNameNotFound() {
public void testUnqualifiedPathNameNotFound() throws Exception {
PropertyEditor pathEditor = new PathEditor();
String fileName = ClassUtils.classPackageAsResourcePath(getClass()) + "/" +
ClassUtils.getShortName(getClass()) + ".clazz";
pathEditor.setAsText(fileName);
Object value = pathEditor.getValue();
assertThat(value instanceof Path).isTrue();
boolean condition = value instanceof Path;
assertThat(condition).isTrue();
Path path = (Path) value;
File file = path.toFile();
assertThat(file.exists()).isFalse();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 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.context.index.processor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -36,7 +37,7 @@ import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
/**
* Annotation {@link Processor} that writes a {@link CandidateComponentsMetadata}
* Annotation {@link Processor} that writes {@link CandidateComponentsMetadata}
* file for spring components.
*
* @author Stephane Nicoll
@@ -45,6 +46,9 @@ import javax.lang.model.element.TypeElement;
*/
public class CandidateComponentsIndexer implements Processor {
private static final Set<ElementKind> TYPE_KINDS =
Collections.unmodifiableSet(EnumSet.of(ElementKind.CLASS, ElementKind.INTERFACE));
private MetadataStore metadataStore;
private MetadataCollector metadataCollector;
@@ -132,8 +136,7 @@ public class CandidateComponentsIndexer implements Processor {
private static List<TypeElement> staticTypesIn(Iterable<? extends Element> elements) {
List<TypeElement> list = new ArrayList<>();
for (Element element : elements) {
if ((element.getKind().isClass() || element.getKind() == ElementKind.INTERFACE) &&
element.getModifiers().contains(Modifier.STATIC) && element instanceof TypeElement) {
if (TYPE_KINDS.contains(element.getKind()) && element.getModifiers().contains(Modifier.STATIC)) {
list.add((TypeElement) element);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import javax.lang.model.element.ElementKind;
/**
* A {@link StereotypesProvider} implementation that extracts the stereotypes
* flagged by the {@value #INDEXED_ANNOTATION} annotation. This implementation
* flagged by the {@value INDEXED_ANNOTATION} annotation. This implementation
* honors stereotypes defined this way on meta-annotations.
*
* @author Stephane Nicoll
@@ -48,7 +48,7 @@ class IndexedStereotypesProvider implements StereotypesProvider {
public Set<String> getStereotypes(Element element) {
Set<String> stereotypes = new LinkedHashSet<>();
ElementKind kind = element.getKind();
if (!kind.isClass() && kind != ElementKind.INTERFACE) {
if (kind != ElementKind.CLASS && kind != ElementKind.INTERFACE) {
return stereotypes;
}
Set<Element> seen = new HashSet<>();
@@ -24,7 +24,7 @@ import javax.lang.model.element.ElementKind;
/**
* A {@link StereotypesProvider} implementation that provides the
* {@value #STEREOTYPE} stereotype for each package-info.
* {@value STEREOTYPE} stereotype for each package-info.
*
* @author Stephane Nicoll
* @since 5.0
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,8 +24,8 @@ import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
/**
* A {@link StereotypesProvider} that extracts a stereotype for each
* {@code javax.*} annotation <i>present</i> on a class or interface.
* A {@link StereotypesProvider} that extract a stereotype for each
* {@code javax.*} annotation placed on a class or interface.
*
* @author Stephane Nicoll
* @since 5.0
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ import javax.lang.model.element.Element;
/**
* Provide the list of stereotypes that match an {@link Element}.
* <p>If an element has one or more stereotypes, it is referenced in the index
* If an element has one more stereotypes, it is referenced in the index
* of candidate components and each stereotype can be queried individually.
*
* @author Stephane Nicoll
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -130,8 +130,8 @@ public class EhCacheManagerFactoryBean implements FactoryBean<CacheManager>, Ini
@Override
public void afterPropertiesSet() throws CacheException {
if (logger.isDebugEnabled()) {
logger.debug("Initializing EhCache CacheManager" +
if (logger.isInfoEnabled()) {
logger.info("Initializing EhCache CacheManager" +
(this.cacheManagerName != null ? " '" + this.cacheManagerName + "'" : ""));
}
@@ -188,8 +188,8 @@ public class EhCacheManagerFactoryBean implements FactoryBean<CacheManager>, Ini
@Override
public void destroy() {
if (this.cacheManager != null && this.locallyManaged) {
if (logger.isDebugEnabled()) {
logger.debug("Shutting down EhCache CacheManager" +
if (logger.isInfoEnabled()) {
logger.info("Shutting down EhCache CacheManager" +
(this.cacheManagerName != null ? " '" + this.cacheManagerName + "'" : ""));
}
this.cacheManager.shutdown();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 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.
@@ -221,11 +221,11 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
}
catch (NoUniqueBeanDefinitionException ex) {
throw new IllegalStateException("No CacheResolver specified, and no unique bean of type " +
"CacheManager found. Mark one as primary or declare a specific CacheManager to use.", ex);
"CacheManager found. Mark one as primary or declare a specific CacheManager to use.");
}
catch (NoSuchBeanDefinitionException ex) {
throw new IllegalStateException("No CacheResolver specified, and no bean of type CacheManager found. " +
"Register a CacheManager bean or remove the @EnableCaching annotation from your configuration.", ex);
"Register a CacheManager bean or remove the @EnableCaching annotation from your configuration.");
}
}
this.initialized = true;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -71,9 +71,9 @@ public class CacheEvictOperation extends CacheOperation {
@Override
protected StringBuilder getOperationDescription() {
StringBuilder sb = super.getOperationDescription();
sb.append(',');
sb.append(",");
sb.append(this.cacheWide);
sb.append(',');
sb.append(",");
sb.append(this.beforeInvocation);
return sb;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -216,13 +216,13 @@ public abstract class CacheOperation implements BasicOperation {
*/
protected StringBuilder getOperationDescription() {
StringBuilder result = new StringBuilder(getClass().getSimpleName());
result.append('[').append(this.name);
result.append("[").append(this.name);
result.append("] caches=").append(this.cacheNames);
result.append(" | key='").append(this.key);
result.append("' | keyGenerator='").append(this.keyGenerator);
result.append("' | cacheManager='").append(this.cacheManager);
result.append("' | cacheResolver='").append(this.cacheResolver);
result.append("' | condition='").append(this.condition).append('\'');
result.append("' | condition='").append(this.condition).append("'");
return result;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -66,7 +66,7 @@ public class CachePutOperation extends CacheOperation {
StringBuilder sb = super.getOperationDescription();
sb.append(" | unless='");
sb.append(this.unless);
sb.append('\'');
sb.append("'");
return sb;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -79,10 +79,10 @@ public class CacheableOperation extends CacheOperation {
StringBuilder sb = super.getOperationDescription();
sb.append(" | unless='");
sb.append(this.unless);
sb.append('\'');
sb.append("'");
sb.append(" | sync='");
sb.append(this.sync);
sb.append('\'');
sb.append("'");
return sb;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.springframework.context;
import java.time.Clock;
import java.util.EventObject;
/**
@@ -38,37 +37,18 @@ public abstract class ApplicationEvent extends EventObject {
/**
* Create a new {@code ApplicationEvent} with its {@link #getTimestamp() timestamp}
* set to {@link System#currentTimeMillis()}.
* Create a new {@code ApplicationEvent}.
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
* @see #ApplicationEvent(Object, Clock)
*/
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
/**
* Create a new {@code ApplicationEvent} with its {@link #getTimestamp() timestamp}
* set to the value returned by {@link Clock#millis()} in the provided {@link Clock}.
* <p>This constructor is typically used in testing scenarios.
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
* @param clock a clock which will provide the timestamp
* @since 5.3.8
* @see #ApplicationEvent(Object)
*/
public ApplicationEvent(Object source, Clock clock) {
super(source);
this.timestamp = clock.millis();
}
/**
* Return the time in milliseconds when the event occurred.
* @see #ApplicationEvent(Object)
* @see #ApplicationEvent(Object, Clock)
* Return the system time in milliseconds when the event occurred.
*/
public final long getTimestamp() {
return this.timestamp;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 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.
@@ -35,8 +35,6 @@ import java.util.function.Consumer;
* @param <E> the specific {@code ApplicationEvent} subclass to listen to
* @see org.springframework.context.ApplicationEvent
* @see org.springframework.context.event.ApplicationEventMulticaster
* @see org.springframework.context.event.SmartApplicationListener
* @see org.springframework.context.event.GenericApplicationListener
* @see org.springframework.context.event.EventListener
*/
@FunctionalInterface
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,15 +19,13 @@ package org.springframework.context.annotation;
import org.springframework.beans.factory.parsing.Problem;
import org.springframework.beans.factory.parsing.ProblemReporter;
import org.springframework.core.type.MethodMetadata;
import org.springframework.lang.Nullable;
/**
* Represents a {@link Configuration @Configuration} class method annotated with
* {@link Bean @Bean}.
* Represents a {@link Configuration @Configuration} class method marked with the
* {@link Bean @Bean} annotation.
*
* @author Chris Beams
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.0
* @see ConfigurationClass
* @see ConfigurationClassParser
@@ -35,7 +33,7 @@ import org.springframework.lang.Nullable;
*/
final class BeanMethod extends ConfigurationMethod {
BeanMethod(MethodMetadata metadata, ConfigurationClass configurationClass) {
public BeanMethod(MethodMetadata metadata, ConfigurationClass configurationClass) {
super(metadata, configurationClass);
}
@@ -54,28 +52,12 @@ final class BeanMethod extends ConfigurationMethod {
}
}
@Override
public boolean equals(@Nullable Object obj) {
return ((this == obj) || ((obj instanceof BeanMethod) &&
this.metadata.equals(((BeanMethod) obj).metadata)));
}
@Override
public int hashCode() {
return this.metadata.hashCode();
}
@Override
public String toString() {
return "BeanMethod: " + this.metadata;
}
private class NonOverridableMethodError extends Problem {
NonOverridableMethodError() {
public NonOverridableMethodError() {
super(String.format("@Bean method '%s' must not be private or final; change the method's modifiers to continue",
getMetadata().getMethodName()), getResourceLocation());
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,7 +36,7 @@ import org.springframework.util.ClassUtils;
/**
* Represents a user-defined {@link Configuration @Configuration} class.
* <p>Includes a set of {@link Bean} methods, including all such methods
* Includes a set of {@link Bean} methods, including all such methods
* defined in the ancestry of the class, in a 'flattened-out' manner.
*
* @author Chris Beams
@@ -74,7 +74,7 @@ final class ConfigurationClass {
* @param beanName must not be {@code null}
* @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass)
*/
ConfigurationClass(MetadataReader metadataReader, String beanName) {
public ConfigurationClass(MetadataReader metadataReader, String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
this.metadata = metadataReader.getAnnotationMetadata();
this.resource = metadataReader.getResource();
@@ -89,7 +89,7 @@ final class ConfigurationClass {
* @param importedBy the configuration class importing this one or {@code null}
* @since 3.1.1
*/
ConfigurationClass(MetadataReader metadataReader, @Nullable ConfigurationClass importedBy) {
public ConfigurationClass(MetadataReader metadataReader, @Nullable ConfigurationClass importedBy) {
this.metadata = metadataReader.getAnnotationMetadata();
this.resource = metadataReader.getResource();
this.importedBy.add(importedBy);
@@ -101,7 +101,7 @@ final class ConfigurationClass {
* @param beanName name of the {@code @Configuration} class bean
* @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass)
*/
ConfigurationClass(Class<?> clazz, String beanName) {
public ConfigurationClass(Class<?> clazz, String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
this.metadata = AnnotationMetadata.introspect(clazz);
this.resource = new DescriptiveResource(clazz.getName());
@@ -116,7 +116,7 @@ final class ConfigurationClass {
* @param importedBy the configuration class importing this one (or {@code null})
* @since 3.1.1
*/
ConfigurationClass(Class<?> clazz, @Nullable ConfigurationClass importedBy) {
public ConfigurationClass(Class<?> clazz, @Nullable ConfigurationClass importedBy) {
this.metadata = AnnotationMetadata.introspect(clazz);
this.resource = new DescriptiveResource(clazz.getName());
this.importedBy.add(importedBy);
@@ -128,7 +128,7 @@ final class ConfigurationClass {
* @param beanName name of the {@code @Configuration} class bean
* @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass)
*/
ConfigurationClass(AnnotationMetadata metadata, String beanName) {
public ConfigurationClass(AnnotationMetadata metadata, String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
this.metadata = metadata;
this.resource = new DescriptiveResource(metadata.getClassName());
@@ -136,19 +136,19 @@ final class ConfigurationClass {
}
AnnotationMetadata getMetadata() {
public AnnotationMetadata getMetadata() {
return this.metadata;
}
Resource getResource() {
public Resource getResource() {
return this.resource;
}
String getSimpleName() {
public String getSimpleName() {
return ClassUtils.getShortName(getMetadata().getClassName());
}
void setBeanName(String beanName) {
public void setBeanName(String beanName) {
this.beanName = beanName;
}
@@ -171,7 +171,7 @@ final class ConfigurationClass {
* Merge the imported-by declarations from the given configuration class into this one.
* @since 4.0.5
*/
void mergeImportedBy(ConfigurationClass otherConfigClass) {
public void mergeImportedBy(ConfigurationClass otherConfigClass) {
this.importedBy.addAll(otherConfigClass.importedBy);
}
@@ -181,35 +181,35 @@ final class ConfigurationClass {
* @since 4.0.5
* @see #isImported()
*/
Set<ConfigurationClass> getImportedBy() {
public Set<ConfigurationClass> getImportedBy() {
return this.importedBy;
}
void addBeanMethod(BeanMethod method) {
public void addBeanMethod(BeanMethod method) {
this.beanMethods.add(method);
}
Set<BeanMethod> getBeanMethods() {
public Set<BeanMethod> getBeanMethods() {
return this.beanMethods;
}
void addImportedResource(String importedResource, Class<? extends BeanDefinitionReader> readerClass) {
public void addImportedResource(String importedResource, Class<? extends BeanDefinitionReader> readerClass) {
this.importedResources.put(importedResource, readerClass);
}
void addImportBeanDefinitionRegistrar(ImportBeanDefinitionRegistrar registrar, AnnotationMetadata importingClassMetadata) {
public void addImportBeanDefinitionRegistrar(ImportBeanDefinitionRegistrar registrar, AnnotationMetadata importingClassMetadata) {
this.importBeanDefinitionRegistrars.put(registrar, importingClassMetadata);
}
Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> getImportBeanDefinitionRegistrars() {
public Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> getImportBeanDefinitionRegistrars() {
return this.importBeanDefinitionRegistrars;
}
Map<String, Class<? extends BeanDefinitionReader>> getImportedResources() {
public Map<String, Class<? extends BeanDefinitionReader>> getImportedResources() {
return this.importedResources;
}
void validate(ProblemReporter problemReporter) {
public void validate(ProblemReporter problemReporter) {
// A configuration class may not be final (CGLIB limitation) unless it declares proxyBeanMethods=false
Map<String, Object> attributes = this.metadata.getAnnotationAttributes(Configuration.class.getName());
if (attributes != null && (Boolean) attributes.get("proxyBeanMethods")) {
@@ -244,7 +244,7 @@ final class ConfigurationClass {
*/
private class FinalConfigurationProblem extends Problem {
FinalConfigurationProblem() {
public FinalConfigurationProblem() {
super(String.format("@Configuration class '%s' may not be final. Remove the final modifier to continue.",
getSimpleName()), new Location(getResource(), getMetadata()));
}
@@ -75,17 +75,16 @@ import org.springframework.util.ClassUtils;
*
* <p>Registered by default when using {@code <context:annotation-config/>} or
* {@code <context:component-scan/>}. Otherwise, may be declared manually as
* with any other {@link BeanFactoryPostProcessor}.
* with any other BeanFactoryPostProcessor.
*
* <p>This post processor is priority-ordered as it is important that any
* {@link Bean @Bean} methods declared in {@code @Configuration} classes have
* {@link Bean} methods declared in {@code @Configuration} classes have
* their corresponding bean definitions registered before any other
* {@code BeanFactoryPostProcessor} executes.
* {@link BeanFactoryPostProcessor} executes.
*
* @author Chris Beams
* @author Juergen Hoeller
* @author Phillip Webb
* @author Sam Brannen
* @since 3.0
*/
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
@@ -390,30 +389,21 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
AnnotationMetadata annotationMetadata = null;
MethodMetadata methodMetadata = null;
if (beanDef instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) beanDef;
annotationMetadata = annotatedBeanDefinition.getMetadata();
methodMetadata = annotatedBeanDefinition.getFactoryMethodMetadata();
methodMetadata = ((AnnotatedBeanDefinition) beanDef).getFactoryMethodMetadata();
}
if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) {
// Configuration class (full or lite) or a configuration-derived @Bean method
// -> eagerly resolve bean class at this point, unless it's a 'lite' configuration
// or component class without @Bean methods.
// -> resolve bean class at this point...
AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef;
if (!abd.hasBeanClass()) {
boolean liteConfigurationCandidateWithoutBeanMethods =
(ConfigurationClassUtils.CONFIGURATION_CLASS_LITE.equals(configClassAttr) &&
annotationMetadata != null && !ConfigurationClassUtils.hasBeanMethods(annotationMetadata));
if (!liteConfigurationCandidateWithoutBeanMethods) {
try {
abd.resolveBeanClass(this.beanClassLoader);
}
catch (Throwable ex) {
throw new IllegalStateException(
"Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
}
try {
abd.resolveBeanClass(this.beanClassLoader);
}
catch (Throwable ex) {
throw new IllegalStateException(
"Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,7 +46,6 @@ import org.springframework.stereotype.Component;
*
* @author Chris Beams
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.1
*/
abstract class ConfigurationClassUtils {
@@ -163,10 +162,6 @@ abstract class ConfigurationClassUtils {
}
// Finally, let's look for @Bean methods...
return hasBeanMethods(metadata);
}
static boolean hasBeanMethods(AnnotationMetadata metadata) {
try {
return metadata.hasAnnotatedMethods(Bean.class.getName());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,9 +51,18 @@ abstract class ConfigurationMethod {
return new Location(this.configurationClass.getResource(), this.metadata);
}
void validate(ProblemReporter problemReporter) {
String getFullyQualifiedMethodName() {
return this.metadata.getDeclaringClassName() + "#" + this.metadata.getMethodName();
}
static String getShortMethodName(String fullyQualifiedMethodName) {
return fullyQualifiedMethodName.substring(fullyQualifiedMethodName.indexOf('#') + 1);
}
public void validate(ProblemReporter problemReporter) {
}
@Override
public String toString() {
return String.format("[%s:name=%s,declaringClass=%s]",
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 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.
@@ -23,7 +23,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.BeanClassLoaderAware;
@@ -138,22 +137,6 @@ public abstract class AbstractApplicationEventMulticaster
}
}
@Override
public void removeApplicationListeners(Predicate<ApplicationListener<?>> predicate) {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListeners.removeIf(predicate);
this.retrieverCache.clear();
}
}
@Override
public void removeApplicationListenerBeans(Predicate<String> predicate) {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListenerBeans.removeIf(predicate);
this.retrieverCache.clear();
}
}
@Override
public void removeAllListeners() {
synchronized (this.defaultRetriever) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
package org.springframework.context.event;
import java.util.function.Predicate;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.ResolvableType;
@@ -41,68 +39,31 @@ public interface ApplicationEventMulticaster {
/**
* Add a listener to be notified of all events.
* @param listener the listener to add
* @see #removeApplicationListener(ApplicationListener)
* @see #removeApplicationListeners(Predicate)
*/
void addApplicationListener(ApplicationListener<?> listener);
/**
* Add a listener bean to be notified of all events.
* @param listenerBeanName the name of the listener bean to add
* @see #removeApplicationListenerBean(String)
* @see #removeApplicationListenerBeans(Predicate)
*/
void addApplicationListenerBean(String listenerBeanName);
/**
* Remove a listener from the notification list.
* @param listener the listener to remove
* @see #addApplicationListener(ApplicationListener)
* @see #removeApplicationListeners(Predicate)
*/
void removeApplicationListener(ApplicationListener<?> listener);
/**
* Remove a listener bean from the notification list.
* @param listenerBeanName the name of the listener bean to remove
* @see #addApplicationListenerBean(String)
* @see #removeApplicationListenerBeans(Predicate)
*/
void removeApplicationListenerBean(String listenerBeanName);
/**
* Remove all matching listeners from the set of registered
* {@code ApplicationListener} instances (which includes adapter classes
* such as {@link ApplicationListenerMethodAdapter}, e.g. for annotated
* {@link EventListener} methods).
* <p>Note: This just applies to instance registrations, not to listeners
* registered by bean name.
* @param predicate the predicate to identify listener instances to remove,
* e.g. checking {@link SmartApplicationListener#getListenerId()}
* @since 5.3.5
* @see #addApplicationListener(ApplicationListener)
* @see #removeApplicationListener(ApplicationListener)
*/
void removeApplicationListeners(Predicate<ApplicationListener<?>> predicate);
/**
* Remove all matching listener beans from the set of registered
* listener bean names (referring to bean classes which in turn
* implement the {@link ApplicationListener} interface directly).
* <p>Note: This just applies to bean name registrations, not to
* programmatically registered {@code ApplicationListener} instances.
* @param predicate the predicate to identify listener bean names to remove
* @since 5.3.5
* @see #addApplicationListenerBean(String)
* @see #removeApplicationListenerBean(String)
*/
void removeApplicationListenerBeans(Predicate<String> predicate);
/**
* Remove all listeners registered with this multicaster.
* <p>After a remove call, the multicaster will perform no action
* on event notification until new listeners are registered.
* @see #removeApplicationListeners(Predicate)
*/
void removeAllListeners();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.StringJoiner;
import java.util.concurrent.CompletionStage;
import org.apache.commons.logging.Log;
@@ -90,9 +89,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
private final int order;
@Nullable
private volatile String listenerId;
@Nullable
private ApplicationContext applicationContext;
@@ -117,8 +113,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
this.declaredEventTypes = resolveDeclaredEventTypes(method, ann);
this.condition = (ann != null ? ann.condition() : null);
this.order = resolveOrder(this.targetMethod);
String id = (ann != null ? ann.id() : "");
this.listenerId = (!id.isEmpty() ? id : null);
}
private static List<ResolvableType> resolveDeclaredEventTypes(Method method, @Nullable EventListener ann) {
@@ -192,32 +186,6 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
return this.order;
}
@Override
public String getListenerId() {
String id = this.listenerId;
if (id == null) {
id = getDefaultListenerId();
this.listenerId = id;
}
return id;
}
/**
* Determine the default id for the target listener, to be applied in case of
* no {@link EventListener#id() annotation-specified id value}.
* <p>The default implementation builds a method name with parameter types.
* @since 5.3.5
* @see #getListenerId()
*/
protected String getDefaultListenerId() {
Method method = getTargetMethod();
StringJoiner sj = new StringJoiner(",", "(", ")");
for (Class<?> paramType : method.getParameterTypes()) {
sj.add(paramType.getName());
}
return ClassUtils.getQualifiedMethodName(method) + sj.toString();
}
/**
* Process the specified {@link ApplicationEvent}, checking if the condition
@@ -396,7 +364,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
* @param message error message to append the HandlerMethod details to
*/
protected String getDetailedErrorMessage(Object bean, String message) {
StringBuilder sb = new StringBuilder(message).append('\n');
StringBuilder sb = new StringBuilder(message).append("\n");
sb.append("HandlerMethod details: \n");
sb.append("Bean [").append(bean.getClass().getName()).append("]\n");
sb.append("Method [").append(this.method.toGenericString()).append("]\n");
@@ -426,7 +394,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
StringBuilder sb = new StringBuilder(getDetailedErrorMessage(bean, message));
sb.append("Resolved arguments: \n");
for (int i = 0; i < resolvedArgs.length; i++) {
sb.append('[').append(i).append("] ");
sb.append("[").append(i).append("] ");
if (resolvedArgs[i] == null) {
sb.append("[null] \n");
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.function.Predicate;
import org.springframework.context.ApplicationEvent;
import org.springframework.core.annotation.AliasFor;
@@ -84,7 +83,6 @@ import org.springframework.core.annotation.AliasFor;
* @author Sam Brannen
* @since 4.2
* @see EventListenerMethodProcessor
* @see org.springframework.transaction.event.TransactionalEventListener
*/
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@@ -130,13 +128,4 @@ public @interface EventListener {
*/
String condition() default "";
/**
* An optional identifier for the listener, defaulting to the fully-qualified
* signature of the declaring method (e.g. "mypackage.MyClass.myMethod()").
* @since 5.3.5
* @see SmartApplicationListener#getListenerId()
* @see ApplicationEventMulticaster#removeApplicationListeners(Predicate)
*/
String id() default "";
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,9 @@ package org.springframework.context.event;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
/**
* Extended variant of the standard {@link ApplicationListener} interface,
@@ -26,26 +28,13 @@ import org.springframework.core.ResolvableType;
*
* <p>As of Spring Framework 4.2, this interface supersedes the Class-based
* {@link SmartApplicationListener} with full handling of generic event types.
* As of 5.3.5, it formally extends {@link SmartApplicationListener}, adapting
* {@link #supportsEventType(Class)} to {@link #supportsEventType(ResolvableType)}
* with a default method.
*
* @author Stephane Nicoll
* @author Juergen Hoeller
* @since 4.2
* @see SmartApplicationListener
* @see GenericApplicationListenerAdapter
*/
public interface GenericApplicationListener extends SmartApplicationListener {
/**
* Overrides {@link SmartApplicationListener#supportsEventType(Class)} with
* delegation to {@link #supportsEventType(ResolvableType)}.
*/
@Override
default boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return supportsEventType(ResolvableType.forClass(eventType));
}
public interface GenericApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
/**
* Determine whether this listener actually supports the given event type.
@@ -53,4 +42,22 @@ public interface GenericApplicationListener extends SmartApplicationListener {
*/
boolean supportsEventType(ResolvableType eventType);
/**
* Determine whether this listener actually supports the given source type.
* <p>The default implementation always returns {@code true}.
* @param sourceType the source type, or {@code null} if no source
*/
default boolean supportsSourceType(@Nullable Class<?> sourceType) {
return true;
}
/**
* Determine this listener's order in a set of listeners for the same event.
* <p>The default implementation returns {@link #LOWEST_PRECEDENCE}.
*/
@Override
default int getOrder() {
return LOWEST_PRECEDENCE;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,7 +36,7 @@ import org.springframework.util.ConcurrentReferenceHashMap;
* @since 3.0
* @see org.springframework.context.ApplicationListener#onApplicationEvent
*/
public class GenericApplicationListenerAdapter implements GenericApplicationListener {
public class GenericApplicationListenerAdapter implements GenericApplicationListener, SmartApplicationListener {
private static final Map<Class<?>, ResolvableType> eventTypeCache = new ConcurrentReferenceHashMap<>();
@@ -67,10 +67,7 @@ public class GenericApplicationListenerAdapter implements GenericApplicationList
@Override
@SuppressWarnings("unchecked")
public boolean supportsEventType(ResolvableType eventType) {
if (this.delegate instanceof GenericApplicationListener) {
return ((GenericApplicationListener) this.delegate).supportsEventType(eventType);
}
else if (this.delegate instanceof SmartApplicationListener) {
if (this.delegate instanceof SmartApplicationListener) {
Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve();
return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass));
}
@@ -79,6 +76,11 @@ public class GenericApplicationListenerAdapter implements GenericApplicationList
}
}
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return supportsEventType(ResolvableType.forClass(eventType));
}
@Override
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
return !(this.delegate instanceof SmartApplicationListener) ||
@@ -90,12 +92,6 @@ public class GenericApplicationListenerAdapter implements GenericApplicationList
return (this.delegate instanceof Ordered ? ((Ordered) this.delegate).getOrder() : Ordered.LOWEST_PRECEDENCE);
}
@Override
public String getListenerId() {
return (this.delegate instanceof SmartApplicationListener ?
((SmartApplicationListener) this.delegate).getListenerId() : "");
}
@Nullable
private static ResolvableType resolveDeclaredEventType(ApplicationListener<ApplicationEvent> listener) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -59,15 +59,4 @@ public interface SmartApplicationListener extends ApplicationListener<Applicatio
return LOWEST_PRECEDENCE;
}
/**
* Return an optional identifier for the listener.
* <p>The default value is an empty String.
* @since 5.3.5
* @see EventListener#id
* @see ApplicationEventMulticaster#removeApplicationListeners
*/
default String getListenerId() {
return "";
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@ import org.springframework.lang.Nullable;
* @author Stephane Nicoll
* @since 2.0.5
*/
public class SourceFilteringListener implements GenericApplicationListener {
public class SourceFilteringListener implements GenericApplicationListener, SmartApplicationListener {
private final Object source;
@@ -79,6 +79,11 @@ public class SourceFilteringListener implements GenericApplicationListener {
return (this.delegate == null || this.delegate.supportsEventType(eventType));
}
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return supportsEventType(ResolvableType.forType(eventType));
}
@Override
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
return (sourceType != null && sourceType.isInstance(this.source));
@@ -89,11 +94,6 @@ public class SourceFilteringListener implements GenericApplicationListener {
return (this.delegate != null ? this.delegate.getOrder() : Ordered.LOWEST_PRECEDENCE);
}
@Override
public String getListenerId() {
return (this.delegate != null ? this.delegate.getListenerId() : "");
}
/**
* Actually process the event, after having filtered according to the
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,13 +48,13 @@ public final class CandidateComponentsIndexLoader {
public static final String COMPONENTS_RESOURCE_LOCATION = "META-INF/spring.components";
/**
* System property that instructs Spring to ignore the components index, i.e.
* System property that instructs Spring to ignore the index, i.e.
* to always return {@code null} from {@link #loadIndex(ClassLoader)}.
* <p>The default is "false", allowing for regular use of the index. Switching this
* flag to {@code true} fulfills a corner case scenario when an index is partially
* available for some libraries (or use cases) but couldn't be built for the whole
* application. In this case, the application context fallbacks to a regular
* classpath arrangement (i.e. as though no index were present at all).
* classpath arrangement (i.e. as no index was present at all).
*/
public static final String IGNORE_INDEX = "spring.index.ignore";
@@ -46,7 +46,6 @@ import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ApplicationStartupAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
@@ -693,7 +692,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartup.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
@@ -895,8 +894,8 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no BeanFactoryPostProcessor
// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2020 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.
@@ -205,12 +205,12 @@ public class LiveBeansView implements LiveBeansViewMBean, ApplicationContextAwar
}
}
result.append("]\n");
result.append('}');
result.append("}");
if (it.hasNext()) {
result.append(",\n");
}
}
result.append(']');
result.append("]");
return result.toString();
}

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