This commit introduces @DisabledInAotMode in the TestContext
framework to support the following use cases.
- Disabling AOT build-time processing of a test ApplicationContext --
applicable to any testing framework (JUnit 4, JUnit Jupiter, etc.).
- Disabling an entire test class or a single test method at run time
when the test suite is run with AOT optimizations enabled -- only
applicable to JUnit Jupiter based tests.
Closes gh-30834
As a workaround before a proper solution the Spring team is trying to
find with the Hibernate team in a future version of Hibernate, this
commit introduces 2 GraalVM substitutions that should allow to remove
ByteBuddy reachability with Hibernate 6.3.
Closes gh-29549
VirtualThreadDelegate built on JDK 21 for multi-release jar.
Includes dedicated VirtualThreadTaskExecutor as lean option.
Includes setVirtualThreads flag on SimpleAsyncTaskExecutor.
Includes additional default methods on AsyncTaskExecutor.
Closes gh-30241
This commit picks up where the two previous commits left off.
Specifically, this commit:
- Removes the "severity=warning" configuration to ensure that violations
actually fail the build.
- Fixes regular expressions for suppressions by matching forward
slashes using `[\\/]` instead of `\/`.
- Moves the configuration for newly introduced checks to locations in
checkstyle.xml that align with the existing organization of that file.
- Renames the IDs for RegexpSinglelineJava checks from
javaDocPackageNonNullApiAnnotation/javaDocPackageNonNullFieldsAnnotation
to packageLevelNonNullApiAnnotation/packageLevelNonNullFieldsAnnotation,
respectively, since these checks are not related to Javadoc.
- Simplifies the null-safety annotation checks to match against
imported annotation types, which enforces consistency across
package-info.java files for the annotation declarations.
- Simplifies the RegEx for JavadocPackage suppressions to only exclude
packages not under src/main/java (vs src/main) and those in the
framework-docs module.
- Consistently suppresses all checks for the `asm`, `cglib`, `objenesis`,
and `javapoet` packages in spring-core.
- Adds explicit suppressions for null-safety annotations for the `lang`
package in spring-core.
- Adds explicit suppressions for null-safety annotations for the
`org.aopalliance` package in spring-aop.
- Revises the RegEx for null-safety annotation suppressions to only
exclude package-info.java files not under src/main/java and
additionally to exclude package-info.java files in the framework-docs
module as well as those in the spring-context-indexer,
spring-instrument, and spring-jcl modules.
- Adds all missing package-info.java files.
- Adds null-safety annotations to package-info.java files where
appropriate.
Closes gh-30069
This commit updates the project's checkstyle configuration to check
that package-info.java files contain the @NonNullApi and @NonNullFields
null-safety annotations.
See gh-30069
This commit updates the project's checkstyle configuration to require
the existence of a package-info.java file for all packages within the
src/main directory while excluding the framework-docs module and
certain packages inside the spring-core module. A missing
package-info.java file will result in emitting a warning.
See gh-30069
This commit introduces tests which serve as "regression tests" for the
behavior of PathMatchingResourcePatternResolver in Spring Framework
5.3.x with regard to URL-encoding and Unicode normalization of resource
paths.
Specifically, the new tests demonstrate that resource paths do NOT need
to be decoded or normalized in 5.3.x.
See gh-29243
This commit introduces automatic registration of a runtime hint for
classpath resources configured via the `value` attribute in
@WebAppConfiguration.
Closes gh-29026
This commit provides an alternative
java.beans.Introspector#findCustomizerClass implementation
via a GraalVM substitution that avoids to include thousands
of unused AWT classes in the native image.
Closes gh-29060
This commit introduces the TestClassScanner which scans provided
classpath roots for Spring integration test classes using the JUnit
Platform Launcher API which allows all registered TestEngines to
discover tests according to their own rules.
The scanner currently detects the following categories of Spring
integration test classes.
- JUnit Jupiter: classes that register the SpringExtension via
@ExtendWith.
- JUnit 4: classes that register the SpringJUnit4ClassRunner or
SpringRunner via @RunWith.
- Generic: classes that are annotated with @ContextConfiguration or
@BootstrapWith.
The scanner has been tested with the following TestEngine
implementations for the JUnit Platform.
- JUnit Jupiter
- JUnit Vintage
- JUnit Platform Suite Engine
- TestNG Engine for the JUnit Platform
Closes gh-28824
This commit adds the supporting testing infrastructure using the
`RuntimeHintsAgent`. Given that the agent is loaded by the JVM running
the test suite, we can then use it to record method invocations at
runtime and check whether the prepared `RuntimeHints` match the expected
behavior.
This commit contributes the `RuntimeHintsRecorder`. With this, we can
record relevant method invocations for a given lambda, focusing on a
specific part of the code behavior. This returns a
`RuntimeHintsInvocations` instance, which is an AssertJ assert provider.
From there, we can perform assertions on the recorded invocations and
check that a given collection of hints cover the reflection, resources
and proxies needs at runtime.
This also ships the `@EnabledIfRuntimeHintsAgent` opinionated
annotation: this applies the `RuntimeHintsAgentCondition` JUnit
extension that detects whether the `RuntimeHintsAgent` is loaded by the
current JVM. Tests annotated with this will be skipped if the agent is
not present. This annotation is also tagged with a JUnit `@Tag` to
gather such tests in a specific `"RuntimeHintsTests"` test suite.
In the Spring Framework build, we have chosen to isolate such tests and
not load the agent for the main test suite ("RuntimeHintsTests" tests
are excluded from the main suite). While the agent's intent is to be as
transparent as possible, there are security and access considerations
that could interefere with other tests.
With this approach, we can then create a separate test suite and run
agent tests in a dedicated JVM.
Note that projects using this infrastructure can choose to use the
condition by itself in a custom annotation.
Here is an example of this testing infrastructure:
```
@EnabledIfRuntimeHintsAgent
class MyTestCases {
@Test
void hintsForMethodsReflectionShouldMatch() {
RuntimeHints hints = new RuntimeHints();
hints.reflection().registerType(String.class,
hint -> hint.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS));
RuntimeHintsInvocations invocations = RuntimeHintsRecorder.record(() -> {
Method[] methods = String.class.getMethods();
});
assertThat(invocations).match(hints);
}
}
```
See gh-27981
Update the `TestCompiler` so that classes can be defined using
a `Lookup`. This update allows package-private classes to be
accessed without needing a quite so unusual classloader setup.
The `@CompileWithTargetClassAccess` should be added to any
test that needs to use `Lookup` based defines. The test will
run with a completed forked classloader so not to pollute the
main classloader.
This commit also adds some useful additional APIs.
See gh-28120
Prior to this commit, if AOP proxy generation was configured with
proxyTargetClass=true (which is the default behavior in recent versions
of Spring Boot), beans implemented as lambda expressions or method
references could not be proxied with CGLIB on Java 16 or higher without
specifying `--add-opens java.base/java.lang=ALL-UNNAMED`.
This commit addresses this shortcoming by ensuring that beans
implemented as lambda expressions or method references are always
proxied using a JDK dynamic proxy even if proxyTargetClass=true.
Closes gh-27971
In order to be able to use text blocks and other new Java language
features, we are upgrading to a recent version of Checkstyle.
The latest version of spring-javaformat-checkstyle (0.0.28) is built
against Checkstyle 8.32 which does not include support for language
features such as text blocks. Support for text blocks was added in
Checkstyle 8.36.
In addition, there is a binary compatibility issue between
spring-javaformat-checkstyle 0.0.28 and Checkstyle 8.42. Thus we cannot
use Checkstyle 8.42 or higher.
In this commit, we therefore upgrade to spring-javaformat-checkstyle
0.0.28 and downgrade to Checkstyle 8.41.
This change is being applied to `5.3.x` as well as `main` in order to
benefit from the enhanced checking provided in more recent versions of
Checkstyle.
Closes gh-27481
This commit fixes various issues with the configuration of the Gradle
Java toolchain in the build.
First, the configuration of build properties is fixed in the CI pipeline
because it wasn't properly checked.
The JMH plugin is also upgraded and we now configure its toolchain
support.
This commit also rewrites the XJC tasks in the spring-oxm module,
leveraging a Gradle plugin that creates actual compile tasks we can
configure.
See gh-25787
Prior to this commit (and the previous one), the `AntPathStringMatcher`
(inner class of `AntPathmatcher`) would compile `Pattern` instances and
use regex matching even for static patterns such as `"/home"`.
This change introduces a shortcut in the string matcher algorithm to
skip the `Pattern` creation and uses `String` equality instead.
Static patterns are quite common in applications and this change can
bring performance improvements, depending on the mix of patterns
configured in the web application.
In benchmarks (added with this commit), we're seeing +20% throughput
and -40% allocation. This of course can vary depending on the number of
static patterns configured in the application.
Closes gh-24887
Prior to this commit, the Spring Framework test suite would rely only on
"Performance" tests associated with a specific CI build. As outlined in
gh-24830, the way they're built and executed is not working well
anymore.
This commit introduces a new JMH benchmark infrastructure in the build.
The goal here is not to run those benchmarks as part of a CI build, but
rather provide a proper infrastructure for writing and locally running
micro-benchmarks when working on specific optimizations.
This commit adds and configures a Gradle JMH plugin to allow for JMH
benchmark classes in Spring Framework modules (in `src/jmh/java` of each
`spring-*` module). It's also relaxing the checkstyle rules for JMH
classes, especially around Javadoc rules: this code is not meant to
have Javadocs.
Finally, this commit links to a new Wiki page on the project GitHub
repository documenting the infrastructure and helping contributors to
run and design benchmarks.
See gh-24830
Previously, spring-webmvc and spring-webflux both contained tests
that would create gzipped files, write them to the filesystem
alongside the project's compiled test classes, and configure them to
be deleted on JVM exit. The output location placed the files on the
classpath, polluting it for every subsequent test that used the same
ClassLoader. The test-sources plugin combined with Gradle's use of
worker JVMs, broadens the scope of this pollution to other, downstream
projects in the same build. For example, the tests for
spring-websocket will have a different classpath depending on whether
or not the tests for spring-webmvc have already been run on the same
worker as part of the current build.
This commit updates the spring-webmvc and spring-webflux modules to
introduce a new JUnit Jupiter extension, GzipSupport. This extension
allows gzipped files to be created via an injectable GzippedFiles
class and automatically deletes each created file in an after-each
callback. This ensures that a gzipped file only exists on the
classpath for the duration of the test that needs it, avoiding the
pollution of the classpath of any subsequent tests.
Closes gh-23970
Commit 979508a7f3a02df0a2a24a3dfc6968e70786684c removed the JUnit 4
dependency from all modules except spring-test. Unfortunately, the
@Inject TCK tests (SpringAtInjectTckTests) are still based on JUnit 3.
Thus, that commit accidentally excluded those tests from the build.
This commit includes SpringAtInjectTckTests in the build again by
introducing a test runtime dependency on the JUnit Vintage TestEngine
in spring-context.
See gh-23451
Prior to this commit, a lot of work had been done to prevent improper
use of testing Framework APIs throughout the codebase; however, there
were still some loopholes.
This commit addresses these loopholes by introducing additional
Checkstyle rules (and modifying existing rules) to prevent improper use
of testing framework APIs in production code as well as in test code.
- Checkstyle rules for banned imports have been refactored into
multiple rules specific to JUnit 3, JUnit 4, JUnit Jupiter, and
TestNG.
- Accidental usage of org.junit.Assume has been switched to
org.junit.jupiter.api.Assumptions.
- All test classes now reside under org.springframework packages.
- All test classes (including abstract test classes) now conform to the
`*Tests` naming convention.
- As an added bonus, tests in the renamed
ScenariosForSpringSecurityExpressionTests are now included in the
build.
- Dead JUnit 4 parameterized code has been removed from
DefaultServerWebExchangeCheckNotModifiedTests.
Closes gh-22962
Add `SpringJUnit5` checkstyle rule to ensure that JUnit 4 annotations
aren't accidentally used in new tests.
The "must not be public" rule has been suppressed since there are
quite a few tests that extend base tests from other packages.