Compare commits

..

17 Commits

Author SHA1 Message Date
Spring Buildmaster 41fd015eed Release version 5.2.11.RELEASE 2020-11-10 07:09:16 +00:00
Juergen Hoeller e9416b369e Polishing 2020-11-09 18:23:45 +01:00
Juergen Hoeller cde95e1446 Polishing 2020-11-09 13:52:34 +01:00
Sam Brannen da4e37dc1d Do not create intermediate list in MergedAnnotationCollectors.toAnnotationSet()
Prior to this commit, MergedAnnotationCollectors.toAnnotationSet()
created an intermediate ArrayList for storing the results prior to
creating a LinkedHashSet in the finishing step.

Since the creation of the intermediate list is unnecessary, this commit
simplifies the implementation of toAnnotationSet() by using the
Collector.of() factory method that does not accept a `finisher` argument.
The resulting Collector internally uses a `castingIdentity()` function
as the `finisher`.

Closes gh-26031
2020-11-08 15:20:18 +01:00
Rossen Stoyanchev 010d0947c7 Refine logging in StompErrorHandler
Avoid a full stacktrace at ERROR level for a client message that could
not be sent to a MessageChannel.

See gh-26026
2020-11-05 21:51:16 +00:00
Juergen Hoeller 5b06c23a1b Consistent javadoc within SpelCompiler 2020-11-05 18:33:12 +01:00
Juergen Hoeller 7881329cf7 Polishing 2020-11-05 18:18:38 +01:00
Juergen Hoeller 58aa0659cc Suppress NotWritablePropertyException in case of ignoreUnknown=true
Closes gh-25986
2020-11-05 18:15:59 +01:00
Juergen Hoeller dbbedc6c86 Add FullyQualifiedAnnotationBeanNameGenerator.INSTANCE
Closes gh-26025
2020-11-05 18:15:29 +01:00
Juergen Hoeller 09c1e986b9 Upgrade to Hibernate ORM 5.4.23
(cherry picked from commit b815accca9)
2020-11-05 17:54:18 +01:00
Juergen Hoeller 10bff054a9 Reliably refresh metadata for dynamically changing prototype bean class
Closes gh-26019

(cherry picked from commit 412aa06d86)
2020-11-05 17:50:24 +01:00
Sam Brannen e713e0d6d5 Preserve registration order in @ActiveProfiles
With this commit, bean definition profiles declared via @ActiveProfiles
are once again stored in registration order, in order to support use
cases in Spring Boot and other frameworks that depend on the
registration order.

This effectively reverts the changes made in conjunction with gh-25973.

Closes gh-26004
2020-11-02 22:40:59 +01:00
Rossen Stoyanchev b4f8fc8177 Use static accessors in DefaultSimpUserRegistry
Closes gh-26010
2020-11-02 17:32:12 +00:00
Rossen Stoyanchev 8c3cdc6118 Remove unused import 2020-10-30 18:43:19 +00:00
Rossen Stoyanchev 01827fd8d2 Ensure response not closed by MappingJackson2HttpMessageConverter
Closes gh-25987
2020-10-30 18:42:11 +00:00
Stephane Nicoll af1d721aa3 Fix a broken Asciidoctor syntax in core-resources.adoc
Closes gh-26000
2020-10-30 09:33:36 +01:00
Arjen Poutsma 0acb1e5513 Copy default headers, cookies in WebClient builder
This commit makes copies of the default headers and cookies when a
WebClient is built, so that subsequent changes to these do not affect
previously built clients.

Closes: gh-25992
2020-10-29 13:36:26 +01:00
3478 changed files with 69640 additions and 126162 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
<!--
!!! For Security Vulnerabilities, please go to https://spring.io/security-policy !!!
!!! For Security Vulnerabilities, please go to https://pivotal.io/security !!!
-->
**Affects:** \<Spring Framework version>
@@ -14,4 +14,4 @@ Thanks for taking the time to create an issue. Please read the following:
Issue or Pull Request? Create only one, not both. GitHub treats them as the same.
If unsure, start with an issue, and if you submit a pull request later, the
issue will be closed as superseded.
-->
-->
@@ -1,13 +1,10 @@
name: "Validate Gradle Wrapper"
on: [push, pull_request]
permissions:
contents: read
jobs:
validation:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1
-6
View File
@@ -21,14 +21,11 @@ classes/
/build
buildSrc/build
/spring-*/build
/spring-core/graalvm/build
/spring-core/kotlin-coroutines/build
/framework-bom/build
/framework-docs/build
/integration-tests/build
/src/asciidoc/build
target/
/target/
# Eclipse artifacts, including WTP generated manifests
.classpath
@@ -44,6 +41,3 @@ out
test-output
atlassian-ide-plugin.xml
.gradletasknamecache
# VS Code
.vscode/
+22 -32
View File
@@ -1,33 +1,23 @@
Juergen Hoeller <jhoeller@vmware.com>
Juergen Hoeller <jhoeller@vmware.com> <jhoeller@pivotal.io>
Juergen Hoeller <jhoeller@vmware.com> <jhoeller@gopivotal.com>
Rossen Stoyanchev <rstoyanchev@vmware.com>
Rossen Stoyanchev <rstoyanchev@vmware.com> <rstoyanchev@pivotal.io>
Rossen Stoyanchev <rstoyanchev@vmware.com> <rstoyanchev@gopivotal.com>
Phillip Webb <pwebb@vmware.com>
Phillip Webb <pwebb@vmware.com> <pwebb@pivotal.io>
Phillip Webb <pwebb@vmware.com> <pwebb@gopivotal.com>
Chris Beams <cbeams@vmware.com>
Chris Beams <cbeams@vmware.com> <cbeams@pivotal.io>
Chris Beams <cbeams@vmware.com> <cbeams@gopivotal.com>
Arjen Poutsma <apoutsma@vmware.com>
Arjen Poutsma <apoutsma@vmware.com> <apoutsma@pivotal.io>
Arjen Poutsma <apoutsma@vmware.com> <apoutsma@gopivotal.com>
Arjen Poutsma <apoutsma@vmware.com> <poutsma@mac.com>
Oliver Drotbohm <odrotbohm@vmware.com>
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@vmware.com>
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@pivotal.io>
Oliver Drotbohm <odrotbohm@vmware.com> <ogierke@gopivotal.com>
Dave Syer <dsyer@vmware.com>
Dave Syer <dsyer@vmware.com> <dsyer@pivotal.io>
Dave Syer <dsyer@vmware.com> <dsyer@gopivotal.com>
Dave Syer <dsyer@vmware.com> <david_syer@hotmail.com>
Andy Clement <aclement@vmware.com>
Andy Clement <aclement@vmware.com> <aclement@pivotal.io>
Andy Clement <aclement@vmware.com> <aclement@gopivotal.com>
Andy Clement <aclement@vmware.com> <andrew.clement@gmail.com>
Sam Brannen <sbrannen@vmware.com>
Sam Brannen <sbrannen@vmware.com> <sbrannen@pivotal.io>
Sam Brannen <sbrannen@vmware.com> <sam@sambrannen.com>
Juergen Hoeller <jhoeller@pivotal.io> jhoeller <jhoeller@vmware.com>
<jhoeller@pivotal.io> <jhoeller@vmware.com>
<jhoeller@pivotal.io> <jhoeller@gopivotal.com>
<rstoyanchev@pivotal.io> <rstoyanchev@vmware.com>
<rstoyanchev@pivotal.io> <rstoyanchev@gopivotal.com>
<pwebb@pivotal.io> <pwebb@vmware.com>
<pwebb@pivotal.io> <pwebb@gopivotal.com>
<cbeams@pivotal.io> <cbeams@vmware.com>
<cbeams@pivotal.io> <cbeams@gopivotal.com>
<cbeams@pivotal.io> <cbeams@gmail.com>
<apoutsma@pivotal.io> <apoutsma@vmware.com>
<apoutsma@pivotal.io> <apoutsma@gopivotal.com>
<apoutsma@pivotal.io> <poutsma@mac.com>
<ogierke@pivotal.io> <ogierke@vmware.com>
<ogierke@pivotal.io> <ogierke@gopivotal.com>
<dsyer@pivotal.io> <dsyer@vmware.com>
<dsyer@pivotal.io> <dsyer@gopivotal.com>
<dsyer@pivotal.io> <david_syer@hotmail.com>
<aclement@pivotal.io> <aclement@vmware.com>
<aclement@pivotal.io> <aclement@gopivotal.com>
<aclement@pivotal.io> <andrew.clement@gmail.com>
<dmitry.katsubo@gmail.com> <dmitry.katsubo@gmai.com>
Nick Williams <nicholas@nicholaswilliams.net>
Nick Williams <nicholas@nicholaswilliams.net> Nicholas Williams <nicholas@nicholaswilliams.net>
-3
View File
@@ -1,3 +0,0 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=8.0.362-librca
+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`.
+3 -11
View File
@@ -1,4 +1,4 @@
# <img src="src/docs/spring-framework.png" width="80" height="80"> Spring Framework [![Build Status](https://ci.spring.io/api/v1/teams/spring-framework/pipelines/spring-framework-5.3.x/jobs/build/badge)](https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-5.3.x?groups=Build") [![Revved up by Gradle Enterprise](https://img.shields.io/badge/Revved%20up%20by-Gradle%20Enterprise-06A0CE?logo=Gradle&labelColor=02303A)](https://ge.spring.io/scans?search.rootProjectNames=spring)
# <img src="src/docs/asciidoc/images/spring-framework.png" width="80" height="80"> Spring Framework [![Build Status](https://build.spring.io/plugins/servlet/wittified/build-status/SPR-PUBM)](https://build.spring.io/browse/SPR)
This is the home of the Spring Framework: the foundation for all [Spring projects](https://spring.io/projects). Collectively the Spring Framework and the family of Spring projects are often referred to simply as "Spring".
@@ -14,20 +14,12 @@ For access to artifacts or a distribution zip, see the [Spring Framework Artifac
## Documentation
The Spring Framework maintains reference documentation ([published](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and [source](src/docs/asciidoc)), GitHub [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
The Spring Framework maintains reference documentation ([published](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/) and [source](src/docs/asciidoc)), Github [wiki pages](https://github.com/spring-projects/spring-framework/wiki), and an
[API reference](https://docs.spring.io/spring-framework/docs/current/javadoc-api/). There are also [guides and tutorials](https://spring.io/guides) across Spring projects.
## Micro-Benchmarks
See the [Micro-Benchmarks](https://github.com/spring-projects/spring-framework/wiki/Micro-Benchmarks) wiki page.
## Build from Source
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.
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.
## Stay in Touch
+1 -1
View File
@@ -8,4 +8,4 @@ wiki page.
## Reporting a Vulnerability
Please see https://spring.io/security-policy.
Please see https://pivotal.io/security.
+109 -140
View File
@@ -1,19 +1,19 @@
plugins {
id 'io.spring.dependency-management' version '1.0.11.RELEASE' apply false
id 'io.spring.nohttp' version '0.0.10'
id 'io.freefair.aspectj' version '6.2.0' apply false
id 'org.jetbrains.dokka' version '1.6.10' apply false
id 'org.jetbrains.kotlin.jvm' version '1.5.32' apply false
id 'org.jetbrains.kotlin.plugin.serialization' version "1.5.32" apply false
id 'org.asciidoctor.jvm.convert' version '3.3.2'
id 'org.asciidoctor.jvm.pdf' version '3.3.2'
id 'org.unbroken-dome.xjc' version '2.0.0' apply false
id 'com.github.ben-manes.versions' version '0.39.0'
id 'com.github.johnrengelman.shadow' version '7.0.0' apply false
id 'de.undercouch.download' version '4.1.2'
id 'me.champeau.jmh' version "0.6.6" apply false
id 'io.spring.dependency-management' version '1.0.9.RELEASE' apply false
id 'io.spring.gradle-enterprise-conventions' version '0.0.2'
id 'io.spring.nohttp' version '0.0.5.RELEASE'
id 'org.jetbrains.kotlin.jvm' version '1.3.72' apply false
id 'org.jetbrains.dokka' version '0.10.1' apply false
id 'org.asciidoctor.jvm.convert' version '2.4.0'
id 'org.asciidoctor.jvm.pdf' version '2.4.0'
id 'de.undercouch.download' version '4.1.1'
id "io.freefair.aspectj" version '4.1.6' apply false
id 'com.gradle.build-scan' version '3.2'
id "com.jfrog.artifactory" version '4.12.0' apply false
id "com.github.ben-manes.versions" version '0.24.0'
}
apply from: "$rootDir/gradle/build-scan-user-data.gradle"
ext {
moduleProjects = subprojects.findAll { it.name.startsWith("spring-") }
javaProjects = subprojects - project(":framework-bom")
@@ -27,63 +27,56 @@ configure(allprojects) { project ->
dependencyManagement {
imports {
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.7"
mavenBom "io.netty:netty-bom:4.1.90.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.30"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR13"
mavenBom "io.rsocket:rsocket-bom:1.1.3"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.51.v20230217"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.32"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2"
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2"
mavenBom "org.junit:junit-bom:5.8.2"
mavenBom "com.fasterxml.jackson:jackson-bom:2.10.5"
mavenBom "io.netty:netty-bom:4.1.51.Final"
mavenBom "io.projectreactor:reactor-bom:Dysprosium-SR13"
mavenBom "io.rsocket:rsocket-bom:1.0.3"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.31.v20200723"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.3.72"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.3.5"
mavenBom "org.junit:junit-bom:5.6.3"
}
dependencies {
dependencySet(group: 'org.apache.logging.log4j', version: '2.20.0') {
dependencySet(group: 'org.apache.logging.log4j', version: '2.13.3') {
entry 'log4j-api'
entry 'log4j-core'
entry 'log4j-jul'
entry 'log4j-slf4j-impl'
}
dependency "org.slf4j:slf4j-api:1.7.36"
dependency("com.google.code.findbugs:findbugs:3.0.1") {
exclude group: "dom4j", name: "dom4j"
}
dependency "org.slf4j:slf4j-api:1.7.30"
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.9') {
dependencySet(group: 'org.codehaus.groovy', version: '2.5.13') {
entry 'groovy'
entry 'groovy-jsr223'
entry 'groovy-templates' // requires findbugs for warning-free compilation
entry 'groovy-templates'
entry 'groovy-test'
entry 'groovy-xml'
}
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.1.5"
dependency "io.smallrye.reactive:mutiny:1.8.0"
dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE"
dependency "io.reactivex.rxjava2:rxjava:2.2.19"
dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE"
dependency "com.caucho:hessian:4.0.63"
dependency "com.fasterxml:aalto-xml:1.3.1"
dependency("com.fasterxml.woodstox:woodstox-core:6.2.8") {
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.9"
dependency "com.google.protobuf:protobuf-java-util:3.19.3"
dependency "com.google.code.gson:gson:2.8.6"
dependency "com.google.protobuf:protobuf-java-util:3.11.4"
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
dependency("com.thoughtworks.xstream:xstream:1.4.19") {
dependency("com.thoughtworks.xstream:xstream:1.4.11.1") {
exclude group: "xpp3", name: "xpp3_min"
exclude group: "xmlpull", name: "xmlpull"
}
dependency "org.apache.johnzon:johnzon-jsonb:1.2.18"
dependency "org.apache.johnzon:johnzon-jsonb:1.2.8"
dependency("org.codehaus.jettison:jettison:1.3.8") {
exclude group: "stax", name: "stax-api"
}
@@ -92,16 +85,16 @@ configure(allprojects) { project ->
entry 'jibx-run'
}
dependency "org.ogce:xpp3:1.1.6"
dependency "org.yaml:snakeyaml:1.33"
dependency "org.yaml:snakeyaml:1.27"
dependency "com.h2database:h2:2.1.214"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.3"
dependency "com.github.librepdf:openpdf:1.3.30"
dependency "com.rometools:rome:1.18.0"
dependency "com.h2database:h2:1.4.200"
dependency "com.github.ben-manes.caffeine:caffeine:2.8.6"
dependency "com.github.librepdf:openpdf:1.3.22"
dependency "com.rometools:rome:1.12.2"
dependency "commons-io:commons-io:2.5"
dependency "io.vavr:vavr:0.10.4"
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.8.0') {
entry 'activemq-broker'
entry('activemq-kahadb-store') {
exclude group: "org.springframework", name: "spring-context"
@@ -109,107 +102,103 @@ configure(allprojects) { project ->
entry 'activemq-stomp'
}
dependency "org.apache.bcel:bcel:6.0"
dependency "org.apache.commons:commons-pool2:2.9.0"
dependency "org.apache.commons:commons-pool2:2.8.1"
dependencySet(group: 'org.apache.derby', version: '10.14.2.0') {
entry 'derby'
entry 'derbyclient'
}
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.33.Final"
dependency "org.hibernate:hibernate-validator:6.2.5.Final"
dependency "org.webjars:webjars-locator-core:0.48"
dependency "org.hibernate:hibernate-core:5.4.23.Final"
dependency "org.hibernate:hibernate-validator:6.1.6.Final"
dependency "org.webjars:webjars-locator-core:0.46"
dependency "org.webjars:underscorejs:1.8.3"
dependencySet(group: 'org.apache.tomcat', version: '9.0.73') {
dependencySet(group: 'org.apache.tomcat', version: '9.0.37') {
entry 'tomcat-util'
entry('tomcat-websocket') {
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
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.73') {
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.37') {
entry 'tomcat-embed-core'
entry 'tomcat-embed-websocket'
}
dependencySet(group: 'io.undertow', version: '2.2.23.Final') {
dependencySet(group: 'io.undertow', version: '2.0.32.Final') {
entry 'undertow-core'
entry('undertow-servlet') {
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_4.0_spec"
exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.3_spec"
}
entry('undertow-websockets-jsr') {
exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec"
}
entry('undertow-servlet') {
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_3.1_spec"
exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.2_spec"
}
}
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.13"
dependency 'org.apache.httpcomponents.client5:httpclient5:5.1.3'
dependency 'org.apache.httpcomponents.core5:httpcore5-reactive:5.1.3'
dependency("org.apache.httpcomponents:httpclient:4.5.13") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.apache.httpcomponents:httpasyncclient:4.1.5") {
exclude group: "commons-logging", name: "commons-logging"
}
dependencySet(group: 'com.squareup.okhttp3', version: '3.14.9') {
entry 'okhttp'
entry 'mockwebserver'
}
dependency("org.apache.httpcomponents:httpclient:4.5.12") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.apache.httpcomponents:httpasyncclient:4.1.4") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency "org.eclipse.jetty:jetty-reactive-httpclient:1.1.4"
dependency "org.jruby:jruby:9.2.20.1"
dependency "org.jruby:jruby:9.2.11.1"
dependency "org.python:jython-standalone:2.7.1"
dependency "org.mozilla:rhino:1.7.11"
dependency "commons-fileupload:commons-fileupload:1.4"
dependency "org.synchronoss.cloud:nio-multipart-parser:1.1.0"
dependency("org.dom4j:dom4j:2.1.3") {
exclude group: "jaxen", name: "jaxen"
exclude group: "net.java.dev.msv", name: "xsdlib"
exclude group: "pull-parser", name: "pull-parser"
exclude group: "xpp3", name: "xpp3"
dependency("dom4j:dom4j:1.6.1") {
exclude group: "xml-apis", name: "xml-apis"
}
dependency("jaxen:jaxen:1.2.0") {
exclude group: "dom4j", name: "dom4j"
dependency("jaxen:jaxen:1.1.1") {
exclude group: "xml-apis", name: "xml-apis"
exclude group: "xom", name: "xom"
exclude group: "xerces", name: "xercesImpl"
}
dependency("junit:junit:4.13.2") {
dependency("junit:junit:4.12") {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
dependency("de.bechte.junit:junit-hierarchicalcontextrunner:4.12.1") {
exclude group: "junit", name: "junit"
}
dependency "org.testng:testng:7.4.0"
dependency "org.junit.support:testng-engine:1.0.4"
dependency "org.hamcrest:hamcrest:2.2"
dependency "org.testng:testng:6.14.3"
dependency "org.hamcrest:hamcrest:2.1"
dependency "org.awaitility:awaitility:3.1.6"
dependency "org.assertj:assertj-core:3.24.2"
dependencySet(group: 'org.xmlunit', version: '2.9.0') {
dependency "org.assertj:assertj-core:3.17.2"
dependencySet(group: 'org.xmlunit', version: '2.6.2') {
entry 'xmlunit-assertj'
entry('xmlunit-matchers') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
}
dependencySet(group: 'org.mockito', version: '4.9.0') { // spring-beans tests fail with 4.10+
dependencySet(group: 'org.mockito', version: '3.3.3') {
entry('mockito-core') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
entry 'mockito-junit-jupiter'
}
dependency "io.mockk:mockk:1.12.1"
dependency "io.mockk:mockk:1.10.0"
dependency("net.sourceforge.htmlunit:htmlunit:2.70.0") {
dependency("net.sourceforge.htmlunit:htmlunit:2.43.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:htmlunit-driver:2.70.0") {
dependency("org.seleniumhq.selenium:htmlunit-driver:2.43.1") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
@@ -217,8 +206,7 @@ configure(allprojects) { project ->
exclude group: "io.netty", name: "netty"
}
dependency "org.skyscreamer:jsonassert:1.5.0"
dependency "com.jayway.jsonpath:json-path:2.7.0"
dependency "org.bouncycastle:bcpkix-jdk18on:1.71"
dependency "com.jayway.jsonpath:json-path:2.4.0"
dependencySet(group: 'org.apache.tiles', version: '3.0.8') {
entry 'tiles-api'
@@ -237,8 +225,8 @@ configure(allprojects) { project ->
dependency "com.ibm.websphere:uow:6.0.2.17"
dependency "com.jamonapi:jamon:2.82"
dependency "joda-time:joda-time:2.10.13"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.10"
dependency "joda-time:joda-time:2.10.6"
dependency "org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.7"
dependency "org.javamoney:moneta:1.3"
dependency "com.sun.activation:javax.activation:1.2.0"
@@ -309,23 +297,21 @@ 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"
apply from: "${rootDir}/gradle/docs-dokka.gradle"
compileKotlin {
kotlinOptions {
languageVersion = "1.3"
apiVersion = "1.3"
freeCompilerArgs = ["-Xjsr305=strict", "-Xsuppress-version-warnings", "-Xopt-in=kotlin.RequiresOptIn"]
jvmTarget = "1.8"
freeCompilerArgs = ["-Xjsr305=strict"]
allWarningsAsErrors = true
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs = ["-Xjsr305=strict"]
}
}
@@ -340,36 +326,35 @@ configure([rootProject] + javaProjects) { project ->
}
checkstyle {
toolVersion = "10.9.1"
configDirectory.set(rootProject.file("src/checkstyle"))
toolVersion = "8.36.2"
configDir = rootProject.file("src/checkstyle")
}
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.junit.jupiter:junit-jupiter-params")
testImplementation("org.junit.platform:junit-platform-suite-api")
testImplementation("org.mockito:mockito-core")
testImplementation("org.mockito:mockito-junit-jupiter")
testImplementation("io.mockk:mockk")
testImplementation("org.assertj:assertj-core")
testCompile("org.junit.jupiter:junit-jupiter-api")
testCompile("org.junit.jupiter:junit-jupiter-params")
testCompile("org.mockito:mockito-core")
testCompile("org.mockito:mockito-junit-jupiter")
testCompile("io.mockk:mockk")
testCompile("org.assertj:assertj-core")
// Pull in the latest JUnit 5 Launcher API to ensure proper support in IDEs.
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testRuntimeOnly("org.junit.platform:junit-platform-suite-engine")
testRuntimeOnly("org.apache.logging.log4j:log4j-core")
testRuntimeOnly("org.apache.logging.log4j:log4j-jul")
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl")
testRuntime("org.junit.platform:junit-platform-launcher")
testRuntime("org.junit.jupiter:junit-jupiter-engine")
testRuntime("org.apache.logging.log4j:log4j-core")
testRuntime("org.apache.logging.log4j:log4j-slf4j-impl")
testRuntime("org.apache.logging.log4j:log4j-jul")
// JSR-305 only used for non-required meta-annotations
compileOnly("com.google.code.findbugs:jsr305")
testCompileOnly("com.google.code.findbugs:jsr305")
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.31")
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.15")
}
ext.javadocLinks = [
"https://docs.oracle.com/javase/8/docs/api/",
"https://docs.oracle.com/javaee/7/api/",
"https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ
"https://www.ibm.com/docs/api/v1/content/SSEQTP_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/",
"https://www.ibm.com/support/knowledgecenter/SS7JFU_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/",
"https://glassfish.java.net/nonav/docs/v3/api/",
"https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/",
"https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/",
"https://tiles.apache.org/tiles-request/apidocs/",
@@ -377,24 +362,12 @@ configure([rootProject] + javaProjects) { project ->
"https://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
"https://www.ehcache.org/apidocs/2.10.4/",
"https://www.quartz-scheduler.org/api/2.3.0/",
"https://www.javadoc.io/doc/com.fasterxml.jackson.core/jackson-core/2.12.7/",
"https://www.javadoc.io/doc/com.fasterxml.jackson.core/jackson-databind/2.12.7/",
"https://www.javadoc.io/doc/com.fasterxml.jackson.dataformat/jackson-dataformat-xml/2.12.7/",
"https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/",
"https://projectreactor.io/docs/test/release/api/",
"https://junit.org/junit4/javadoc/4.13.2/",
// Disabling linking to JUnit 5.8.2, since the `package-list` file no longer exists due to
// https://github.com/junit-team/junit5/commit/67ad4e545518b0ce2b0e7c96df31a669866d5003.
// "https://junit.org/junit5/docs/5.8.2/api/",
"https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/",
"https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/",
"https://r2dbc.io/spec/0.8.5.RELEASE/api/",
// The external Javadoc link for JSR 305 must come last to ensure that types from
// JSR 250 (such as @PostConstruct) are still supported. This is due to the fact
// that JSR 250 and JSR 305 both define types in javax.annotation, which results
// in a split package, and the javadoc tool does not support split packages
// across multiple external Javadoc sites.
"https://www.javadoc.io/doc/com.google.code.findbugs/jsr305/3.0.2/"
"https://fasterxml.github.io/jackson-core/javadoc/2.10/",
"https://fasterxml.github.io/jackson-databind/javadoc/2.10/",
"https://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.10/",
"https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/",
"https://junit.org/junit4/javadoc/4.12/",
"https://junit.org/junit5/docs/5.6.3/api/"
] as String[]
}
@@ -405,6 +378,7 @@ configure(moduleProjects) { project ->
configure(rootProject) {
description = "Spring Framework"
apply plugin: "groovy"
apply plugin: "kotlin"
apply plugin: "io.spring.nohttp"
apply plugin: 'org.springframework.build.api-diff'
@@ -415,7 +389,7 @@ configure(rootProject) {
source.exclude "**/test-output/**"
allowlistFile = project.file("src/nohttp/allowlist.lines")
def rootPath = file(rootDir).toPath()
def projectDirs = allprojects.collect { it.projectDir } + "${rootDir}/spring-core-test" + "${rootDir}/buildSrc" + "${rootDir}/framework-docs"
def projectDirs = allprojects.collect { it.projectDir } + "${rootDir}/buildSrc"
projectDirs.forEach { dir ->
[ 'bin', 'build', 'out', '.settings' ]
.collect { rootPath.relativize(new File(dir, it).toPath()) }
@@ -426,10 +400,6 @@ configure(rootProject) {
}
}
tasks.named("checkstyleNohttp").configure {
maxHeapSize = "1g"
}
publishing {
publications {
mavenJava(MavenPublication) {
@@ -439,5 +409,4 @@ configure(rootProject) {
}
}
}
}
+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
+2 -1
View File
@@ -8,7 +8,8 @@ repositories {
}
dependencies {
implementation "me.champeau.gradle:japicmp-gradle-plugin:0.3.0"
implementation "me.champeau.gradle:japicmp-gradle-plugin:0.2.8"
implementation "com.google.guava:guava:28.2-jre" // required by japicmp-gradle-plugin
}
gradlePlugin {
+1
View File
@@ -0,0 +1 @@
apply from: "../gradle/build-cache-settings.gradle"
@@ -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,22 +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
* @author Sebastien Deleuze
*/
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;
@@ -44,8 +53,7 @@ public class CompilerConventionsPlugin implements Plugin<Project> {
List<String> commonCompilerArgs = Arrays.asList(
"-Xlint:serial", "-Xlint:cast", "-Xlint:classfile", "-Xlint:dep-ann",
"-Xlint:divzero", "-Xlint:empty", "-Xlint:finally", "-Xlint:overrides",
"-Xlint:path", "-Xlint:processing", "-Xlint:static", "-Xlint:try", "-Xlint:-options",
"-parameters"
"-Xlint:path", "-Xlint:processing", "-Xlint:static", "-Xlint:try", "-Xlint:-options"
);
COMPILER_ARGS = new ArrayList<>();
COMPILER_ARGS.addAll(commonCompilerArgs);
@@ -56,12 +64,12 @@ public class CompilerConventionsPlugin implements Plugin<Project> {
TEST_COMPILER_ARGS = new ArrayList<>();
TEST_COMPILER_ARGS.addAll(commonCompilerArgs);
TEST_COMPILER_ARGS.addAll(Arrays.asList("-Xlint:-varargs", "-Xlint:-fallthrough", "-Xlint:-rawtypes",
"-Xlint:-deprecation", "-Xlint:-unchecked"));
"-Xlint:-deprecation", "-Xlint:-unchecked", "-parameters"));
}
@Override
public void apply(Project project) {
project.getPlugins().withType(JavaLibraryPlugin.class, javaPlugin -> applyJavaCompileConventions(project));
project.getPlugins().withType(JavaPlugin.class, javaPlugin -> applyJavaCompileConventions(project));
}
/**
@@ -71,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 -> {
@@ -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.
@@ -19,7 +19,6 @@ package org.springframework.build.optional;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.attributes.Usage;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSetContainer;
@@ -29,7 +28,7 @@ import org.gradle.plugins.ide.eclipse.model.EclipseModel;
/**
* A {@code Plugin} that adds support for Maven-style optional dependencies. Creates a new
* {@code optional} configuration. The {@code optional} configuration is part of the
* project's compile and runtime classpaths but does not affect the classpath of
* project's compile and runtime classpath's but does not affect the classpath of
* dependent projects.
*
* @author Andy Wilkinson
@@ -44,16 +43,22 @@ public class OptionalDependenciesPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
Configuration optional = project.getConfigurations().create("optional");
optional.setCanBeConsumed(false);
optional.setCanBeResolved(false);
project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> {
SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class)
.getSourceSets();
SourceSetContainer sourceSets = project.getConvention()
.getPlugin(JavaPluginConvention.class).getSourceSets();
sourceSets.all((sourceSet) -> {
project.getConfigurations().getByName(sourceSet.getCompileClasspathConfigurationName()).extendsFrom(optional);
project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName()).extendsFrom(optional);
sourceSet.setCompileClasspath(
sourceSet.getCompileClasspath().plus(optional));
sourceSet.setRuntimeClasspath(
sourceSet.getRuntimeClasspath().plus(optional));
});
});
project.getPlugins().withType(EclipsePlugin.class, (eclipePlugin) -> {
project.getExtensions().getByType(EclipseModel.class)
.classpath((classpath) -> {
classpath.getPlusConfigurations().add(optional);
});
});
}
}
-57
View File
@@ -1,57 +0,0 @@
== 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].
=== Setting up your development environment
If you're part of the Spring Framework project on GitHub, you can get access to CI management features.
First, you need to go to https://ci.spring.io and install the client CLI for your platform (see bottom right of the screen).
You can then login with the instance using:
[source]
----
$ fly -t spring login -n spring-framework -c https://ci.spring.io
----
Once logged in, you should get something like:
[source]
----
$ fly ts
name url team expiry
spring https://ci.spring.io spring-framework Wed, 25 Mar 2020 17:45:26 UTC
----
=== 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
* `scripts/` holds the build scripts that ship within the CI container images
* `tasks` contains the task definitions used in the main `pipeline.yml`
=== 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]
----
$ 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.
-20
View File
@@ -1,20 +0,0 @@
changelog:
repository: spring-projects/spring-framework
sections:
- title: ":star: New Features"
labels:
- "type: enhancement"
- title: ":lady_beetle: Bug Fixes"
labels:
- "type: bug"
- "type: regression"
- title: ":notebook_with_decorative_cover: Documentation"
labels:
- "type: documentation"
- title: ":hammer: Dependency Upgrades"
sort: "title"
labels:
- "type: dependency-upgrade"
contributors:
exclude:
names: ["bclozel", "jhoeller", "poutsma", "rstoyanchev", "sbrannen", "sdeleuze", "snicoll"]
-10
View File
@@ -1,10 +0,0 @@
logging:
level:
io.spring.concourse: DEBUG
spring:
main:
banner-mode: off
sonatype:
exclude:
- 'build-info\.json'
- '.*\.zip'
-21
View File
@@ -1,21 +0,0 @@
== CI Images
These images are used by CI to run the actual builds.
To build the image locally run the following from this directory:
----
$ docker build --no-cache -f <image-folder>/Dockerfile .
----
For example
----
$ docker build --no-cache -f spring-framework-ci-image/Dockerfile .
----
To test run:
----
$ docker run -it --entrypoint /bin/bash <SHA>
----
-10
View File
@@ -1,10 +0,0 @@
FROM ubuntu:focal-20220922
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 JDK17 /opt/openjdk/java17
ENV PATH $JAVA_HOME/bin:$PATH
-14
View File
@@ -1,14 +0,0 @@
#!/bin/bash
set -e
case "$1" in
java8)
echo "https://github.com/bell-sw/Liberica/releases/download/8u345+1/bellsoft-jdk8u345+1-linux-amd64.tar.gz"
;;
java17)
echo "https://github.com/bell-sw/Liberica/releases/download/17.0.4+8/bellsoft-jdk17.0.4+8-linux-amd64.tar.gz"
;;
*)
echo $"Unknown java version"
exit 1
esac
-40
View File
@@ -1,40 +0,0 @@
#!/bin/bash
set -ex
###########################################################
# UTILS
###########################################################
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install --no-install-recommends -y tzdata ca-certificates net-tools libxml2-utils git curl libudev1 libxml2-utils iptables iproute2 jq fontconfig
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
###########################################################
# JAVA
###########################################################
mkdir -p /opt/openjdk
pushd /opt/openjdk > /dev/null
for jdk in java8 java17
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
###########################################################
# GRADLE ENTERPRISE
###########################################################
cd /
mkdir ~/.gradle
echo 'systemProp.user.name=concourse' > ~/.gradle/gradle.properties
-11
View File
@@ -1,11 +0,0 @@
github-repo: "https://github.com/spring-projects/spring-framework.git"
github-repo-name: "spring-projects/spring-framework"
sonatype-staging-profile: "org.springframework"
docker-hub-organization: "springci"
artifactory-server: "https://repo.spring.io"
branch: "5.3.x"
milestone: "5.3.x"
build-name: "spring-framework"
pipeline-name: "spring-framework"
concourse-url: "https://ci.spring.io"
task-timeout: 1h00m
-446
View File
@@ -1,446 +0,0 @@
anchors:
git-repo-resource-source: &git-repo-resource-source
uri: ((github-repo))
username: ((github-username))
password: ((github-ci-release-token))
branch: ((branch))
gradle-enterprise-task-params: &gradle-enterprise-task-params
GRADLE_ENTERPRISE_ACCESS_KEY: ((gradle_enterprise_secret_access_key))
GRADLE_ENTERPRISE_CACHE_USERNAME: ((gradle_enterprise_cache_user.username))
GRADLE_ENTERPRISE_CACHE_PASSWORD: ((gradle_enterprise_cache_user.password))
sonatype-task-params: &sonatype-task-params
SONATYPE_USERNAME: ((sonatype-username))
SONATYPE_PASSWORD: ((sonatype-password))
SONATYPE_URL: ((sonatype-url))
SONATYPE_STAGING_PROFILE: ((sonatype-staging-profile))
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
docker-resource-source: &docker-resource-source
username: ((docker-hub-username))
password: ((docker-hub-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!>
[$TEXT_FILE_CONTENT]
text_file: git-repo/build/build-scan-uri.txt
silent: true
icon_emoji: ":concourse:"
username: concourse-ci
changelog-task-params: &changelog-task-params
name: generated-changelog/tag
tag: generated-changelog/tag
body: generated-changelog/changelog.md
github-task-params: &github-task-params
GITHUB_USERNAME: ((github-username))
GITHUB_TOKEN: ((github-ci-release-token))
resource_types:
- name: registry-image
type: registry-image
source:
<<: *docker-resource-source
repository: concourse/registry-image-resource
tag: 1.7.1
- name: artifactory-resource
type: registry-image
source:
<<: *docker-resource-source
repository: springio/artifactory-resource
tag: 0.0.18
- name: github-release
type: registry-image
source:
<<: *docker-resource-source
repository: concourse/github-release-resource
tag: 1.8.0
- name: github-status-resource
type: registry-image
source:
<<: *docker-resource-source
repository: dpb587/github-status-resource
tag: master
- name: pull-request
type: registry-image
source:
<<: *docker-resource-source
repository: teliaoss/github-pr-resource
tag: v0.23.0
- name: slack-notification
type: registry-image
source:
<<: *docker-resource-source
repository: cfcommunity/slack-notification-resource
tag: latest
resources:
- name: git-repo
type: git
icon: github
source:
<<: *git-repo-resource-source
- name: every-morning
type: time
icon: alarm
source:
start: 8:00 AM
stop: 9:00 AM
location: Europe/Vienna
- name: ci-images-git-repo
type: git
icon: github
source:
uri: ((github-repo))
branch: ((branch))
paths: ["ci/images/*"]
- name: ci-image
type: registry-image
icon: docker
source:
<<: *docker-resource-source
repository: ((docker-hub-organization))/spring-framework-ci
tag: ((milestone))
- name: artifactory-repo
type: artifactory-resource
icon: package-variant
source:
uri: ((artifactory-server))
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
source:
repository: ((github-repo-name))
access_token: ((github-ci-status-token))
branch: ((branch))
context: build
- name: repo-status-jdk17-build
type: github-status-resource
icon: eye-check-outline
source:
repository: ((github-repo-name))
access_token: ((github-ci-status-token))
branch: ((branch))
context: jdk17-build
- name: slack-alert
type: slack-notification
icon: slack
source:
url: ((slack-webhook-url))
- name: github-pre-release
type: github-release
icon: briefcase-download-outline
source:
owner: spring-projects
repository: spring-framework
access_token: ((github-ci-release-token))
pre_release: true
release: false
- name: github-release
type: github-release
icon: briefcase-download
source:
owner: spring-projects
repository: spring-framework
access_token: ((github-ci-release-token))
pre_release: false
jobs:
- name: build-ci-images
plan:
- get: git-repo
- get: ci-images-git-repo
trigger: true
- task: build-ci-image
privileged: true
file: git-repo/ci/tasks/build-ci-image.yml
output_mapping:
image: ci-image
vars:
ci-image-name: ci-image
<<: *docker-resource-source
- put: ci-image
params:
image: ci-image/image.tar
- name: build
serial: true
public: true
plan:
- get: 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))
params:
<<: *build-project-task-params
on_failure:
do:
- put: repo-status-build
params: { state: "failure", commit: "git-repo" }
- put: slack-alert
params:
<<: *slack-fail-params
- put: repo-status-build
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}"
build_number: "${BUILD_PIPELINE_NAME}-${BUILD_JOB_NAME}-${BUILD_NAME}"
disable_checksum_uploads: true
threads: 8
artifact_set:
- include:
- "/**/spring-*.zip"
properties:
"zip.name": "spring-framework"
"zip.displayname": "Spring Framework"
"zip.deployed": "false"
- include:
- "/**/spring-*-docs.zip"
properties:
"zip.type": "docs"
- include:
- "/**/spring-*-dist.zip"
properties:
"zip.type": "dist"
- include:
- "/**/spring-*-schema.zip"
properties:
"zip.type": "schema"
get_params:
threads: 8
- name: jdk17-build
serial: true
public: true
plan:
- get: ci-image
- get: git-repo
- get: every-morning
trigger: true
- put: repo-status-jdk17-build
params: { state: "pending", commit: "git-repo" }
- do:
- task: check-project
image: ci-image
file: git-repo/ci/tasks/check-project.yml
privileged: true
timeout: ((task-timeout))
params:
TEST_TOOLCHAIN: 17
<<: *build-project-task-params
on_failure:
do:
- put: repo-status-jdk17-build
params: { state: "failure", commit: "git-repo" }
- put: slack-alert
params:
<<: *slack-fail-params
- put: repo-status-jdk17-build
params: { state: "success", commit: "git-repo" }
- name: build-pull-requests
serial: true
public: true
plan:
- get: ci-image
- get: git-repo
resource: git-pull-request
trigger: true
version: every
- do:
- put: git-pull-request
params:
path: git-repo
status: pending
- task: build-pr
image: ci-image
file: git-repo/ci/tasks/build-pr.yml
privileged: true
timeout: ((task-timeout))
params:
BRANCH: ((branch))
on_success:
put: git-pull-request
params:
path: git-repo
status: success
on_failure:
put: git-pull-request
params:
path: git-repo
status: failure
- name: stage-milestone
serial: true
plan:
- get: ci-image
- get: git-repo
trigger: false
- task: stage
image: ci-image
file: git-repo/ci/tasks/stage-version.yml
params:
RELEASE_TYPE: M
<<: *gradle-enterprise-task-params
- put: artifactory-repo
params:
<<: *artifactory-params
repo: libs-staging-local
- put: git-repo
params:
repository: stage-git-repo
- name: promote-milestone
serial: true
plan:
- get: ci-image
- get: git-repo
trigger: false
- get: artifactory-repo
trigger: false
passed: [stage-milestone]
params:
download_artifacts: false
save_build_info: true
- task: promote
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: M
<<: *artifactory-task-params
- task: generate-changelog
file: git-repo/ci/tasks/generate-changelog.yml
params:
RELEASE_TYPE: M
<<: *github-task-params
- put: github-pre-release
params:
<<: *changelog-task-params
- name: stage-rc
serial: true
plan:
- get: ci-image
- get: git-repo
trigger: false
- task: stage
image: ci-image
file: git-repo/ci/tasks/stage-version.yml
params:
RELEASE_TYPE: RC
<<: *gradle-enterprise-task-params
- put: artifactory-repo
params:
<<: *artifactory-params
repo: libs-staging-local
- put: git-repo
params:
repository: stage-git-repo
- name: promote-rc
serial: true
plan:
- get: ci-image
- get: git-repo
trigger: false
- get: artifactory-repo
trigger: false
passed: [stage-rc]
params:
download_artifacts: false
save_build_info: true
- task: promote
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: RC
<<: *artifactory-task-params
- task: generate-changelog
file: git-repo/ci/tasks/generate-changelog.yml
params:
RELEASE_TYPE: RC
<<: *github-task-params
- put: github-pre-release
params:
<<: *changelog-task-params
- name: stage-release
serial: true
plan:
- get: ci-image
- get: git-repo
trigger: false
- task: stage
image: ci-image
file: git-repo/ci/tasks/stage-version.yml
params:
RELEASE_TYPE: RELEASE
<<: *gradle-enterprise-task-params
- put: artifactory-repo
params:
<<: *artifactory-params
repo: libs-staging-local
- put: git-repo
params:
repository: stage-git-repo
- name: promote-release
serial: true
plan:
- get: ci-image
- get: git-repo
trigger: false
- get: artifactory-repo
trigger: false
passed: [stage-release]
params:
download_artifacts: true
save_build_info: true
- task: promote
file: git-repo/ci/tasks/promote-version.yml
params:
RELEASE_TYPE: RELEASE
<<: *artifactory-task-params
<<: *sonatype-task-params
- name: create-github-release
serial: true
plan:
- get: ci-image
- get: git-repo
- get: artifactory-repo
trigger: true
passed: [promote-release]
params:
download_artifacts: false
save_build_info: true
- task: generate-changelog
file: git-repo/ci/tasks/generate-changelog.yml
params:
RELEASE_TYPE: RELEASE
<<: *github-task-params
- put: github-release
params:
<<: *changelog-task-params
groups:
- name: "builds"
jobs: ["build", "jdk17-build"]
- name: "releases"
jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"]
- name: "ci-images"
jobs: ["build-ci-images"]
- name: "pull-requests"
jobs: [ "build-pull-requests" ]
-8
View File
@@ -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
-9
View File
@@ -1,9 +0,0 @@
#!/bin/bash
set -e
source $(dirname $0)/common.sh
repository=$(pwd)/distribution-repository
pushd git-repo > /dev/null
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 -PdeploymentRepository=${repository} build publishAllPublicationsToDeploymentRepository
popd > /dev/null
-9
View File
@@ -1,9 +0,0 @@
#!/bin/bash
set -e
source $(dirname $0)/common.sh
pushd git-repo > /dev/null
./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK17 \
-PmainToolchain=${MAIN_TOOLCHAIN} -PtestToolchain=${TEST_TOOLCHAIN} --no-daemon --max-workers=4 check
popd > /dev/null
-2
View File
@@ -1,2 +0,0 @@
source /opt/concourse-java.sh
setup_symlinks
-12
View File
@@ -1,12 +0,0 @@
#!/bin/bash
set -e
CONFIG_DIR=git-repo/ci/config
version=$( cat artifactory-repo/build-info.json | jq -r '.buildInfo.modules[0].id' | sed 's/.*:.*:\(.*\)/\1/' )
java -jar /github-changelog-generator.jar \
--spring.config.location=${CONFIG_DIR}/changelog-generator.yml \
${version} generated-changelog/changelog.md
echo ${version} > generated-changelog/version
echo v${version} > generated-changelog/tag
-18
View File
@@ -1,18 +0,0 @@
#!/bin/bash
source $(dirname $0)/common.sh
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 /concourse-release-scripts.jar \
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
publishToCentral $RELEASE_TYPE $BUILD_INFO_LOCATION artifactory-repo || { exit 1; }
java -jar /concourse-release-scripts.jar \
--spring.config.location=${CONFIG_DIR}/release-scripts.yml \
promote $RELEASE_TYPE $BUILD_INFO_LOCATION || { exit 1; }
echo "Promotion complete"
echo $version > version/version
-50
View File
@@ -1,50 +0,0 @@
#!/bin/bash
set -e
source $(dirname $0)/common.sh
repository=$(pwd)/distribution-repository
pushd git-repo > /dev/null
git fetch --tags --all > /dev/null
popd > /dev/null
git clone git-repo stage-git-repo > /dev/null
pushd stage-git-repo > /dev/null
snapshotVersion=$( awk -F '=' '$1 == "version" { print $2 }' gradle.properties )
if [[ $RELEASE_TYPE = "M" ]]; then
stageVersion=$( get_next_milestone_release $snapshotVersion)
nextVersion=$snapshotVersion
elif [[ $RELEASE_TYPE = "RC" ]]; then
stageVersion=$( get_next_rc_release $snapshotVersion)
nextVersion=$snapshotVersion
elif [[ $RELEASE_TYPE = "RELEASE" ]]; then
stageVersion=$( get_next_release $snapshotVersion)
nextVersion=$( bump_version_number $snapshotVersion)
else
echo "Unknown release type $RELEASE_TYPE" >&2; exit 1;
fi
echo "Staging $stageVersion (next version will be $nextVersion)"
sed -i "s/version=$snapshotVersion/version=$stageVersion/" gradle.properties
git config user.name "Spring Builds" > /dev/null
git config user.email "spring-builds@users.noreply.github.com" > /dev/null
git add gradle.properties > /dev/null
git commit -m"Release v$stageVersion" > /dev/null
git tag -a "v$stageVersion" -m"Release v$stageVersion" > /dev/null
./gradlew --no-daemon --max-workers=4 -PdeploymentRepository=${repository} build publishAllPublicationsToDeploymentRepository
git reset --hard HEAD^ > /dev/null
if [[ $nextVersion != $snapshotVersion ]]; then
echo "Setting next development version (v$nextVersion)"
sed -i "s/version=$snapshotVersion/version=$nextVersion/" gradle.properties
git add gradle.properties > /dev/null
git commit -m"Next development version (v$nextVersion)" > /dev/null
fi;
echo "Staging Complete"
popd > /dev/null
-29
View File
@@ -1,29 +0,0 @@
---
platform: linux
image_resource:
type: registry-image
source:
repository: concourse/oci-build-task
tag: 0.10.0
username: ((docker-hub-username))
password: ((docker-hub-password))
inputs:
- name: ci-images-git-repo
outputs:
- name: image
caches:
- path: ci-image-cache
params:
CONTEXT: ci-images-git-repo/ci/images
DOCKERFILE: ci-images-git-repo/ci/images/ci-image/Dockerfile
DOCKER_HUB_AUTH: ((docker-hub-auth))
run:
path: /bin/sh
args:
- "-c"
- |
mkdir -p /root/.docker
cat > /root/.docker/config.json <<EOF
{ "auths": { "https://index.docker.io/v1/": { "auth": "$DOCKER_HUB_AUTH" }}}
EOF
build
-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
-22
View File
@@ -1,22 +0,0 @@
---
platform: linux
inputs:
- name: git-repo
outputs:
- name: distribution-repository
- 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-project.sh
-24
View File
@@ -1,24 +0,0 @@
---
platform: linux
inputs:
- name: git-repo
outputs:
- name: distribution-repository
- name: git-repo
caches:
- path: gradle
params:
BRANCH:
CI: true
MAIN_TOOLCHAIN:
TEST_TOOLCHAIN:
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/check-project.sh
-20
View File
@@ -1,20 +0,0 @@
---
platform: linux
image_resource:
type: registry-image
source:
repository: springio/github-changelog-generator
tag: '0.0.7'
inputs:
- name: git-repo
- name: artifactory-repo
outputs:
- name: generated-changelog
params:
GITHUB_ORGANIZATION:
GITHUB_REPO:
GITHUB_USERNAME:
GITHUB_TOKEN:
RELEASE_TYPE:
run:
path: git-repo/ci/scripts/generate-changelog.sh
-23
View File
@@ -1,23 +0,0 @@
---
platform: linux
image_resource:
type: registry-image
source:
repository: springio/concourse-release-scripts
tag: '0.3.4'
inputs:
- name: git-repo
- name: artifactory-repo
outputs:
- name: version
params:
RELEASE_TYPE:
ARTIFACTORY_SERVER:
ARTIFACTORY_USERNAME:
ARTIFACTORY_PASSWORD:
SONATYPE_USER:
SONATYPE_PASSWORD:
SONATYPE_URL:
SONATYPE_STAGING_PROFILE:
run:
path: git-repo/ci/scripts/promote-version.sh
-17
View File
@@ -1,17 +0,0 @@
---
platform: linux
inputs:
- name: git-repo
outputs:
- name: stage-git-repo
- name: distribution-repository
params:
RELEASE_TYPE:
CI: true
GRADLE_ENTERPRISE_CACHE_USERNAME:
GRADLE_ENTERPRISE_CACHE_PASSWORD:
GRADLE_ENTERPRISE_URL: https://ge.spring.io
caches:
- path: gradle
run:
path: git-repo/ci/scripts/stage-version.sh
+6
View File
@@ -18,6 +18,12 @@ publishing {
mavenJava(MavenPublication) {
artifactId = 'spring-framework-bom'
from components.javaPlatform
// remove scope information from published BOM
pom.withXml {
asNode().dependencyManagement.first().dependencies.first().each {
it.remove(it.scope.first())
}
}
}
}
}
+2 -3
View File
@@ -1,5 +1,4 @@
version=5.3.26
org.gradle.jvmargs=-Xmx2048m
version=5.2.11.RELEASE
org.gradle.jvmargs=-Xmx1536M
org.gradle.caching=true
org.gradle.parallel=true
kotlin.stdlib.default.dependency=false
+18
View File
@@ -0,0 +1,18 @@
buildCache {
local {
enabled = true
}
remote(HttpBuildCache) {
enabled = true
url = 'https://ge.spring.io/cache/'
def cacheUsername = System.getenv('GRADLE_ENTERPRISE_CACHE_USERNAME')
def cachePassword = System.getenv('GRADLE_ENTERPRISE_CACHE_PASSWORD')
if (cacheUsername && cachePassword) {
push = true
credentials {
username = cacheUsername
password = cachePassword
}
}
}
}
+16
View File
@@ -0,0 +1,16 @@
addCustomJavaHomeMetadata()
addCustomJavaSourceVersionMetadata()
void addCustomJavaHomeMetadata() {
def customJavaHome = System.getProperty("customJavaHome")
if (customJavaHome) {
buildScan.value "Custom JAVA_HOME", customJavaHome
}
}
void addCustomJavaSourceVersionMetadata() {
def customJavaSourceVersion = System.getProperty("customJavaSourceVersion")
if (customJavaSourceVersion) {
buildScan.value "Custom Java Source Version", customJavaSourceVersion
}
}
+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)
}
}
}
-30
View File
@@ -1,30 +0,0 @@
tasks.findByName("dokkaHtmlPartial")?.configure {
outputDirectory.set(new File(buildDir, "docs/kdoc"))
dokkaSourceSets {
configureEach {
sourceRoots.setFrom(file("src/main/kotlin"))
classpath.from(sourceSets["main"].runtimeClasspath)
externalDocumentationLink {
url.set(new URL("https://docs.spring.io/spring-framework/docs/current/javadoc-api/"))
}
externalDocumentationLink {
url.set(new URL("https://projectreactor.io/docs/core/release/api/"))
}
externalDocumentationLink {
url.set(new URL("https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/"))
}
externalDocumentationLink {
url.set(new URL("https://kotlin.github.io/kotlinx.coroutines/"))
}
externalDocumentationLink {
url.set(new URL("https://javadoc.io/doc/org.hamcrest/hamcrest/2.1/"))
}
externalDocumentationLink {
url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/"))
}
externalDocumentationLink {
url.set(new URL("https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/"))
}
}
}
}
+64 -29
View File
@@ -3,7 +3,7 @@ configurations {
}
dependencies {
asciidoctorExt("io.spring.asciidoctor:spring-asciidoctor-extensions-block-switch:0.5.0")
asciidoctorExt("io.spring.asciidoctor:spring-asciidoctor-extensions-block-switch:0.4.0.RELEASE")
}
repositories {
@@ -46,9 +46,8 @@ task api(type: Javadoc) {
stylesheetFile = file("src/docs/api/stylesheet.css")
splitIndex = true
links(project.ext.javadocLinks)
addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint
addBooleanOption('Xwerror', true) // fail build on Javadoc warnings
if (JavaVersion.current().isJava9Compatible()) {
addStringOption('Xdoclint:none', '-quiet')
if(JavaVersion.current().isJava9Compatible()) {
addBooleanOption('html5', true)
}
}
@@ -62,18 +61,56 @@ task api(type: Javadoc) {
/**
* Produce KDoc for all Spring Framework modules in "build/docs/kdoc"
*/
pluginManager.withPlugin("kotlin") {
tasks.dokkaHtmlMultiModule.configure {
dependsOn {
tasks.getByName("api")
dokka {
dependsOn {
tasks.getByName("api")
}
doFirst {
configuration {
classpath = moduleProjects.collect { project -> project.jar.outputs.files.getFiles() }.flatten()
classpath += files(moduleProjects.collect { it.sourceSets.main.compileClasspath })
moduleProjects.findAll {
it.pluginManager.hasPlugin("kotlin")
}.each { project ->
def kotlinDirs = project.sourceSets.main.kotlin.srcDirs.collect()
kotlinDirs -= project.sourceSets.main.java.srcDirs
kotlinDirs.each { dir ->
if (dir.exists()) {
sourceRoot {
path = dir.path
}
}
}
}
}
}
outputFormat = "html"
outputDirectory = "$buildDir/docs/kdoc"
configuration {
moduleName = "spring-framework"
externalDocumentationLink {
url = new URL("https://docs.spring.io/spring-framework/docs/$version/javadoc-api/")
packageListUrl = new File(buildDir, "docs/javadoc/package-list").toURI().toURL()
}
externalDocumentationLink {
url = new URL("https://projectreactor.io/docs/core/release/api/")
}
externalDocumentationLink {
url = new URL("https://www.reactive-streams.org/reactive-streams-1.0.1-javadoc/")
}
externalDocumentationLink {
url = new URL("https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/")
}
moduleName.set("spring-framework")
outputDirectory.set(project.file("$buildDir/docs/kdoc"))
}
}
task downloadResources(type: Download) {
def version = "0.2.5"
def version = "0.2.1.RELEASE"
src "https://repo.spring.io/release/io/spring/docresources/" +
"spring-doc-resources/$version/spring-doc-resources-${version}.zip"
dest project.file("$buildDir/docs/spring-doc-resources.zip")
@@ -87,29 +124,27 @@ 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'
modules {
pdf {
version '1.5.0-beta.8'
}
}
fatalWarnings ".*"
options doctype: 'book', eruby: 'erubis'
attributes([
icons: 'font',
idprefix: '',
idseparator: '-',
docinfo: 'shared,private-header', // https://docs.asciidoctor.org/asciidoctor/latest/docinfo/
docinfo: 'shared',
revnumber: project.version,
sectanchors: '',
sectnums: '',
'source-highlighter': 'highlight.js',
highlightjsdir: 'js/highlight',
'highlightjs-theme': 'googlecode',
'highlightjs-theme': 'github', // '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
])
}
@@ -127,7 +162,7 @@ asciidoctor {
logDocuments = true
resources {
from(sourceDir) {
include 'images/*.png', 'css/**', 'js/**'
include 'images/*', 'css/**', 'js/**'
}
from extractDocResources
}
@@ -150,10 +185,10 @@ asciidoctorPdf {
/**
* Zip all docs (API and reference) into a single archive
*/
task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dokkaHtmlMultiModule']) {
task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dokka']) {
group = "Distribution"
description = "Builds -${archiveClassifier} archive containing api and reference " +
"for deployment at https://docs.spring.io/spring-framework/docs/."
"for deployment at https://docs.spring.io/spring-framework/docs."
archiveBaseName.set("spring-framework")
archiveClassifier.set("docs")
@@ -164,12 +199,12 @@ task docsZip(type: Zip, dependsOn: ['api', 'asciidoctor', 'asciidoctorPdf', 'dok
into "javadoc-api"
}
from ("$asciidoctor.outputDir") {
into "reference/html"
into "spring-framework-reference"
}
from ("$asciidoctorPdf.outputDir") {
into "reference/pdf"
into "spring-framework-reference/pdf"
}
from (dokkaHtmlMultiModule.outputDirectory) {
from (dokka) {
into "kdoc-api"
}
}
@@ -226,11 +261,11 @@ task distZip(type: Zip, dependsOn: [docsZip, schemaZip]) {
expand(copyright: new Date().format("yyyy"), version: project.version)
}
from(zipTree(docsZip.archiveFile)) {
from(zipTree(docsZip.archivePath)) {
into "${baseDir}/docs"
}
from(zipTree(schemaZip.archiveFile)) {
from(zipTree(schemaZip.archivePath)) {
into "${baseDir}/schema"
}
+67 -37
View File
@@ -1,7 +1,7 @@
import org.gradle.plugins.ide.eclipse.model.ProjectDependency
import org.gradle.plugins.ide.eclipse.model.SourceFolder
apply plugin: 'eclipse'
apply plugin: "eclipse"
eclipse.jdt {
sourceCompatibility = 1.8
@@ -18,73 +18,103 @@ eclipse.classpath.file.whenMerged { classpath ->
if (matcher) {
def projectName = matcher[0][1]
def path = "/${projectName}"
if (!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) {
def recursiveDependency = entry.path.matches('.+/' + projectName + '/build/([^/]+/)+(?:main|test)')
// Avoid recursive dependency on current project.
if (!recursiveDependency) {
classpath.entries.add(new ProjectDependency(path))
}
if(!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) {
def dependency = new ProjectDependency(path)
dependency.exported = true
classpath.entries.add(dependency)
}
classpath.entries.remove(entry)
}
}
// Remove any remaining direct depencencies on JARs in the build/libs folder
// except Spring's spring-cglib-repack and spring-objenesis-repack JARs.
classpath.entries.removeAll { entry -> (entry.path =~ /(?!.*?repack.*\.jar).*?\/([^\/]+)\/build\/libs\/[^\/]+\.jar/) }
}
// Use separate main/test outputs (prevents WTP from packaging test classes)
eclipse.classpath.defaultOutputDir = file(project.name + '/bin/eclipse')
eclipse.classpath.defaultOutputDir = file(project.name+"/bin/eclipse")
eclipse.classpath.file.beforeMerged { classpath ->
classpath.entries.findAll{ it instanceof SourceFolder }.each {
if (it.output.startsWith('bin/')) {
if(it.output.startsWith("bin/")) {
it.output = null
}
}
}
eclipse.classpath.file.whenMerged {
entries.findAll{ it instanceof SourceFolder }.each {
it.output = 'bin/' + it.path.split('/')[1]
eclipse.classpath.file.whenMerged { classpath ->
classpath.entries.findAll{ it instanceof SourceFolder }.each {
it.output = "bin/" + it.path.split("/")[1]
}
}
// Ensure project dependencies come after 3rd-party libs (SPR-11836)
// https://jira.spring.io/browse/SPR-11836
eclipse.classpath.file.whenMerged {
entries.findAll { it instanceof ProjectDependency }.each {
eclipse.classpath.file.whenMerged { classpath ->
classpath.entries.findAll { it instanceof ProjectDependency }.each {
// delete from original position
entries.remove(it)
classpath.entries.remove(it)
// append to end of classpath
entries.add(it)
classpath.entries.add(it)
}
}
// Ensure that JMH sources and resources are treated as test classpath entries
// so that they can see test fixtures.
// https://github.com/melix/jmh-gradle-plugin/issues/157
eclipse.classpath.file.whenMerged {
entries.findAll { it.path =~ /src\/jmh\/(java|resources)/ }.each {
it.entryAttributes['test'] = 'true'
}
}
// Allow projects to be used as WTP modules
eclipse.project.natures "org.eclipse.wst.common.project.facet.core.nature"
// Include project specific settings
task eclipseSettings(type: Copy) {
from rootProject.files(
'src/eclipse/org.eclipse.core.resources.prefs',
'src/eclipse/org.eclipse.jdt.core.prefs',
'src/eclipse/org.eclipse.jdt.ui.prefs')
"src/eclipse/org.eclipse.jdt.ui.prefs",
"src/eclipse/org.eclipse.wst.common.project.facet.core.xml")
into project.file('.settings/')
outputs.upToDateWhen { false }
}
task cleanEclipseSettings(type: Delete) {
delete project.file('.settings/org.eclipse.core.resources.prefs')
delete project.file('.settings/org.eclipse.jdt.core.prefs')
delete project.file('.settings/org.eclipse.jdt.ui.prefs')
task eclipseWstComponent(type: Copy) {
from rootProject.files(
"src/eclipse/org.eclipse.wst.common.component")
into project.file('.settings/')
expand(deployname: project.name)
outputs.upToDateWhen { false }
}
tasks['eclipse'].dependsOn(eclipseSettings)
tasks['eclipseJdt'].dependsOn(eclipseSettings)
tasks['cleanEclipse'].dependsOn(cleanEclipseSettings)
task eclipseJdtPrepare(type: Copy) {
from rootProject.file("src/eclipse/org.eclipse.jdt.core.prefs")
into project.file(".settings/")
outputs.upToDateWhen { false }
}
task cleanEclipseJdtUi(type: Delete) {
delete project.file(".settings/org.eclipse.jdt.core.prefs")
delete project.file(".settings/org.eclipse.jdt.ui.prefs")
delete project.file(".settings/org.eclipse.wst.common.component")
delete project.file(".settings/org.eclipse.wst.common.project.facet.core.xml")
}
task eclipseBuildship(type: Copy) {
from rootProject.files(
"src/eclipse/org.eclipse.jdt.ui.prefs",
"src/eclipse/org.eclipse.jdt.core.prefs")
into project.file('.settings/')
outputs.upToDateWhen { false }
}
tasks["eclipseJdt"].dependsOn(eclipseJdtPrepare)
tasks["cleanEclipse"].dependsOn(cleanEclipseJdtUi)
tasks["eclipse"].dependsOn(eclipseSettings, eclipseWstComponent)
// Filter 'build' folder
eclipse.project.file.withXml {
def node = it.asNode()
def filteredResources = node.get("filteredResources")
if(filteredResources) {
node.remove(filteredResources)
}
def filterNode = node.appendNode("filteredResources").appendNode("filter")
filterNode.appendNode("id", "1359048889071")
filterNode.appendNode("name", "")
filterNode.appendNode("type", "30")
def matcherNode = filterNode.appendNode("matcher")
matcherNode.appendNode("id", "org.eclipse.ui.ide.multiFilter")
matcherNode.appendNode("arguments", "1.0-projectRelativePath-matches-false-false-build")
}
+3 -12
View File
@@ -1,4 +1,5 @@
apply plugin: "maven-publish"
apply plugin: 'com.jfrog.artifactory'
publishing {
publications {
@@ -49,16 +50,6 @@ publishing {
}
}
configureDeploymentRepository(project)
void configureDeploymentRepository(Project project) {
project.plugins.withType(MavenPublishPlugin.class).all {
PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class);
if (project.hasProperty("deploymentRepository")) {
publishing.repositories.maven {
it.url = project.property("deploymentRepository")
it.name = "deployment"
}
}
}
artifactoryPublish {
publications(publishing.publications.mavenJava)
}
+6 -37
View File
@@ -1,42 +1,7 @@
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 from: "$rootDir/gradle/publications.gradle"
dependencies {
jmh 'org.openjdk.jmh:jmh-core:1.32'
jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.32'
jmh 'net.sf.jopt-simple:jopt-simple'
}
jmh {
duplicateClassesStrategy = DuplicatesStrategy.EXCLUDE
}
tasks.findByName("processJmhResources").configure {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
jmhJar {
// Uncomment the following for Shadow's Transformer support.
// mergeServiceFiles()
// append('META-INF/spring.handlers')
// append('META-INF/spring.schemas')
// append('META-INF/spring.tooling')
exclude 'LICENSE'
exclude 'THIRD-PARTY'
exclude 'META-INF/license.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE*'
exclude 'META-INF/NOTICE'
exclude 'META-INF/THIRD-PARTY'
}
jar {
manifest.attributes["Implementation-Title"] = project.name
manifest.attributes["Implementation-Version"] = project.version
@@ -98,5 +63,9 @@ publishing {
}
// Disable publication of test fixture artifacts.
components.java.withVariantsFromConfiguration(configurations.testFixturesApiElements) { skip() }
components.java.withVariantsFromConfiguration(configurations.testFixturesRuntimeElements) { skip() }
//
// Once we upgrade to Gradle 6.x, we will need to delete the following line ...
components.java.variants.removeAll { it.outgoingConfiguration.name.startsWith("testFixtures") }
// ... and uncomment the following two lines.
// components.java.withVariantsFromConfiguration(configurations.testFixturesApiElements) { skip() }
// components.java.withVariantsFromConfiguration(configurations.testFixturesRuntimeElements) { skip() }
-171
View File
@@ -1,171 +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
}
if(testLanguageVersion == JavaLanguageVersion.of(17)) {
jvmArgs(["--add-opens=java.base/java.lang=ALL-UNNAMED",
"--add-opens=java.base/java.util=ALL-UNNAMED"])
}
}
}
}
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'
}
}
}
}
// Configure the JMH plugin to use the toolchain for generating and running JMH bytecode
pluginManager.withPlugin("me.champeau.jmh") {
if (mainToolchainConfigured() || testToolchainConfigured()) {
tasks.matching { it.name.contains('jmh') && it.hasProperty('javaLauncher') }.configureEach {
javaLauncher.set(javaToolchains.launcherFor {
languageVersion.set(testToolchainLanguageVersion())
})
}
tasks.withType(JavaCompile).matching { it.name.contains("Jmh") }.configureEach {
javaCompiler = javaToolchains.compilerFor {
languageVersion = testToolchainLanguageVersion()
}
}
}
}
// Store resolved Toolchain JVM information as custom values in the build scan.
rootProject.ext {
resolvedMainToolchain = false
resolvedTestToolchain = false
}
gradle.taskGraph.afterTask { Task task, TaskState state ->
if (mainToolchainConfigured() && !resolvedMainToolchain && task instanceof JavaCompile && task.javaCompiler.isPresent()) {
def metadata = task.javaCompiler.get().metadata
task.project.buildScan.value('Main toolchain', "$metadata.vendor $metadata.languageVersion ($metadata.installationPath)")
resolvedMainToolchain = true
}
if (testToolchainConfigured() && !resolvedTestToolchain && task instanceof Test && task.javaLauncher.isPresent()) {
def metadata = task.javaLauncher.get().metadata
task.project.buildScan.value('Test toolchain', "$metadata.vendor $metadata.languageVersion ($metadata.installationPath)")
resolvedTestToolchain = true
}
}
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+108 -154
View File
@@ -1,7 +1,7 @@
#!/bin/sh
#!/usr/bin/env sh
#
# Copyright © 2015-2021 the original authors.
# Copyright 2015 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,113 +17,78 @@
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
MAX_FD="maximum"
warn () {
echo "$*"
} >&2
}
die () {
echo
echo "$*"
echo
exit 1
} >&2
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD=$JAVA_HOME/bin/java
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -132,7 +97,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@@ -140,95 +105,84 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
Vendored
+18 -7
View File
@@ -29,9 +29,6 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@@ -40,7 +37,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -54,7 +51,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,14 +61,28 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
+20 -24
View File
@@ -3,11 +3,11 @@
This document will guide you through the process of importing the Spring Framework
projects into Eclipse or the Spring Tool Suite (_STS_). It is recommended that you
have a recent version of Eclipse. As a bare minimum you will need Eclipse with full Java
8 support, Eclipse Buildship, and the Groovy plugin.
8 support, Eclipse Buildship, the Kotlin plugin, and the Groovy plugin.
The following instructions have been tested against [STS](https://spring.io/tools) 4.12.0
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-4120-changelog))
(based on Eclipse 4.21) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship).
The following instructions have been tested against [STS](https://spring.io/tools) 4.3.2
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-432-changelog))
(based on Eclipse 4.12) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship).
The instructions should work with the latest Eclipse distribution as long as you install
[Buildship](https://marketplace.eclipse.org/content/buildship-gradle-integration). Note
that STS 4 comes with Buildship preinstalled.
@@ -16,32 +16,28 @@ that STS 4 comes with Buildship preinstalled.
_When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._
1. Install the [Groovy Development Tools](https://marketplace.eclipse.org/content/groovy-development-tools).
1. Switch to Groovy 3.0 in Eclipse (Preferences &#8594; Groovy &#8594; Compiler &#8594; Switch to 3.0...).
- If you encounter build errors stating something similar to _"Groovy: compiler mismatch: project level is 2.5, workspace level is 3.0"_, change the Groovy compiler version to 3.0 for each affected project.
1. Ensure that the _Forbidden reference (access rule)_ in Eclipse is set to `Info`
(Preferences &#8594; Java &#8594; Compiler &#8594; Errors/Warnings &#8594; Deprecated and restricted API &#8594; Forbidden reference (access rule)).
1. Optionally install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) if you need to execute Kotlin-based tests or develop Kotlin extensions.
- **NOTE**: As of September 21, 2021, it appears that the Kotlin Plugin for Eclipse does not yet work with Eclipse 4.21.
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project.
- **NOTE**: As of September 21, 2021, it appears that the AspectJ Development Tools do not yet work with Eclipse 4.21.
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute individual TestNG test classes or tests in the `spring-test` module.
- As an alternative to installing the TestNG plugin, you can execute the `org.springframework.test.context.testng.TestNGTestSuite` class as a "JUnit 5" test class in Eclipse.
1. Ensure that Eclipse launches with JDK 8.
- For example, on Mac OS this can be configured in the `Info.plist` file located in the `Contents` folder of the installed Eclipse or STS application (e.g., the `Eclipse.app` file).
1. Install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) in Eclipse.
1. Install the [Eclipse Groovy Development Tools](https://github.com/groovy/groovy-eclipse/wiki) in Eclipse.
1. Switch to Groovy 2.5 (Preferences -> Groovy -> Compiler -> Switch to 2.5...) in Eclipse.
1. Change the _Forbidden reference (access rule)_ in Eclipse from Error to Warning
(Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API -> Forbidden reference (access rule)).
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project. The AspectJ Development Tools available in the Eclipse Marketplace have been tested with these instructions using STS 4.5 (Eclipse 4.14).
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute TestNG tests in the `spring-test` module.
1. Build `spring-oxm` from the command line with `./gradlew :spring-oxm:check`.
1. To apply Spring Framework specific settings, run `./gradlew cleanEclipse eclipse` from the command line.
1. Import all projects into Eclipse (File &#8594; Import &#8594; Gradle &#8594; Existing Gradle Project &#8594; Navigate to the locally cloned `spring-framework` directory &#8594; Select Finish).
1. To apply project specific settings, run `./gradlew eclipseBuildship` from the command line.
1. Import into Eclipse (File -> Import -> Gradle -> Existing Gradle Project -> Navigate to the locally cloned `spring-framework` directory -> Select Finish).
- If you have not installed AJDT, exclude the `spring-aspects` project from the import, if prompted, or close it after the import.
- If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences &#8594; Gradle &#8594; Java home).
1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select "Build Path &#8594; Use as Source Folder").
- If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the _three vertical dots_ in the upper right corner of the Package Explorer).
- If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences -> Gradle -> Java home).
1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select `Build Path -> Use as Source Folder`).
- If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the small downward facing arrow in the upper right corner of the Package Explorer).
1. Code away!
## Known Issues
1. `spring-core` should be pre-compiled due to repackaged dependencies.
- See `*RepackJar` tasks in the `spring-core.gradle` build file.
1. `spring-oxm` should be pre-compiled due to JAXB types generated for tests.
- Note that executing `./gradlew :spring-oxm:check` as explained in the _Steps_ above will compile `spring-core` and generate JAXB types for `spring-oxm`.
1. `spring-core` and `spring-oxm` should be pre-compiled due to repackaged dependencies.
- See `*RepackJar` tasks in the build.
1. `spring-aspects` does not compile due to references to aspect types unknown to Eclipse.
- If you installed _AJDT_ into Eclipse it should work.
1. While JUnit tests pass from the command line with Gradle, some may fail when run from
+1 -1
View File
@@ -31,6 +31,6 @@ You'll notice these files are already intentionally in .gitignore. The same poli
## FAQ
Q. What about IntelliJ IDEA's own [Gradle support](https://www.jetbrains.com/help/idea/gradle.html)?
Q. What about IntelliJ IDEA's own [Gradle support](https://confluence.jetbrains.net/display/IDEADEV/Gradle+integration)?
A. Keep an eye on https://youtrack.jetbrains.com/issue/IDEA-53476
+20 -20
View File
@@ -1,26 +1,26 @@
description = "Spring Integration Tests"
dependencies {
testImplementation(project(":spring-aop"))
testImplementation(project(":spring-beans"))
testImplementation(project(":spring-context"))
testImplementation(project(":spring-core"))
testImplementation(testFixtures(project(":spring-aop")))
testImplementation(testFixtures(project(":spring-beans")))
testImplementation(testFixtures(project(":spring-core")))
testImplementation(testFixtures(project(":spring-tx")))
testImplementation(project(":spring-expression"))
testImplementation(project(":spring-jdbc"))
testImplementation(project(":spring-orm"))
testImplementation(project(":spring-test"))
testImplementation(project(":spring-tx"))
testImplementation(project(":spring-web"))
testImplementation("javax.inject:javax.inject")
testImplementation("javax.resource:javax.resource-api")
testImplementation("javax.servlet:javax.servlet-api")
testImplementation("org.aspectj:aspectjweaver")
testImplementation("org.hsqldb:hsqldb")
testImplementation("org.hibernate:hibernate-core")
testCompile(project(":spring-aop"))
testCompile(project(":spring-beans"))
testCompile(project(":spring-context"))
testCompile(project(":spring-core"))
testCompile(testFixtures(project(":spring-aop")))
testCompile(testFixtures(project(":spring-beans")))
testCompile(testFixtures(project(":spring-core")))
testCompile(testFixtures(project(":spring-tx")))
testCompile(project(":spring-expression"))
testCompile(project(":spring-jdbc"))
testCompile(project(":spring-orm"))
testCompile(project(":spring-test"))
testCompile(project(":spring-tx"))
testCompile(project(":spring-web"))
testCompile("javax.inject:javax.inject")
testCompile("javax.resource:javax.resource-api")
testCompile("javax.servlet:javax.servlet-api")
testCompile("org.aspectj:aspectjweaver")
testCompile("org.hsqldb:hsqldb")
testCompile("org.hibernate:hibernate-core")
}
normalization {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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.
@@ -28,7 +28,7 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Integration tests for advice invocation order for advice configured via the
@@ -52,7 +52,7 @@ class AopNamespaceHandlerAdviceOrderIntegrationTests {
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after", "after returning");
aspect.invocations.clear();
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
assertThatExceptionOfType(Exception.class).isThrownBy(() -> echo.echo(new Exception()));
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after", "after throwing");
}
}
@@ -69,7 +69,7 @@ class AopNamespaceHandlerAdviceOrderIntegrationTests {
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after returning", "after");
aspect.invocations.clear();
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
assertThatExceptionOfType(Exception.class).isThrownBy(() -> echo.echo(new Exception()));
assertThat(aspect.invocations).containsExactly("around - start", "before", "around - end", "after throwing", "after");
}
}
@@ -70,7 +70,7 @@ class AopNamespaceHandlerScopeIntegrationTests {
assertThat(singletonScoped.getName()).isEqualTo(rob);
singletonScoped.setName(bram);
assertThat(singletonScoped.getName()).isEqualTo(bram);
ITestBean deserialized = SerializationTestUtils.serializeAndDeserialize(singletonScoped);
ITestBean deserialized = (ITestBean) SerializationTestUtils.serializeAndDeserialize(singletonScoped);
assertThat(deserialized.getName()).isEqualTo(bram);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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.
@@ -38,7 +38,7 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Integration tests for advice invocation order for advice configured via
@@ -65,7 +65,8 @@ class AspectJAutoProxyAdviceOrderIntegrationTests {
assertThat(aspect.invocations).containsExactly("around - start", "before", "after returning", "after", "around - end");
aspect.invocations.clear();
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
assertThatExceptionOfType(Exception.class).isThrownBy(
() -> echo.echo(new Exception()));
assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end");
}
}
@@ -94,7 +95,8 @@ class AspectJAutoProxyAdviceOrderIntegrationTests {
assertThat(aspect.invocations).containsExactly("around - start", "before", "after returning", "after", "around - end");
aspect.invocations.clear();
assertThatException().isThrownBy(() -> echo.echo(new Exception()));
assertThatExceptionOfType(Exception.class).isThrownBy(
() -> echo.echo(new Exception()));
assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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,7 +34,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Repository;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Integration tests for the @EnableCaching annotation.
@@ -62,7 +62,8 @@ class EnableCachingIntegrationTests {
// this test is a bit fragile, but gets the job done, proving that an
// attempt was made to look up the AJ aspect. It's due to classpath issues
// in .integration-tests that it's not found.
assertThatException().isThrownBy(ctx::refresh)
assertThatExceptionOfType(Exception.class).isThrownBy(
ctx::refresh)
.withMessageContaining("AspectJCachingConfiguration");
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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,6 +34,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ScopeMetadata;
import org.springframework.context.annotation.ScopeMetadataResolver;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
@@ -306,26 +307,29 @@ class ClassPathBeanDefinitionScannerJsr330ScopeIntegrationTests {
GenericWebApplicationContext context = new GenericWebApplicationContext();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.setIncludeAnnotationConfig(false);
scanner.setScopeMetadataResolver(definition -> {
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
for (String type : annDef.getMetadata().getAnnotationTypes()) {
if (type.equals(javax.inject.Singleton.class.getName())) {
metadata.setScopeName(BeanDefinition.SCOPE_SINGLETON);
break;
}
else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(javax.inject.Scope.class.getName())) {
metadata.setScopeName(type.substring(type.length() - 13, type.length() - 6).toLowerCase());
metadata.setScopedProxyMode(scopedProxyMode);
break;
}
else if (type.startsWith("javax.inject")) {
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
scanner.setScopeMetadataResolver(new ScopeMetadataResolver() {
@Override
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
for (String type : annDef.getMetadata().getAnnotationTypes()) {
if (type.equals(javax.inject.Singleton.class.getName())) {
metadata.setScopeName(BeanDefinition.SCOPE_SINGLETON);
break;
}
else if (annDef.getMetadata().getMetaAnnotationTypes(type).contains(javax.inject.Scope.class.getName())) {
metadata.setScopeName(type.substring(type.length() - 13, type.length() - 6).toLowerCase());
metadata.setScopedProxyMode(scopedProxyMode);
break;
}
else if (type.startsWith("javax.inject")) {
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
}
}
}
return metadata;
}
return metadata;
});
// Scan twice in order to find errors in the bean definition compatibility check.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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.
@@ -40,7 +40,7 @@ import org.springframework.transaction.testfixture.CallCountingTransactionManage
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.Mockito.mock;
import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
import static org.springframework.core.testfixture.TestGroup.PERFORMANCE;
/**
* Integration tests cornering bug SPR-8651, which revealed that @Scheduled methods may
@@ -52,7 +52,7 @@ import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
* @since 3.1
*/
@SuppressWarnings("resource")
@EnabledForTestGroups(LONG_RUNNING)
@EnabledForTestGroups(PERFORMANCE)
class ScheduledAndTransactionalAnnotationIntegrationTests {
@Test
@@ -61,7 +61,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
ctx.register(Config.class, JdkProxyTxConfig.class, RepoConfigA.class);
assertThatExceptionOfType(BeanCreationException.class)
.isThrownBy(ctx::refresh)
.withCauseInstanceOf(IllegalStateException.class);
.satisfies(ex -> assertThat(ex.getRootCause()).isInstanceOf(IllegalStateException.class));
}
@Test
@@ -74,7 +74,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
MyRepository repository = ctx.getBean(MyRepository.class);
CallCountingTransactionManager txManager = ctx.getBean(CallCountingTransactionManager.class);
assertThat(AopUtils.isCglibProxy(repository)).isTrue();
assertThat(AopUtils.isCglibProxy(repository)).isEqualTo(true);
assertThat(repository.getInvocationCount()).isGreaterThan(0);
assertThat(txManager.commits).isGreaterThan(0);
}
@@ -182,7 +182,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
@Aspect
public static class MyAspect {
private final AtomicInteger count = new AtomicInteger();
private final AtomicInteger count = new AtomicInteger(0);
@org.aspectj.lang.annotation.Before("execution(* scheduled())")
public void checkTransaction() {
@@ -200,7 +200,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
@Repository
static class MyRepositoryImpl implements MyRepository {
private final AtomicInteger count = new AtomicInteger();
private final AtomicInteger count = new AtomicInteger(0);
@Transactional
@Scheduled(fixedDelay = 5)
@@ -226,7 +226,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
@Repository
static class MyRepositoryWithScheduledMethodImpl implements MyRepositoryWithScheduledMethod {
private final AtomicInteger count = new AtomicInteger();
private final AtomicInteger count = new AtomicInteger(0);
@Autowired(required = false)
private MyAspect myAspect;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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.
@@ -45,7 +45,7 @@ import org.springframework.transaction.interceptor.BeanFactoryTransactionAttribu
import org.springframework.transaction.testfixture.CallCountingTransactionManager;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Integration tests for the @EnableTransactionManagement annotation.
@@ -98,7 +98,7 @@ class EnableTransactionManagementIntegrationTests {
// this test is a bit fragile, but gets the job done, proving that an
// attempt was made to look up the AJ aspect. It's due to classpath issues
// in .integration-tests that it's not found.
assertThatException()
assertThatExceptionOfType(Exception.class)
.isThrownBy(ctx::refresh)
.withMessageContaining("AspectJJtaTransactionManagementConfiguration");
}
+6 -25
View File
@@ -1,23 +1,20 @@
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
maven { url "https://repo.spring.io/release" }
maven { url 'https://repo.spring.io/plugins-release' }
}
}
plugins {
id "com.gradle.enterprise" version "3.12.1"
id "io.spring.ge.conventions" version "0.0.13"
}
apply from: "$rootDir/gradle/build-cache-settings.gradle"
include "spring-aop"
include "spring-aspects"
include "spring-beans"
include "spring-context"
include "spring-context-indexer"
include "spring-context-support"
include "spring-context-indexer"
include "spring-core"
include "kotlin-coroutines"
project(':kotlin-coroutines').projectDir = file('spring-core/kotlin-coroutines')
include "spring-expression"
include "spring-instrument"
include "spring-jcl"
@@ -26,12 +23,11 @@ include "spring-jms"
include "spring-messaging"
include "spring-orm"
include "spring-oxm"
include "spring-r2dbc"
include "spring-test"
include "spring-tx"
include "spring-web"
include "spring-webflux"
include "spring-webmvc"
include "spring-webflux"
include "spring-websocket"
include "framework-bom"
include "integration-tests"
@@ -40,18 +36,3 @@ rootProject.name = "spring"
rootProject.children.each {project ->
project.buildFileName = "${project.name}.gradle"
}
settings.gradle.projectsLoaded {
gradleEnterprise {
buildScan {
File buildDir = settings.gradle.rootProject.getBuildDir()
buildDir.mkdirs()
new File(buildDir, "build-scan-uri.txt").text = "(build scan not generated)"
buildScanPublished { scan ->
if (buildDir.exists()) {
new File(buildDir, "build-scan-uri.txt").text = "${scan.buildScanUri}\n"
}
}
}
}
}
+4 -5
View File
@@ -1,13 +1,12 @@
description = "Spring AOP"
dependencies {
api(project(":spring-beans"))
api(project(":spring-core"))
compile(project(":spring-beans"))
compile(project(":spring-core"))
optional("org.aspectj:aspectjweaver")
optional("org.apache.commons:commons-pool2")
optional("com.jamonapi:jamon")
testImplementation(testFixtures(project(":spring-beans")))
testImplementation(testFixtures(project(":spring-core")))
testFixturesImplementation(testFixtures(project(":spring-beans")))
testCompile(testFixtures(project(":spring-beans")))
testCompile(testFixtures(project(":spring-core")))
testFixturesImplementation(testFixtures(project(":spring-core")))
}
@@ -16,8 +16,6 @@
package org.aopalliance.intercept;
import javax.annotation.Nonnull;
/**
* Intercepts the construction of a new object.
*
@@ -56,7 +54,6 @@ public interface ConstructorInterceptor extends Interceptor {
* @throws Throwable if the interceptors or the target object
* throws an exception
*/
@Nonnull
Object construct(ConstructorInvocation invocation) throws Throwable;
}
@@ -18,8 +18,6 @@ package org.aopalliance.intercept;
import java.lang.reflect.Constructor;
import javax.annotation.Nonnull;
/**
* Description of an invocation to a constructor, given to an
* interceptor upon constructor-call.
@@ -38,7 +36,6 @@ public interface ConstructorInvocation extends Invocation {
* {@link Joinpoint#getStaticPart()} method (same result).
* @return the constructor being called
*/
@Nonnull
Constructor<?> getConstructor();
}
@@ -16,8 +16,6 @@
package org.aopalliance.intercept;
import javax.annotation.Nonnull;
/**
* This interface represents an invocation in the program.
*
@@ -34,7 +32,6 @@ public interface Invocation extends Joinpoint {
* array to change the arguments.
* @return the argument of the invocation
*/
@Nonnull
Object[] getArguments();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2016 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,15 +18,12 @@ package org.aopalliance.intercept;
import java.lang.reflect.AccessibleObject;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* This interface represents a generic runtime joinpoint (in the AOP
* terminology).
*
* <p>A runtime joinpoint is an <i>event</i> that occurs on a static
* joinpoint (i.e. a location in a program). For instance, an
* joinpoint (i.e. a location in a the program). For instance, an
* invocation is the runtime joinpoint on a method (static joinpoint).
* The static part of a given joinpoint can be generically retrieved
* using the {@link #getStaticPart()} method.
@@ -49,7 +46,6 @@ public interface Joinpoint {
* @return see the children interfaces' proceed definition
* @throws Throwable if the joinpoint throws an exception
*/
@Nullable
Object proceed() throws Throwable;
/**
@@ -57,15 +53,13 @@ public interface Joinpoint {
* <p>For instance, the target object for an invocation.
* @return the object (can be null if the accessible object is static)
*/
@Nullable
Object getThis();
/**
* Return the static part of this joinpoint.
* <p>The static part is an accessible object on which a chain of
* interceptors is installed.
* interceptors are installed.
*/
@Nonnull
AccessibleObject getStaticPart();
}
@@ -16,9 +16,6 @@
package org.aopalliance.intercept;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Intercepts calls on an interface on its way to the target. These
* are nested "on top" of the target.
@@ -55,7 +52,6 @@ public interface MethodInterceptor extends Interceptor {
* @throws Throwable if the interceptors or the target object
* throws an exception
*/
@Nullable
Object invoke(@Nonnull MethodInvocation invocation) throws Throwable;
Object invoke(MethodInvocation invocation) throws Throwable;
}
@@ -18,8 +18,6 @@ package org.aopalliance.intercept;
import java.lang.reflect.Method;
import javax.annotation.Nonnull;
/**
* Description of an invocation to a method, given to an interceptor
* upon method-call.
@@ -38,7 +36,6 @@ public interface MethodInvocation extends Invocation {
* {@link Joinpoint#getStaticPart()} method (same result).
* @return the method being called
*/
@Nonnull
Method getMethod();
}
@@ -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.
@@ -36,7 +36,7 @@ public interface IntroductionAwareMethodMatcher extends MethodMatcher {
* @param targetClass the target class
* @param hasIntroductions {@code true} if the object on whose behalf we are
* asking is the subject on one or more introductions; {@code false} otherwise
* @return whether this method matches statically
* @return whether or not this method matches statically
*/
boolean matches(Method method, Class<?> targetClass, boolean hasIntroductions);
@@ -60,7 +60,7 @@ public interface MethodMatcher {
* will be made.
* @param method the candidate method
* @param targetClass the target class
* @return whether this method matches statically
* @return whether or not this method matches statically
*/
boolean matches(Method method, Class<?> targetClass);
@@ -70,7 +70,7 @@ public interface MethodMatcher {
* runtime even if the 2-arg matches method returns {@code true}?
* <p>Can be invoked when an AOP proxy is created, and need not be invoked
* again before each method invocation,
* @return whether a runtime match via the 3-arg
* @return whether or not a runtime match via the 3-arg
* {@link #matches(java.lang.reflect.Method, Class, Object[])} method
* is required if static matching passed
*/
@@ -18,7 +18,7 @@ package org.springframework.aop;
/**
* Marker interface implemented by all AOP proxies. Used to detect
* whether objects are Spring-generated proxies.
* whether or not objects are Spring-generated proxies.
*
* @author Rob Harrop
* @since 2.0.1
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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.
@@ -350,8 +350,17 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
return this.discoveredThrowingType;
}
private static boolean isVariableName(String name) {
return AspectJProxyUtils.isVariableName(name);
private boolean isVariableName(String name) {
char[] chars = name.toCharArray();
if (!Character.isJavaIdentifierStart(chars[0])) {
return false;
}
for (int i = 1; i < chars.length; i++) {
if (!Character.isJavaIdentifierPart(chars[i])) {
return false;
}
}
return true;
}
@@ -368,7 +377,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
* to which argument name. There are multiple strategies for determining
* this binding, which are arranged in a ChainOfResponsibility.
*/
public final void calculateArgumentBindings() {
public final synchronized void calculateArgumentBindings() {
// The simple case... nothing to bind.
if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
return;
@@ -631,6 +640,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
// TODO AopUtils.invokeJoinpointUsingReflection
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
}
catch (IllegalArgumentException ex) {
@@ -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.
@@ -470,10 +470,22 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
*/
@Nullable
private String maybeExtractVariableName(@Nullable String candidateToken) {
if (AspectJProxyUtils.isVariableName(candidateToken)) {
if (!StringUtils.hasLength(candidateToken)) {
return null;
}
if (Character.isJavaIdentifierStart(candidateToken.charAt(0)) &&
Character.isLowerCase(candidateToken.charAt(0))) {
char[] tokenChars = candidateToken.toCharArray();
for (char tokenChar : tokenChars) {
if (!Character.isJavaIdentifierPart(tokenChar)) {
return null;
}
}
return candidateToken;
}
return null;
else {
return null;
}
}
/**
@@ -625,7 +637,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 +657,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-2020 the original author or authors.
* Copyright 2002-2015 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 org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterAdvice;
import org.springframework.lang.Nullable;
/**
* Spring AOP advice wrapping an AspectJ after advice method.
@@ -43,7 +42,6 @@ public class AspectJAfterAdvice extends AbstractAspectJAdvice
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2015 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 org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterAdvice;
import org.springframework.lang.Nullable;
/**
* Spring AOP advice wrapping an AspectJ after-throwing advice method.
@@ -58,7 +57,6 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
}
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -25,7 +25,6 @@ import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.weaver.tools.JoinPointMatch;
import org.springframework.aop.ProxyMethodInvocation;
import org.springframework.lang.Nullable;
/**
* Spring AOP around advice (MethodInterceptor) that wraps
@@ -61,7 +60,6 @@ public class AspectJAroundAdvice extends AbstractAspectJAdvice implements Method
}
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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.
@@ -378,7 +378,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
}
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to evaluate join point for arguments " + Arrays.toString(args) +
logger.debug("Failed to evaluate join point for arguments " + Arrays.asList(args) +
" - falling back to non-match", ex);
}
return false;
@@ -547,7 +547,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
StringBuilder sb = new StringBuilder("AspectJExpressionPointcut: (");
for (int i = 0; i < this.pointcutParameterTypes.length; i++) {
sb.append(this.pointcutParameterTypes[i].getName());
sb.append(' ');
sb.append(" ");
sb.append(this.pointcutParameterNames[i]);
if ((i+1) < this.pointcutParameterTypes.length) {
sb.append(", ");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-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,8 +21,6 @@ import java.util.List;
import org.springframework.aop.Advisor;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
* Utility methods for working with AspectJ proxies.
@@ -75,19 +73,4 @@ public abstract class AspectJProxyUtils {
((PointcutAdvisor) advisor).getPointcut() instanceof AspectJExpressionPointcut));
}
static boolean isVariableName(@Nullable String name) {
if (!StringUtils.hasLength(name)) {
return false;
}
if (!Character.isJavaIdentifierStart(name.charAt(0))) {
return false;
}
for (int i = 1; i < name.length(); i++) {
if (!Character.isJavaIdentifierPart(name.charAt(i))) {
return false;
}
}
return true;
}
}
@@ -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,13 +84,11 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
}
@Override
@Nullable
public Object proceed() throws Throwable {
return this.methodInvocation.invocableClone().proceed();
}
@Override
@Nullable
public Object proceed(Object[] arguments) throws Throwable {
Assert.notNull(arguments, "Argument array passed to proceed cannot be null");
if (arguments.length != this.methodInvocation.getArguments().length) {
@@ -255,19 +253,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 +276,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.
@@ -103,11 +103,10 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
@Override
public void validate(Class<?> aspectClass) throws AopConfigException {
// If the parent has the annotation and isn't abstract it's an error
Class<?> superclass = aspectClass.getSuperclass();
if (superclass.getAnnotation(Aspect.class) != null &&
!Modifier.isAbstract(superclass.getModifiers())) {
if (aspectClass.getSuperclass().getAnnotation(Aspect.class) != null &&
!Modifier.isAbstract(aspectClass.getSuperclass().getModifiers())) {
throw new AopConfigException("[" + aspectClass.getName() + "] cannot extend concrete aspect [" +
superclass.getName() + "]");
aspectClass.getSuperclass().getName() + "]");
}
AjType<?> ajType = AjTypeSystem.getAjType(aspectClass);
@@ -39,7 +39,7 @@ import org.springframework.lang.Nullable;
public interface AspectJAdvisorFactory {
/**
* Determine whether the given class is an aspect, as reported
* Determine whether or not the given class is an aspect, as reported
* by AspectJ's {@link org.aspectj.lang.reflect.AjTypeSystem}.
* <p>Will simply return {@code false} if the supposed aspect is
* invalid (such as an extension of a concrete aspect class).
@@ -47,7 +47,7 @@ public interface AspectJAdvisorFactory {
* such as those with unsupported instantiation models.
* Use the {@link #validate} method to handle these cases if necessary.
* @param clazz the supposed annotation-style AspectJ class
* @return whether this class is recognized by AspectJ as an aspect class
* @return whether or not this class is recognized by AspectJ as an aspect class
*/
boolean isAspect(Class<?> clazz);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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.
@@ -34,7 +34,7 @@ import org.springframework.util.ClassUtils;
/**
* AspectJ-based proxy factory, allowing for programmatic building
* of proxies which include AspectJ aspects (code style as well
* annotation style).
* Java 5 annotation style).
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -160,12 +160,23 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
}
/**
* Get the singleton aspect instance for the supplied aspect type.
* An instance is created if one cannot be found in the instance cache.
* Get the singleton aspect instance for the supplied aspect type. An instance
* is created if one cannot be found in the instance cache.
*/
private Object getSingletonAspectInstance(Class<?> aspectClass) {
return aspectCache.computeIfAbsent(aspectClass,
clazz -> new SimpleAspectInstanceFactory(clazz).getAspectInstance());
// Quick check without a lock...
Object instance = aspectCache.get(aspectClass);
if (instance == null) {
synchronized (aspectCache) {
// To be safe, check within full lock now...
instance = aspectCache.get(aspectClass);
if (instance == null) {
instance = new SimpleAspectInstanceFactory(aspectClass).getAspectInstance();
aspectCache.put(aspectClass, instance);
}
}
}
return instance;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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.
@@ -60,14 +60,14 @@ public class AspectMetadata implements Serializable {
private final Class<?> aspectClass;
/**
* AspectJ reflection information.
* <p>Re-resolved on deserialization since it isn't serializable itself.
* AspectJ reflection information (AspectJ 5 / Java 5 specific).
* Re-resolved on deserialization since it isn't serializable itself.
*/
private transient AjType<?> ajType;
/**
* Spring AOP pointcut corresponding to the per clause of the
* aspect. Will be the {@code Pointcut.TRUE} canonical instance in the
* aspect. Will be the Pointcut.TRUE canonical instance in the
* case of a singleton, otherwise an AspectJExpressionPointcut.
*/
private final Pointcut perClausePointcut;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2016 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,6 +23,10 @@ import org.springframework.lang.Nullable;
* Subinterface of {@link org.springframework.aop.aspectj.AspectInstanceFactory}
* that returns {@link AspectMetadata} associated with AspectJ-annotated classes.
*
* <p>Ideally, AspectInstanceFactory would include this method itself, but because
* AspectMetadata uses Java-5-only {@link org.aspectj.lang.reflect.AjType},
* we need to split out this subinterface.
*
* @author Rod Johnson
* @since 2.0
* @see AspectMetadata
@@ -31,13 +35,13 @@ import org.springframework.lang.Nullable;
public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactory {
/**
* Get the AspectJ AspectMetadata for this factory's aspect.
* Return the AspectJ AspectMetadata for this factory's aspect.
* @return the aspect metadata
*/
AspectMetadata getAspectMetadata();
/**
* Get the best possible creation mutex for this factory.
* Return the best possible creation mutex for this factory.
* @return the mutex object (may be {@code null} for no mutex to use)
* @since 4.3
*/
@@ -51,7 +51,6 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConvertingComparator;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodFilter;
import org.springframework.util.StringUtils;
import org.springframework.util.comparator.InstanceComparator;
@@ -71,11 +70,7 @@ import org.springframework.util.comparator.InstanceComparator;
@SuppressWarnings("serial")
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
// Exclude @Pointcut methods
private static final MethodFilter adviceMethodFilter = ReflectionUtils.USER_DECLARED_METHODS
.and(method -> (AnnotationUtils.getAnnotation(method, Pointcut.class) == null));
private static final Comparator<Method> adviceMethodComparator;
private static final Comparator<Method> METHOD_COMPARATOR;
static {
// Note: although @After is ordered before @AfterReturning and @AfterThrowing,
@@ -91,7 +86,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
return (ann != null ? ann.getAnnotation() : null);
});
Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
METHOD_COMPARATOR = adviceKindComparator.thenComparing(methodNameComparator);
}
@@ -165,10 +160,15 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
}
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
final List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, method -> {
// Exclude pointcuts
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}, ReflectionUtils.USER_DECLARED_METHODS);
if (methods.size() > 1) {
methods.sort(adviceMethodComparator);
methods.sort(METHOD_COMPARATOR);
}
return methods;
}
@@ -60,8 +60,8 @@ public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProx
* <li>Otherwise the advice declared first gets highest precedence (i.e., runs
* first).</li>
* </ul>
* <p><b>Important:</b> Advisors are sorted in precedence order, from the highest
* precedence to the lowest. "On the way in" to a join point, the highest precedence
* <p><b>Important:</b> Advisors are sorted in precedence order, from highest
* precedence to lowest. "On the way in" to a join point, the highest precedence
* advisor should run first. "On the way out" of a join point, the highest
* precedence advisor should run last.
*/
@@ -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-2020 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.
@@ -114,15 +114,6 @@ public interface Advised extends TargetClassAware {
*/
Advisor[] getAdvisors();
/**
* Return the number of advisors applying to this proxy.
* <p>The default implementation delegates to {@code getAdvisors().length}.
* @since 5.3.1
*/
default int getAdvisorCount() {
return getAdvisors().length;
}
/**
* Add an advisor at the end of the advisor chain.
* <p>The Advisor may be an {@link org.springframework.aop.IntroductionAdvisor},
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -95,6 +95,12 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
*/
private List<Advisor> advisors = new ArrayList<>();
/**
* Array updated on changes to the advisors list, which is easier
* to manipulate internally.
*/
private Advisor[] advisorArray = new Advisor[0];
/**
* No-arg constructor for use as a JavaBean.
@@ -238,12 +244,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
@Override
public final Advisor[] getAdvisors() {
return this.advisors.toArray(new Advisor[0]);
}
@Override
public int getAdvisorCount() {
return this.advisors.size();
return this.advisorArray;
}
@Override
@@ -291,6 +292,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
}
}
updateAdvisorArray();
adviceChanged();
}
@@ -314,7 +316,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
}
/**
* Add all the given advisors to this proxy configuration.
* Add all of the given advisors to this proxy configuration.
* @param advisors the advisors to register
*/
public void addAdvisors(Advisor... advisors) {
@@ -322,7 +324,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
}
/**
* Add all the given advisors to this proxy configuration.
* Add all of the given advisors to this proxy configuration.
* @param advisors the advisors to register
*/
public void addAdvisors(Collection<Advisor> advisors) {
@@ -337,6 +339,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
Assert.notNull(advisor, "Advisor must not be null");
this.advisors.add(advisor);
}
updateAdvisorArray();
adviceChanged();
}
}
@@ -360,18 +363,27 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
"Illegal position " + pos + " in advisor list with size " + this.advisors.size());
}
this.advisors.add(pos, advisor);
updateAdvisorArray();
adviceChanged();
}
/**
* Bring the array up to date with the list.
*/
protected final void updateAdvisorArray() {
this.advisorArray = this.advisors.toArray(new Advisor[0]);
}
/**
* Allows uncontrolled access to the {@link List} of {@link Advisor Advisors}.
* <p>Use with care, and remember to {@link #adviceChanged() fire advice changed events}
* when making any modifications.
* <p>Use with care, and remember to {@link #updateAdvisorArray() refresh the advisor array}
* and {@link #adviceChanged() fire advice changed events} when making any modifications.
*/
protected final List<Advisor> getAdvisorsInternal() {
return this.advisors;
}
@Override
public void addAdvice(Advice advice) throws AopConfigException {
int pos = this.advisors.size();
@@ -509,6 +521,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
Assert.notNull(advisor, "Advisor must not be null");
this.advisors.add(advisor);
}
updateAdvisorArray();
adviceChanged();
}
@@ -521,8 +534,9 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
copy.copyFrom(this);
copy.targetSource = EmptyTargetSource.forClass(getTargetClass(), getTargetSource().isStatic());
copy.advisorChainFactory = this.advisorChainFactory;
copy.interfaces = new ArrayList<>(this.interfaces);
copy.advisors = new ArrayList<>(this.advisors);
copy.interfaces = this.interfaces;
copy.advisors = this.advisors;
copy.updateAdvisorArray();
return copy;
}
@@ -539,6 +553,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
this.methodCache = new ConcurrentHashMap<>(32);
}
@Override
public String toProxyConfigString() {
return toString();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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.
@@ -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.
@@ -44,16 +40,10 @@ import org.springframework.util.ReflectionUtils;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @see org.springframework.aop.support.AopUtils
*/
public abstract class AopProxyUtils {
// JDK 17 Class.isSealed() method available?
@Nullable
private static final Method isSealedMethod = ClassUtils.getMethodIfAvailable(Class.class, "isSealed");
/**
* Obtain the singleton target object behind the given proxy, if any.
* @param candidate the (potential) proxy to check
@@ -134,29 +124,40 @@ public abstract class AopProxyUtils {
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
else if (Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
else if (Proxy.isProxyClass(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
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;
}
/**
@@ -205,7 +206,7 @@ public abstract class AopProxyUtils {
* Check equality of the advisors behind the given AdvisedSupport objects.
*/
public static boolean equalsAdvisors(AdvisedSupport a, AdvisedSupport b) {
return a.getAdvisorCount() == b.getAdvisorCount() && Arrays.equals(a.getAdvisors(), b.getAdvisors());
return Arrays.equals(a.getAdvisors(), b.getAdvisors());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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.
@@ -21,6 +21,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -48,12 +49,10 @@ 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.KotlinDetector;
import org.springframework.core.SmartClassLoader;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
@@ -126,7 +125,7 @@ class CglibAopProxy implements AopProxy, Serializable {
*/
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
@@ -237,7 +236,7 @@ class CglibAopProxy implements AopProxy, Serializable {
* validates it if not.
*/
private void validateClassIfNecessary(Class<?> proxySuperClass, @Nullable ClassLoader proxyClassLoader) {
if (!this.advised.isOptimize() && logger.isInfoEnabled()) {
if (logger.isWarnEnabled()) {
synchronized (validatedClasses) {
if (!validatedClasses.containsKey(proxySuperClass)) {
doValidateClass(proxySuperClass, proxyClassLoader,
@@ -326,7 +325,7 @@ class CglibAopProxy implements AopProxy, Serializable {
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);
this.fixedInterceptorMap = new HashMap<>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
@@ -375,22 +374,6 @@ class CglibAopProxy implements AopProxy, Serializable {
return false;
}
/**
* Invoke the given method with a CGLIB MethodProxy if possible, falling back
* to a plain reflection invocation in case of a fast-class generation failure.
*/
@Nullable
private static Object invokeMethod(@Nullable Object target, Method method, Object[] args, MethodProxy methodProxy)
throws Throwable {
try {
return methodProxy.invoke(target, args);
}
catch (CodeGenerationException ex) {
CglibMethodInvocation.logFastClassGenerationFailure(method);
return AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
}
/**
* Process a return value. Wraps a return of {@code this} if necessary to be the
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
@@ -441,7 +424,7 @@ class CglibAopProxy implements AopProxy, Serializable {
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object retVal = invokeMethod(this.target, method, args, methodProxy);
Object retVal = methodProxy.invoke(this.target, args);
return processReturnType(proxy, this.target, method, retVal);
}
}
@@ -466,7 +449,7 @@ class CglibAopProxy implements AopProxy, Serializable {
Object oldProxy = null;
try {
oldProxy = AopContext.setCurrentProxy(proxy);
Object retVal = invokeMethod(this.target, method, args, methodProxy);
Object retVal = methodProxy.invoke(this.target, args);
return processReturnType(proxy, this.target, method, retVal);
}
finally {
@@ -494,7 +477,7 @@ class CglibAopProxy implements AopProxy, Serializable {
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object target = this.targetSource.getTarget();
try {
Object retVal = invokeMethod(target, method, args, methodProxy);
Object retVal = methodProxy.invoke(target, args);
return processReturnType(proxy, target, method, retVal);
}
finally {
@@ -524,7 +507,7 @@ class CglibAopProxy implements AopProxy, Serializable {
Object target = this.targetSource.getTarget();
try {
oldProxy = AopContext.setCurrentProxy(proxy);
Object retVal = invokeMethod(target, method, args, methodProxy);
Object retVal = methodProxy.invoke(target, args);
return processReturnType(proxy, target, method, retVal);
}
finally {
@@ -695,13 +678,13 @@ class CglibAopProxy implements AopProxy, Serializable {
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = invokeMethod(target, method, argsToUse, methodProxy);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
@@ -753,7 +736,10 @@ class CglibAopProxy implements AopProxy, Serializable {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
// Only use method proxy for public methods not derived from java.lang.Object
this.methodProxy = (isMethodProxyCompatible(method) ? methodProxy : null);
this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
methodProxy : null);
}
@Override
@@ -766,17 +752,10 @@ class CglibAopProxy implements AopProxy, Serializable {
throw ex;
}
catch (Exception ex) {
if (ReflectionUtils.declaresException(getMethod(), ex.getClass()) ||
KotlinDetector.isKotlinType(getMethod().getDeclaringClass())) {
// Propagate original exception if declared on the target method
// (with callers expecting it). Always propagate it for Kotlin code
// since checked exceptions do not have to be explicitly declared there.
if (ReflectionUtils.declaresException(getMethod(), ex.getClass())) {
throw ex;
}
else {
// Checked exception thrown in the interceptor but not declared on the
// target method signature -> apply an UndeclaredThrowableException,
// aligned with standard JDK dynamic proxy behavior.
throw new UndeclaredThrowableException(ex);
}
}
@@ -789,25 +768,10 @@ class CglibAopProxy implements AopProxy, Serializable {
@Override
protected Object invokeJoinpoint() throws Throwable {
if (this.methodProxy != null) {
try {
return this.methodProxy.invoke(this.target, this.arguments);
}
catch (CodeGenerationException ex) {
logFastClassGenerationFailure(this.method);
}
return this.methodProxy.invoke(this.target, this.arguments);
}
return super.invokeJoinpoint();
}
static boolean isMethodProxyCompatible(Method method) {
return (Modifier.isPublic(method.getModifiers()) &&
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method));
}
static void logFastClassGenerationFailure(Method method) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to generate CGLIB fast class for method: " + method);
else {
return super.invokeJoinpoint();
}
}
}
@@ -978,11 +942,11 @@ class CglibAopProxy implements AopProxy, Serializable {
}
// Advice instance identity is unimportant to the proxy class:
// All that matters is type and ordering.
if (this.advised.getAdvisorCount() != otherAdvised.getAdvisorCount()) {
return false;
}
Advisor[] thisAdvisors = this.advised.getAdvisors();
Advisor[] thatAdvisors = otherAdvised.getAdvisors();
if (thisAdvisors.length != thatAdvisors.length) {
return false;
}
for (int i = 0; i < thisAdvisors.length; i++) {
Advisor thisAdvisor = thisAdvisors[i];
Advisor thatAdvisor = thatAdvisors[i];
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2015 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,8 +20,6 @@ import java.io.Serializable;
import java.lang.reflect.Proxy;
import org.springframework.aop.SpringProxy;
import org.springframework.core.NativeDetector;
import org.springframework.util.ClassUtils;
/**
* Default {@link AopProxyFactory} implementation, creating either a CGLIB proxy
@@ -40,28 +38,23 @@ import org.springframework.util.ClassUtils;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sebastien Deleuze
* @author Sam Brannen
* @since 12.03.2004
* @see AdvisedSupport#setOptimize
* @see AdvisedSupport#setProxyTargetClass
* @see AdvisedSupport#setInterfaces
*/
@SuppressWarnings("serial")
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
private static final long serialVersionUID = 7930414337282325166L;
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!NativeDetector.inNativeImage() &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -57,7 +57,6 @@ import org.springframework.util.ClassUtils;
* @author Juergen Hoeller
* @author Rob Harrop
* @author Dave Syer
* @author Sergey Tsypanov
* @see java.lang.reflect.Proxy
* @see AdvisedSupport
* @see ProxyFactory
@@ -72,8 +71,8 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
* NOTE: We could avoid the code duplication between this class and the CGLIB
* proxies by refactoring "invoke" into a template method. However, this approach
* adds at least 10% performance overhead versus a copy-paste solution, so we sacrifice
* elegance for performance (we have a good test suite to ensure that the different
* proxies behave the same :-)).
* elegance for performance. (We have a good test suite to ensure that the different
* proxies behave the same :-)
* This way, we can also more easily take advantage of minor optimizations in each class.
*/
@@ -83,8 +82,6 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
/** Config used to configure this proxy. */
private final AdvisedSupport advised;
private final Class<?>[] proxiedInterfaces;
/**
* Is the {@link #equals} method defined on the proxied interfaces?
*/
@@ -104,12 +101,10 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
*/
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
}
@@ -123,7 +118,9 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
/**
@@ -198,7 +195,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fall back on direct
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
@@ -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.
@@ -73,9 +73,11 @@ public class ProxyConfig implements Serializable {
* The exact meaning of "aggressive optimizations" will differ
* between proxies, but there is usually some tradeoff.
* Default is "false".
* <p>With Spring's current proxy options, this flag effectively
* enforces CGLIB proxies (similar to {@link #setProxyTargetClass})
* but without any class validation checks (for final methods etc).
* <p>For example, optimization will usually mean that advice changes won't
* take effect after a proxy has been created. For this reason, optimization
* is disabled by default. An optimize value of "true" may be ignored
* if other settings preclude optimization: for example, if "exposeProxy"
* is set to "true" and that's not compatible with the optimization.
*/
public void setOptimize(boolean optimize) {
this.optimize = optimize;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -16,7 +16,7 @@
package org.springframework.aop.framework;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.springframework.util.Assert;
@@ -34,7 +34,7 @@ public class ProxyCreatorSupport extends AdvisedSupport {
private AopProxyFactory aopProxyFactory;
private final List<AdvisedSupportListener> listeners = new ArrayList<>();
private final List<AdvisedSupportListener> listeners = new LinkedList<>();
/** Set to true when the first AOP proxy has been created. */
private boolean active = false;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 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.
@@ -50,7 +50,7 @@ import org.springframework.util.ObjectUtils;
/**
* {@link org.springframework.beans.factory.FactoryBean} implementation that builds an
* AOP proxy based on beans in a Spring {@link org.springframework.beans.factory.BeanFactory}.
* AOP proxy based on beans in Spring {@link org.springframework.beans.factory.BeanFactory}.
*
* <p>{@link org.aopalliance.intercept.MethodInterceptor MethodInterceptors} and
* {@link org.springframework.aop.Advisor Advisors} are identified by a list of bean
@@ -61,11 +61,10 @@ import org.springframework.util.ObjectUtils;
*
* <p>Global interceptors and advisors can be added at the factory level. The specified
* ones are expanded in an interceptor list where an "xxx*" entry is included in the
* list, matching the given prefix with the bean names &mdash; for example, "global*"
* would match both "globalBean1" and "globalBean2"; whereas, "*" would match all
* defined interceptors. The matching interceptors get applied according to their
* returned order value, if they implement the {@link org.springframework.core.Ordered}
* interface.
* list, matching the given prefix with the bean names (e.g. "global*" would match
* both "globalBean1" and "globalBean2", "*" all defined interceptors). The matching
* interceptors get applied according to their returned order value, if they implement
* the {@link org.springframework.core.Ordered} interface.
*
* <p>Creates a JDK proxy when proxy interfaces are given, and a CGLIB proxy for the
* actual target class if not. Note that the latter will only work if the target class
@@ -76,7 +75,7 @@ import org.springframework.util.ObjectUtils;
* This won't work for existing prototype references, which are independent. However,
* it will work for prototypes subsequently obtained from the factory. Changes to
* interception will work immediately on singletons (including existing references).
* However, to change interfaces or a target it's necessary to obtain a new instance
* However, to change interfaces or target it's necessary to obtain a new instance
* from the factory. This means that singleton instances obtained from the factory
* do not have the same object identity. However, they do have the same interceptors
* and target, and changing any reference will change all objects.
@@ -407,7 +406,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
if (namedBeanClass != null) {
return (Advisor.class.isAssignableFrom(namedBeanClass) || Advice.class.isAssignableFrom(namedBeanClass));
}
// Treat it as a target bean if we can't tell.
// Treat it as an target bean if we can't tell.
if (logger.isDebugEnabled()) {
logger.debug("Could not determine type of bean with name '" + beanName +
"' - assuming it is neither an Advisor nor an Advice");
@@ -422,10 +421,14 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
* are unaffected by such changes.
*/
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
if (!this.advisorChainInitialized && !ObjectUtils.isEmpty(this.interceptorNames)) {
if (this.advisorChainInitialized) {
return;
}
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
"- cannot resolve interceptor names " + Arrays.toString(this.interceptorNames));
"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
}
// Globals can't be last unless we specified a targetSource using the property...
@@ -461,9 +464,9 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
addAdvisorOnChainCreation(advice);
}
}
this.advisorChainInitialized = true;
}
this.advisorChainInitialized = true;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 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.
@@ -23,7 +23,6 @@ import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterAdvice;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -52,7 +51,6 @@ public class AfterReturningAdviceInterceptor implements MethodInterceptor, After
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());

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