diff --git a/build.gradle b/build.gradle index 5cdeac881a92..fd9bca394de6 100644 --- a/build.gradle +++ b/build.gradle @@ -102,7 +102,7 @@ configure([rootProject] + javaProjects) { project -> // TODO Uncomment link to JUnit 5 docs once we execute Gradle with Java 18+. // See https://github.com/spring-projects/spring-framework/issues/27497 // - // "https://junit.org/junit5/docs/5.12.0/api/", + // "https://junit.org/junit5/docs/5.12.1/api/", "https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/", //"https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/", "https://r2dbc.io/spec/1.0.0.RELEASE/api/", diff --git a/framework-docs/framework-docs.gradle b/framework-docs/framework-docs.gradle index 5850c2f51d41..38da4496b819 100644 --- a/framework-docs/framework-docs.gradle +++ b/framework-docs/framework-docs.gradle @@ -45,6 +45,7 @@ dependencies { api(project(":spring-aspects")) api(project(":spring-context")) api(project(":spring-context-support")) + api(project(":spring-core-test")) api(project(":spring-jdbc")) api(project(":spring-jms")) api(project(":spring-test")) @@ -66,9 +67,9 @@ dependencies { api("org.apache.activemq:activemq-ra:6.1.2") api("org.apache.commons:commons-dbcp2:2.11.0") api("org.aspectj:aspectjweaver") + api("org.assertj:assertj-core") api("org.eclipse.jetty.websocket:jetty-websocket-jetty-api") api("org.jetbrains.kotlin:kotlin-stdlib") + api("org.junit.jupiter:junit-jupiter-api") - implementation(project(":spring-core-test")) - implementation("org.assertj:assertj-core") } diff --git a/framework-docs/modules/ROOT/pages/testing/unit.adoc b/framework-docs/modules/ROOT/pages/testing/unit.adoc index 249e58c07b7c..ddc70fd18f8e 100644 --- a/framework-docs/modules/ROOT/pages/testing/unit.adoc +++ b/framework-docs/modules/ROOT/pages/testing/unit.adoc @@ -47,8 +47,7 @@ out-of-container tests for code that depends on environment-specific properties. The `org.springframework.mock.web` package contains a comprehensive set of Servlet API mock objects that are useful for testing web contexts, controllers, and filters. These mock objects are targeted at usage with Spring's Web MVC framework and are generally more -convenient to use than dynamic mock objects (such as https://easymock.org/[EasyMock]) -or alternative Servlet API mock objects (such as http://www.mockobjects.com[MockObjects]). +convenient to use than dynamic mock objects (such as https://easymock.org/[EasyMock]). TIP: Since Spring Framework 6.0, the mock objects in `org.springframework.mock.web` are based on the Servlet 6.0 API. diff --git a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc index dca3a958c6f8..d7c780ea27f6 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux-view.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux-view.adoc @@ -225,9 +225,9 @@ The following table shows the templating libraries that we have tested on differ |Scripting Library |Scripting Engine |https://handlebarsjs.com/[Handlebars] |https://openjdk.java.net/projects/nashorn/[Nashorn] |https://mustache.github.io/[Mustache] |https://openjdk.java.net/projects/nashorn/[Nashorn] -|https://facebook.github.io/react/[React] |https://openjdk.java.net/projects/nashorn/[Nashorn] -|https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn] -|https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby] +|https://react.dev/[React] |https://openjdk.java.net/projects/nashorn/[Nashorn] +|https://ejs.co/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn] +|https://docs.ruby-lang.org/en/master/ERB.html[ERB] |https://www.jruby.org[JRuby] |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython] |https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin] |=== diff --git a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc index 53ff9683c69e..e22e07b94bbe 100644 --- a/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc +++ b/framework-docs/modules/ROOT/pages/web/webflux/controller/ann-validation.adoc @@ -57,7 +57,7 @@ locale and language specific resource bundles. For further custom handling of method validation errors, you can extend `ResponseEntityExceptionHandler` or use an `@ExceptionHandler` method in a controller or in a `@ControllerAdvice`, and handle `HandlerMethodValidationException` directly. -The exception contains a list of``ParameterValidationResult``s that group validation errors +The exception contains a list of ``ParameterValidationResult``s that group validation errors by method parameter. You can either iterate over those, or provide a visitor with callback methods by controller method parameter type: diff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc index 5329bc919cf6..3bb07dfbe067 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-script.adoc @@ -13,9 +13,9 @@ templating libraries on different script engines: |Scripting Library |Scripting Engine |https://handlebarsjs.com/[Handlebars] |https://openjdk.java.net/projects/nashorn/[Nashorn] |https://mustache.github.io/[Mustache] |https://openjdk.java.net/projects/nashorn/[Nashorn] -|https://facebook.github.io/react/[React] |https://openjdk.java.net/projects/nashorn/[Nashorn] -|https://www.embeddedjs.com/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn] -|https://www.stuartellis.name/articles/erb/[ERB] |https://www.jruby.org[JRuby] +|https://react.dev/[React] |https://openjdk.java.net/projects/nashorn/[Nashorn] +|https://ejs.co/[EJS] |https://openjdk.java.net/projects/nashorn/[Nashorn] +|https://docs.ruby-lang.org/en/master/ERB.html[ERB] |https://www.jruby.org[JRuby] |https://docs.python.org/2/library/string.html#template-strings[String templates] |https://www.jython.org/[Jython] |https://github.com/sdeleuze/kotlin-script-templating[Kotlin Script templating] |{kotlin-site}[Kotlin] |=== diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc index dd11e2edd769..34cf05e99df2 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-validation.adoc @@ -57,7 +57,7 @@ locale and language specific resource bundles. For further custom handling of method validation errors, you can extend `ResponseEntityExceptionHandler` or use an `@ExceptionHandler` method in a controller or in a `@ControllerAdvice`, and handle `HandlerMethodValidationException` directly. -The exception contains a list of``ParameterValidationResult``s that group validation errors +The exception contains a list of ``ParameterValidationResult``s that group validation errors by method parameter. You can either iterate over those, or provide a visitor with callback methods by controller method parameter type: diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc index 446ae42c0414..9a4f769aa5a2 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-security.adoc @@ -13,7 +13,7 @@ reference documentation, including: * {docs-spring-security}/features/exploits/csrf.html#csrf-protection[CSRF protection] * {docs-spring-security}/features/exploits/headers.html[Security Response Headers] -https://hdiv.org/[HDIV] is another web security framework that integrates with Spring MVC. +https://github.com/hdiv/hdiv[HDIV] is another web security framework that integrates with Spring MVC. diff --git a/framework-platform/framework-platform.gradle b/framework-platform/framework-platform.gradle index fe4829dd0376..7d653acad634 100644 --- a/framework-platform/framework-platform.gradle +++ b/framework-platform/framework-platform.gradle @@ -20,8 +20,8 @@ dependencies { api(platform("org.eclipse.jetty.ee10:jetty-ee10-bom:12.0.17")) api(platform("org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1")) api(platform("org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.3")) - api(platform("org.junit:junit-bom:5.12.0")) - api(platform("org.mockito:mockito-bom:5.16.0")) + api(platform("org.junit:junit-bom:5.12.1")) + api(platform("org.mockito:mockito-bom:5.16.1")) constraints { api("com.fasterxml:aalto-xml:1.3.2") diff --git a/gradle.properties b/gradle.properties index b593061368c3..a27bc9fe8ad6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=6.2.4-SNAPSHOT +version=6.2.5 org.gradle.caching=true org.gradle.jvmargs=-Xmx2048m diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java index ec9b634ff89f..e581f6814dbe 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 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. @@ -241,7 +241,7 @@ public String[] getParameterNames(Method method) { try { int algorithmicStep = STEP_JOIN_POINT_BINDING; - while ((this.numberOfRemainingUnboundArguments > 0) && algorithmicStep < STEP_FINISHED) { + while (this.numberOfRemainingUnboundArguments > 0 && algorithmicStep < STEP_FINISHED) { switch (algorithmicStep++) { case STEP_JOIN_POINT_BINDING -> { if (!maybeBindThisJoinPoint()) { @@ -373,7 +373,8 @@ private void maybeBindReturningVariable() { if (this.returningName != null) { if (this.numberOfRemainingUnboundArguments > 1) { throw new AmbiguousBindingException("Binding of returning parameter '" + this.returningName + - "' is ambiguous: there are " + this.numberOfRemainingUnboundArguments + " candidates."); + "' is ambiguous: there are " + this.numberOfRemainingUnboundArguments + " candidates. " + + "Consider compiling with -parameters in order to make declared parameter names available."); } // We're all set... find the unbound parameter, and bind it. @@ -485,8 +486,8 @@ private void maybeExtractVariableNamesFromArgs(@Nullable String argsSpec, List 1) { - throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments - + " unbound args at this()/target()/args() binding stage, with no way to determine between them"); + throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments + + " unbound args at this()/target()/args() binding stage, with no way to determine between them"); } List varNames = new ArrayList<>(); @@ -535,8 +536,8 @@ else if (varNames.size() == 1) { private void maybeBindReferencePointcutParameter() { if (this.numberOfRemainingUnboundArguments > 1) { - throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments - + " unbound args at reference pointcut binding stage, with no way to determine between them"); + throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments + + " unbound args at reference pointcut binding stage, with no way to determine between them"); } List varNames = new ArrayList<>(); @@ -741,7 +742,9 @@ private void findAndBind(Class argumentType, String varName) { * Simple record to hold the extracted text from a pointcut body, together * with the number of tokens consumed in extracting it. */ - private record PointcutBody(int numTokensConsumed, @Nullable String text) {} + private record PointcutBody(int numTokensConsumed, @Nullable String text) { + } + /** * Thrown in response to an ambiguous binding being detected when diff --git a/spring-aop/src/main/java/org/springframework/aop/config/AspectEntry.java b/spring-aop/src/main/java/org/springframework/aop/config/AspectEntry.java index 93540fe11ddb..e0823a525d4c 100644 --- a/spring-aop/src/main/java/org/springframework/aop/config/AspectEntry.java +++ b/spring-aop/src/main/java/org/springframework/aop/config/AspectEntry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,8 +46,8 @@ public AspectEntry(String id, String ref) { @Override public String toString() { - return "Aspect: " + (StringUtils.hasLength(this.id) ? "id='" + this.id + "'" - : "ref='" + this.ref + "'"); + return "Aspect: " + (StringUtils.hasLength(this.id) ? "id='" + this.id + "'" : + "ref='" + this.ref + "'"); } } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/ClassFilters.java b/spring-aop/src/main/java/org/springframework/aop/support/ClassFilters.java index 929196e66b74..f58dfa8cb8ce 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/ClassFilters.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/ClassFilters.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 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. @@ -198,8 +198,8 @@ public boolean matches(Class clazz) { @Override public boolean equals(Object other) { - return (this == other || (other instanceof NegateClassFilter that - && this.original.equals(that.original))); + return (this == other || (other instanceof NegateClassFilter that && + this.original.equals(that.original))); } @Override diff --git a/spring-aop/src/main/java/org/springframework/aop/support/MethodMatchers.java b/spring-aop/src/main/java/org/springframework/aop/support/MethodMatchers.java index f2d226adfb28..e333cf2aabef 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/MethodMatchers.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/MethodMatchers.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 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,8 +378,8 @@ public boolean matches(Method method, Class targetClass, Object... args) { @Override public boolean equals(Object other) { - return (this == other || (other instanceof NegateMethodMatcher that - && this.original.equals(that.original))); + return (this == other || (other instanceof NegateMethodMatcher that && + this.original.equals(that.original))); } @Override diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactoryTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactoryTests.java index 02d968212d53..03cc27f239f0 100644 --- a/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactoryTests.java +++ b/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -203,7 +203,6 @@ void perThisAspect() throws Exception { itb.getSpouse(); assertThat(maaif.isMaterialized()).isTrue(); - assertThat(imapa.getDeclaredPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getAge"), null)).isTrue(); assertThat(itb.getAge()).as("Around advice must apply").isEqualTo(0); @@ -301,7 +300,7 @@ void bindingWithSingleArg() { void bindingWithMultipleArgsDifferentlyOrdered() { ManyValuedArgs target = new ManyValuedArgs(); ManyValuedArgs mva = createProxy(target, ManyValuedArgs.class, - getAdvisorFactory().getAdvisors(aspectInstanceFactory(new ManyValuedArgs(), "someBean"))); + getAdvisorFactory().getAdvisors(aspectInstanceFactory(new ManyValuedArgs(), "someBean"))); String a = "a"; int b = 12; @@ -320,7 +319,7 @@ void introductionOnTargetNotImplementingInterface() { NotLockable notLockableTarget = new NotLockable(); assertThat(notLockableTarget).isNotInstanceOf(Lockable.class); NotLockable notLockable1 = createProxy(notLockableTarget, NotLockable.class, - getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean"))); + getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean"))); assertThat(notLockable1).isInstanceOf(Lockable.class); Lockable lockable = (Lockable) notLockable1; assertThat(lockable.locked()).isFalse(); @@ -329,7 +328,7 @@ void introductionOnTargetNotImplementingInterface() { NotLockable notLockable2Target = new NotLockable(); NotLockable notLockable2 = createProxy(notLockable2Target, NotLockable.class, - getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean"))); + getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean"))); assertThat(notLockable2).isInstanceOf(Lockable.class); Lockable lockable2 = (Lockable) notLockable2; assertThat(lockable2.locked()).isFalse(); @@ -343,20 +342,19 @@ void introductionOnTargetNotImplementingInterface() { void introductionAdvisorExcludedFromTargetImplementingInterface() { assertThat(AopUtils.findAdvisorsThatCanApply( getAdvisorFactory().getAdvisors( - aspectInstanceFactory(new MakeLockable(), "someBean")), + aspectInstanceFactory(new MakeLockable(), "someBean")), CannotBeUnlocked.class)).isEmpty(); assertThat(AopUtils.findAdvisorsThatCanApply(getAdvisorFactory().getAdvisors( - aspectInstanceFactory(new MakeLockable(),"someBean")), NotLockable.class)).hasSize(2); + aspectInstanceFactory(new MakeLockable(),"someBean")), NotLockable.class)).hasSize(2); } @Test void introductionOnTargetImplementingInterface() { CannotBeUnlocked target = new CannotBeUnlocked(); Lockable proxy = createProxy(target, CannotBeUnlocked.class, - // Ensure that we exclude AopUtils.findAdvisorsThatCanApply( - getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")), - CannotBeUnlocked.class)); + getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")), + CannotBeUnlocked.class)); assertThat(proxy).isInstanceOf(Lockable.class); Lockable lockable = proxy; assertThat(lockable.locked()).as("Already locked").isTrue(); @@ -370,8 +368,8 @@ void introductionOnTargetExcludedByTypePattern() { ArrayList target = new ArrayList<>(); List proxy = createProxy(target, List.class, AopUtils.findAdvisorsThatCanApply( - getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")), - List.class)); + getAdvisorFactory().getAdvisors(aspectInstanceFactory(new MakeLockable(), "someBean")), + List.class)); assertThat(proxy).as("Type pattern must have excluded mixin").isNotInstanceOf(Lockable.class); } @@ -379,7 +377,7 @@ void introductionOnTargetExcludedByTypePattern() { void introductionBasedOnAnnotationMatch() { // gh-9980 AnnotatedTarget target = new AnnotatedTargetImpl(); List advisors = getAdvisorFactory().getAdvisors( - aspectInstanceFactory(new MakeAnnotatedTypeModifiable(), "someBean")); + aspectInstanceFactory(new MakeAnnotatedTypeModifiable(), "someBean")); Object proxy = createProxy(target, AnnotatedTarget.class, advisors); assertThat(proxy).isInstanceOf(Lockable.class); Lockable lockable = (Lockable) proxy; @@ -393,9 +391,9 @@ void introductionWithArgumentBinding() { TestBean target = new TestBean(); List advisors = getAdvisorFactory().getAdvisors( - aspectInstanceFactory(new MakeITestBeanModifiable(), "someBean")); + aspectInstanceFactory(new MakeITestBeanModifiable(), "someBean")); advisors.addAll(getAdvisorFactory().getAdvisors( - aspectInstanceFactory(new MakeLockable(), "someBean"))); + aspectInstanceFactory(new MakeLockable(), "someBean"))); Modifiable modifiable = (Modifiable) createProxy(target, ITestBean.class, advisors); assertThat(modifiable).isInstanceOf(Modifiable.class); @@ -426,7 +424,7 @@ void aspectMethodThrowsExceptionLegalOnSignature() { TestBean target = new TestBean(); UnsupportedOperationException expectedException = new UnsupportedOperationException(); List advisors = getAdvisorFactory().getAdvisors( - aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean")); + aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean")); assertThat(advisors).as("One advice method was found").hasSize(1); ITestBean itb = createProxy(target, ITestBean.class, advisors); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(itb::getAge); @@ -439,12 +437,12 @@ void aspectMethodThrowsExceptionIllegalOnSignature() { TestBean target = new TestBean(); RemoteException expectedException = new RemoteException(); List advisors = getAdvisorFactory().getAdvisors( - aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean")); + aspectInstanceFactory(new ExceptionThrowingAspect(expectedException), "someBean")); assertThat(advisors).as("One advice method was found").hasSize(1); ITestBean itb = createProxy(target, ITestBean.class, advisors); assertThatExceptionOfType(UndeclaredThrowableException.class) - .isThrownBy(itb::getAge) - .withCause(expectedException); + .isThrownBy(itb::getAge) + .withCause(expectedException); } @Test @@ -452,7 +450,7 @@ void twoAdvicesOnOneAspect() { TestBean target = new TestBean(); TwoAdviceAspect twoAdviceAspect = new TwoAdviceAspect(); List advisors = getAdvisorFactory().getAdvisors( - aspectInstanceFactory(twoAdviceAspect, "someBean")); + aspectInstanceFactory(twoAdviceAspect, "someBean")); assertThat(advisors).as("Two advice methods found").hasSize(2); ITestBean itb = createProxy(target, ITestBean.class, advisors); itb.setName(""); @@ -466,7 +464,7 @@ void twoAdvicesOnOneAspect() { void afterAdviceTypes() throws Exception { InvocationTrackingAspect aspect = new InvocationTrackingAspect(); List advisors = getAdvisorFactory().getAdvisors( - aspectInstanceFactory(aspect, "exceptionHandlingAspect")); + aspectInstanceFactory(aspect, "exceptionHandlingAspect")); Echo echo = createProxy(new Echo(), Echo.class, advisors); assertThat(aspect.invocations).isEmpty(); @@ -475,7 +473,7 @@ void afterAdviceTypes() throws Exception { aspect.invocations.clear(); assertThatExceptionOfType(FileNotFoundException.class) - .isThrownBy(() -> echo.echo(new FileNotFoundException())); + .isThrownBy(() -> echo.echo(new FileNotFoundException())); assertThat(aspect.invocations).containsExactly("around - start", "before", "after throwing", "after", "around - end"); } @@ -487,7 +485,6 @@ void nonAbstractParentAspect() { assertThat(Modifier.isAbstract(aspect.getClass().getSuperclass().getModifiers())).isFalse(); List advisors = getAdvisorFactory().getAdvisors(aspectInstanceFactory(aspect, "incrementingAspect")); - ITestBean proxy = createProxy(new TestBean("Jane", 42), ITestBean.class, advisors); assertThat(proxy.getAge()).isEqualTo(86); // (42 + 1) * 2 } @@ -812,19 +809,19 @@ void before() { invocations.add("before"); } - @AfterReturning("echo()") - void afterReturning() { - invocations.add("after returning"); + @After("echo()") + void after() { + invocations.add("after"); } - @AfterThrowing("echo()") - void afterThrowing() { - invocations.add("after throwing"); + @AfterReturning(pointcut = "this(target) && execution(* echo(*))", returning = "returnValue") + void afterReturning(JoinPoint joinPoint, Echo target, Object returnValue) { + invocations.add("after returning"); } - @After("echo()") - void after() { - invocations.add("after"); + @AfterThrowing(pointcut = "this(target) && execution(* echo(*))", throwing = "exception") + void afterThrowing(JoinPoint joinPoint, Echo target, Throwable exception) { + invocations.add("after throwing"); } } @@ -967,7 +964,7 @@ private Method getGetterFromSetter(Method setter) { class MakeITestBeanModifiable extends AbstractMakeModifiable { @DeclareParents(value = "org.springframework.beans.testfixture.beans.ITestBean+", - defaultImpl=ModifiableImpl.class) + defaultImpl = ModifiableImpl.class) static MutableModifiable mixin; } diff --git a/spring-aop/src/test/java/org/springframework/aop/interceptor/AsyncExecutionInterceptorTests.java b/spring-aop/src/test/java/org/springframework/aop/interceptor/AsyncExecutionInterceptorTests.java index e18f4d24b8c6..92c295a59ecb 100644 --- a/spring-aop/src/test/java/org/springframework/aop/interceptor/AsyncExecutionInterceptorTests.java +++ b/spring-aop/src/test/java/org/springframework/aop/interceptor/AsyncExecutionInterceptorTests.java @@ -27,13 +27,12 @@ import org.springframework.core.task.AsyncTaskExecutor; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; - /** * Tests for {@link AsyncExecutionInterceptor}. * diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java b/spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java index d62c3ee6d3cb..06769790d107 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java @@ -274,7 +274,7 @@ default Stream orderedStream() { * @see #orderedStream(Predicate) */ default Stream stream(Predicate> customFilter) { - return stream().filter(obj -> customFilter.test(obj.getClass())); + return stream(customFilter, true); } /** @@ -288,6 +288,44 @@ default Stream stream(Predicate> customFilter) { * @see #stream(Predicate) */ default Stream orderedStream(Predicate> customFilter) { + return orderedStream(customFilter, true); + } + + /** + * Return a custom-filtered {@link Stream} over all matching object instances, + * without specific ordering guarantees (but typically in registration order). + * @param customFilter a custom type filter for selecting beans among the raw + * bean type matches (or {@link #UNFILTERED} for all raw type matches without + * any default filtering) + * @param includeNonSingletons whether to include prototype or scoped beans too + * or just singletons (also applies to FactoryBeans) + * @since 6.2.5 + * @see #stream(Predicate) + * @see #orderedStream(Predicate, boolean) + */ + default Stream stream(Predicate> customFilter, boolean includeNonSingletons) { + if (!includeNonSingletons) { + throw new UnsupportedOperationException("Only supports includeNonSingletons=true by default"); + } + return stream().filter(obj -> customFilter.test(obj.getClass())); + } + + /** + * Return a custom-filtered {@link Stream} over all matching object instances, + * pre-ordered according to the factory's common order comparator. + * @param customFilter a custom type filter for selecting beans among the raw + * bean type matches (or {@link #UNFILTERED} for all raw type matches without + * any default filtering) + * @param includeNonSingletons whether to include prototype or scoped beans too + * or just singletons (also applies to FactoryBeans) + * @since 6.2.5 + * @see #orderedStream() + * @see #stream(Predicate) + */ + default Stream orderedStream(Predicate> customFilter, boolean includeNonSingletons) { + if (!includeNonSingletons) { + throw new UnsupportedOperationException("Only supports includeNonSingletons=true by default"); + } return orderedStream().filter(obj -> customFilter.test(obj.getClass())); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/AotServices.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/AotServices.java index c26a9c1ac845..5145ee7ee252 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/AotServices.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/AotServices.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 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. @@ -212,9 +212,9 @@ public AotServices load(Class type) { } private Map loadBeans(Class type) { - return (this.beanFactory != null) ? BeanFactoryUtils - .beansOfTypeIncludingAncestors(this.beanFactory, type, true, false) - : Collections.emptyMap(); + return (this.beanFactory != null ? + BeanFactoryUtils.beansOfTypeIncludingAncestors(this.beanFactory, type, true, false) : + Collections.emptyMap()); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactory.java index 6938f0c9ef2b..1e9813153783 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactory.java @@ -69,8 +69,8 @@ class BeanDefinitionMethodGeneratorFactory { this.excludeFilters = loader.load(BeanRegistrationExcludeFilter.class); for (BeanRegistrationExcludeFilter excludeFilter : this.excludeFilters) { if (this.excludeFilters.getSource(excludeFilter) == Source.BEAN_FACTORY) { - Assert.state(excludeFilter instanceof BeanRegistrationAotProcessor - || excludeFilter instanceof BeanFactoryInitializationAotProcessor, + Assert.state(excludeFilter instanceof BeanRegistrationAotProcessor || + excludeFilter instanceof BeanFactoryInitializationAotProcessor, () -> "BeanRegistrationExcludeFilter bean of type %s must also implement an AOT processor interface" .formatted(excludeFilter.getClass().getName())); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java index 3e03043075c3..aa5abb243d92 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java @@ -234,8 +234,7 @@ private void buildGetInstanceMethodForConstructor(MethodSpec.Builder method, Con CodeBlock arguments = hasArguments ? new AutowiredArgumentsCodeGenerator(actualType, constructor) - .generateCode(constructor.getParameterTypes(), (onInnerClass ? 1 : 0)) - : NO_ARGS; + .generateCode(constructor.getParameterTypes(), (onInnerClass ? 1 : 0)) : NO_ARGS; CodeBlock newInstance = generateNewInstanceCodeForConstructor(actualType, arguments); code.add(generateWithGeneratorCode(hasArguments, newInstance)); @@ -325,8 +324,7 @@ private void buildGetInstanceMethodForFactoryMethod(MethodSpec.Builder method, boolean hasArguments = factoryMethod.getParameterCount() > 0; CodeBlock arguments = hasArguments ? new AutowiredArgumentsCodeGenerator(ClassUtils.getUserClass(targetClass), factoryMethod) - .generateCode(factoryMethod.getParameterTypes()) - : NO_ARGS; + .generateCode(factoryMethod.getParameterTypes()) : NO_ARGS; CodeBlock newInstance = generateNewInstanceCodeForMethod( factoryBeanName, ClassUtils.getUserClass(targetClass), factoryMethodName, arguments); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 57c1d1a38faa..9e879a96a5f0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -487,14 +487,14 @@ public void ifUnique(Consumer dependencyConsumer) throws BeansException { @SuppressWarnings("unchecked") @Override public Stream stream() { - return Arrays.stream(getBeanNamesForTypedStream(requiredType, allowEagerInit)) + return Arrays.stream(beanNamesForStream(requiredType, true, allowEagerInit)) .map(name -> (T) getBean(name)) .filter(bean -> !(bean instanceof NullBean)); } @SuppressWarnings("unchecked") @Override public Stream orderedStream() { - String[] beanNames = getBeanNamesForTypedStream(requiredType, allowEagerInit); + String[] beanNames = beanNamesForStream(requiredType, true, allowEagerInit); if (beanNames.length == 0) { return Stream.empty(); } @@ -510,16 +510,16 @@ public Stream orderedStream() { } @SuppressWarnings("unchecked") @Override - public Stream stream(Predicate> customFilter) { - return Arrays.stream(getBeanNamesForTypedStream(requiredType, allowEagerInit)) + public Stream stream(Predicate> customFilter, boolean includeNonSingletons) { + return Arrays.stream(beanNamesForStream(requiredType, includeNonSingletons, allowEagerInit)) .filter(name -> customFilter.test(getType(name))) .map(name -> (T) getBean(name)) .filter(bean -> !(bean instanceof NullBean)); } @SuppressWarnings("unchecked") @Override - public Stream orderedStream(Predicate> customFilter) { - String[] beanNames = getBeanNamesForTypedStream(requiredType, allowEagerInit); + public Stream orderedStream(Predicate> customFilter, boolean includeNonSingletons) { + String[] beanNames = beanNamesForStream(requiredType, includeNonSingletons, allowEagerInit); if (beanNames.length == 0) { return Stream.empty(); } @@ -559,8 +559,8 @@ else if (parent != null) { return null; } - private String[] getBeanNamesForTypedStream(ResolvableType requiredType, boolean allowEagerInit) { - return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, allowEagerInit); + private String[] beanNamesForStream(ResolvableType requiredType, boolean includeNonSingletons, boolean allowEagerInit) { + return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, includeNonSingletons, allowEagerInit); } @Override @@ -2544,8 +2544,8 @@ private Stream resolveStream(boolean ordered) { } @Override - public Stream stream(Predicate> customFilter) { - return Arrays.stream(getBeanNamesForTypedStream(this.descriptor.getResolvableType(), true)) + public Stream stream(Predicate> customFilter, boolean includeNonSingletons) { + return Arrays.stream(beanNamesForStream(this.descriptor.getResolvableType(), includeNonSingletons, true)) .filter(name -> AutowireUtils.isAutowireCandidate(DefaultListableBeanFactory.this, name)) .filter(name -> customFilter.test(getType(name))) .map(name -> getBean(name)) @@ -2553,8 +2553,8 @@ public Stream stream(Predicate> customFilter) { } @Override - public Stream orderedStream(Predicate> customFilter) { - String[] beanNames = getBeanNamesForTypedStream(this.descriptor.getResolvableType(), true); + public Stream orderedStream(Predicate> customFilter, boolean includeNonSingletons) { + String[] beanNames = beanNamesForStream(this.descriptor.getResolvableType(), includeNonSingletons, true); if (beanNames.length == 0) { return Stream.empty(); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleAutowireCandidateResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleAutowireCandidateResolver.java index 12041b3686da..a1f438195a0c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleAutowireCandidateResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleAutowireCandidateResolver.java @@ -66,10 +66,40 @@ public AutowireCandidateResolver cloneIfNecessary() { * @see org.springframework.beans.factory.config.BeanDefinition#isAutowireCandidate() * @see AbstractBeanDefinition#isDefaultCandidate() */ - @SuppressWarnings("unchecked") public static Map resolveAutowireCandidates(ConfigurableListableBeanFactory lbf, Class type) { + return resolveAutowireCandidates(lbf, type, true, true); + } + + /** + * Resolve a map of all beans of the given type, also picking up beans defined in + * ancestor bean factories, with the specific condition that each bean actually + * has autowire candidate status. This matches simple injection point resolution + * as implemented by this {@link AutowireCandidateResolver} strategy, including + * beans which are not marked as default candidates but excluding beans which + * are not even marked as autowire candidates. + * @param lbf the bean factory + * @param type the type of bean to match + * @param includeNonSingletons whether to include prototype or scoped beans too + * or just singletons (also applies to FactoryBeans) + * @param allowEagerInit whether to initialize lazy-init singletons and + * objects created by FactoryBeans (or by factory methods with a + * "factory-bean" reference) for the type check. Note that FactoryBeans need to be + * eagerly initialized to determine their type: So be aware that passing in "true" + * for this flag will initialize FactoryBeans and "factory-bean" references. + * @return the Map of matching bean instances, or an empty Map if none + * @throws BeansException if a bean could not be created + * @since 6.2.5 + * @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean) + * @see org.springframework.beans.factory.config.BeanDefinition#isAutowireCandidate() + * @see AbstractBeanDefinition#isDefaultCandidate() + */ + @SuppressWarnings("unchecked") + public static Map resolveAutowireCandidates(ConfigurableListableBeanFactory lbf, Class type, + boolean includeNonSingletons, boolean allowEagerInit) { + Map candidates = new LinkedHashMap<>(); - for (String beanName : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(lbf, type)) { + for (String beanName : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(lbf, type, + includeNonSingletons, allowEagerInit)) { if (AutowireUtils.isAutowireCandidate(lbf, beanName)) { Object beanInstance = lbf.getBean(beanName); if (!(beanInstance instanceof NullBean)) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/AbstractBeanDefinitionParser.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/AbstractBeanDefinitionParser.java index 018c85123f9b..14a3998f441d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/AbstractBeanDefinitionParser.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/AbstractBeanDefinitionParser.java @@ -66,8 +66,8 @@ public final BeanDefinition parse(Element element, ParserContext parserContext) String id = resolveId(element, definition, parserContext); if (!StringUtils.hasText(id)) { parserContext.getReaderContext().error( - "Id is required for element '" + parserContext.getDelegate().getLocalName(element) - + "' when used as a top-level tag", element); + "Id is required for element '" + parserContext.getDelegate().getLocalName(element) + + "' when used as a top-level tag", element); } String[] aliases = null; if (shouldParseNameAsAliases()) { diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java index 4238da225ea9..3216b92938db 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java @@ -1519,34 +1519,34 @@ void orderFromAttribute() { bd2.setBeanClass(DerivedTestBean.class); bd2.setPropertyValues(new MutablePropertyValues(List.of(new PropertyValue("name", "highest")))); bd2.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, Ordered.HIGHEST_PRECEDENCE); + bd2.setScope(BeanDefinition.SCOPE_PROTOTYPE); lbf.registerBeanDefinition("bean2", bd2); assertThat(lbf.getBeanProvider(TestBean.class).orderedStream().map(TestBean::getName)) .containsExactly("highest", "lowest"); - assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED).map(TestBean::getName)) - .containsExactly("highest", "lowest"); assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(clazz -> !DerivedTestBean.class.isAssignableFrom(clazz)) .map(TestBean::getName)).containsExactly("lowest"); + assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED).map(TestBean::getName)) + .containsExactly("highest", "lowest"); + assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED, false).map(TestBean::getName)) + .containsExactly("lowest"); } @Test - void orderFromAttributeOverrideAnnotation() { + void orderFromAttributeOverridesAnnotation() { lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); RootBeanDefinition rbd1 = new RootBeanDefinition(LowestPrecedenceTestBeanFactoryBean.class); rbd1.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, Ordered.HIGHEST_PRECEDENCE); lbf.registerBeanDefinition("lowestPrecedenceFactory", rbd1); RootBeanDefinition rbd2 = new RootBeanDefinition(HighestPrecedenceTestBeanFactoryBean.class); rbd2.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, Ordered.LOWEST_PRECEDENCE); + rbd2.setScope(BeanDefinition.SCOPE_PROTOTYPE); lbf.registerBeanDefinition("highestPrecedenceFactory", rbd2); - GenericBeanDefinition bd1 = new GenericBeanDefinition(); - bd1.setFactoryBeanName("highestPrecedenceFactory"); - lbf.registerBeanDefinition("bean1", bd1); - GenericBeanDefinition bd2 = new GenericBeanDefinition(); - bd2.setFactoryBeanName("lowestPrecedenceFactory"); - lbf.registerBeanDefinition("bean2", bd2); assertThat(lbf.getBeanProvider(TestBean.class).orderedStream().map(TestBean::getName)) .containsExactly("fromLowestPrecedenceTestBeanFactoryBean", "fromHighestPrecedenceTestBeanFactoryBean"); assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED).map(TestBean::getName)) .containsExactly("fromLowestPrecedenceTestBeanFactoryBean", "fromHighestPrecedenceTestBeanFactoryBean"); + assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED, false).map(TestBean::getName)) + .containsExactly("fromLowestPrecedenceTestBeanFactoryBean"); } @Test @@ -1987,7 +1987,6 @@ void getBeanByTypeInstanceDefinedInParent() { void getBeanByTypeInstanceWithAmbiguity() { RootBeanDefinition bd1 = createConstructorDependencyBeanDefinition(99); RootBeanDefinition bd2 = new RootBeanDefinition(ConstructorDependency.class); - bd2.setScope(BeanDefinition.SCOPE_PROTOTYPE); bd2.getConstructorArgumentValues().addGenericArgumentValue("43"); lbf.registerBeanDefinition("bd1", bd1); lbf.registerBeanDefinition("bd2", bd2); @@ -2028,6 +2027,10 @@ void getBeanByTypeInstanceWithAmbiguity() { assertThat(resolved).hasSize(2); assertThat(resolved).contains(lbf.getBean("bd1")); assertThat(resolved).contains(lbf.getBean("bd2")); + + resolved = provider.stream(ObjectProvider.UNFILTERED, false).collect(Collectors.toSet()); + assertThat(resolved).hasSize(1); + assertThat(resolved).contains(lbf.getBean("bd2")); } @Test @@ -2082,6 +2085,9 @@ void getBeanByTypeInstanceWithPrimary() { assertThat(resolved).hasSize(2); assertThat(resolved).contains(lbf.getBean("bd1")); assertThat(resolved).contains(lbf.getBean("bd2")); + + resolved = provider.stream(ObjectProvider.UNFILTERED, false).collect(Collectors.toSet()); + assertThat(resolved).isEmpty(); } @Test diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java index f53f9ff5a48a..82917831f999 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java @@ -1614,6 +1614,10 @@ void objectProviderInjectionWithPrototype() { assertThat(testBeans).containsExactly(bf.getBean("testBean1", TestBean.class), bf.getBean("testBean2", TestBean.class)); testBeans = bean.allTestBeansInOrder(); assertThat(testBeans).containsExactly(bf.getBean("testBean1", TestBean.class), bf.getBean("testBean2", TestBean.class)); + testBeans = bean.allSingletonBeans(); + assertThat(testBeans).isEmpty(); + testBeans = bean.allSingletonBeansInOrder(); + assertThat(testBeans).isEmpty(); } @Test @@ -1648,6 +1652,12 @@ void objectProviderInjectionWithSingletonTarget() { testBeans = bean.allTestBeansInOrder(); assertThat(testBeans).hasSize(1); assertThat(testBeans).contains(bf.getBean("testBean", TestBean.class)); + testBeans = bean.allSingletonBeans(); + assertThat(testBeans).hasSize(1); + assertThat(testBeans).contains(bf.getBean("testBean", TestBean.class)); + testBeans = bean.allSingletonBeansInOrder(); + assertThat(testBeans).hasSize(1); + assertThat(testBeans).contains(bf.getBean("testBean", TestBean.class)); } @Test @@ -1675,6 +1685,10 @@ void objectProviderInjectionWithTargetNotAvailable() { assertThat(testBeans).isEmpty(); testBeans = bean.allTestBeansInOrder(); assertThat(testBeans).isEmpty(); + testBeans = bean.allSingletonBeans(); + assertThat(testBeans).isEmpty(); + testBeans = bean.allSingletonBeansInOrder(); + assertThat(testBeans).isEmpty(); } @Test @@ -1698,6 +1712,8 @@ void objectProviderInjectionWithTargetNotUnique() { assertThat(bean.streamTestBeansInOrder()).containsExactly(testBean1, testBean2); assertThat(bean.allTestBeans()).containsExactly(testBean1, testBean2); assertThat(bean.allTestBeansInOrder()).containsExactly(testBean1, testBean2); + assertThat(bean.allSingletonBeans()).containsExactly(testBean1, testBean2); + assertThat(bean.allSingletonBeansInOrder()).containsExactly(testBean1, testBean2); } @Test @@ -1728,6 +1744,8 @@ void objectProviderInjectionWithTargetPrimary() { assertThat(bean.streamTestBeansInOrder()).containsExactly(testBean2, testBean1); assertThat(bean.allTestBeans()).containsExactly(testBean1, testBean2); assertThat(bean.allTestBeansInOrder()).containsExactly(testBean2, testBean1); + assertThat(bean.allSingletonBeans()).containsExactly(testBean1, testBean2); + assertThat(bean.allSingletonBeansInOrder()).containsExactly(testBean2, testBean1); } @Test @@ -1739,7 +1757,7 @@ void objectProviderInjectionWithUnresolvedOrderedStream() { bf.registerBeanDefinition("testBean1", tb1); RootBeanDefinition tb2 = new RootBeanDefinition(TestBeanFactory.class); tb2.setFactoryMethodName("newTestBean2"); - tb2.setLazyInit(true); + tb2.setScope(BeanDefinition.SCOPE_PROTOTYPE); bf.registerBeanDefinition("testBean2", tb2); ObjectProviderInjectionBean bean = bf.getBean("annotatedBean", ObjectProviderInjectionBean.class); @@ -1747,6 +1765,7 @@ void objectProviderInjectionWithUnresolvedOrderedStream() { bf.getBean("testBean1", TestBean.class)); assertThat(bean.allTestBeansInOrder()).containsExactly(bf.getBean("testBean2", TestBean.class), bf.getBean("testBean1", TestBean.class)); + assertThat(bean.allSingletonBeansInOrder()).containsExactly(bf.getBean("testBean1", TestBean.class)); } @Test @@ -1757,6 +1776,7 @@ void objectProviderInjectionWithNonCandidatesInStream() { bf.registerBeanDefinition("testBean1", tb1); RootBeanDefinition tb2 = new RootBeanDefinition(TestBeanFactory.class); tb2.setFactoryMethodName("newTestBean2"); + tb2.setScope(BeanDefinition.SCOPE_PROTOTYPE); bf.registerBeanDefinition("testBean2", tb2); DefaultListableBeanFactory parent = new DefaultListableBeanFactory(); @@ -1789,6 +1809,10 @@ void objectProviderInjectionWithNonCandidatesInStream() { bf.getBean("testBean2", TestBean.class), bf.getBean("testBean4", TestBean.class)); assertThat(bean.allTestBeansInOrder()).containsExactly(bf.getBean("testBean2", TestBean.class), bf.getBean("testBean1", TestBean.class), bf.getBean("testBean4", TestBean.class)); + assertThat(bean.allSingletonBeans()).containsExactly(bf.getBean("testBean1", TestBean.class), + bf.getBean("testBean4", TestBean.class)); + assertThat(bean.allSingletonBeansInOrder()).containsExactly(bf.getBean("testBean1", TestBean.class), + bf.getBean("testBean4", TestBean.class)); Map typeMatches = BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, TestBean.class); assertThat(typeMatches.remove("testBean3")).isNotNull(); @@ -2370,7 +2394,7 @@ void genericsBasedConstructorInjection() { } @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings("unchecked") void genericsBasedConstructorInjectionWithNonTypedTarget() { RootBeanDefinition bd = new RootBeanDefinition(RepositoryConstructorInjectionBean.class); bd.setScope(BeanDefinition.SCOPE_PROTOTYPE); @@ -3393,6 +3417,14 @@ public List allTestBeans() { public List allTestBeansInOrder() { return this.testBean.orderedStream(ObjectProvider.UNFILTERED).toList(); } + + public List allSingletonBeans() { + return this.testBean.stream(ObjectProvider.UNFILTERED, false).toList(); + } + + public List allSingletonBeansInOrder() { + return this.testBean.orderedStream(ObjectProvider.UNFILTERED, false).toList(); + } } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/ParameterResolutionTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/ParameterResolutionTests.java index e2afff6ee817..1ae68d0296ab 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/ParameterResolutionTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/ParameterResolutionTests.java @@ -71,8 +71,8 @@ void annotatedParametersInInnerClassConstructorAreCandidatesForAutowiring() thro } private void assertAutowirableParameters(Executable executable) { - int startIndex = (executable instanceof Constructor) - && ClassUtils.isInnerClass(executable.getDeclaringClass()) ? 1 : 0; + int startIndex = (executable instanceof Constructor) && + ClassUtils.isInnerClass(executable.getDeclaringClass()) ? 1 : 0; Parameter[] parameters = executable.getParameters(); for (int parameterIndex = startIndex; parameterIndex < parameters.length; parameterIndex++) { Parameter parameter = parameters[parameterIndex]; diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanInstanceSupplierTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanInstanceSupplierTests.java index 078bbee216c5..3b33ea70b142 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanInstanceSupplierTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanInstanceSupplierTests.java @@ -103,8 +103,8 @@ void forConstructorWhenNotFoundThrowsException() { RegisteredBean registerBean = source.registerBean(this.beanFactory); assertThatIllegalArgumentException() .isThrownBy(() -> resolver.get(registerBean)).withMessage( - "Constructor with parameter types [java.io.InputStream] cannot be found on " - + SingleArgConstructor.class.getName()); + "Constructor with parameter types [java.io.InputStream] cannot be found on " + + SingleArgConstructor.class.getName()); } @Test @@ -151,8 +151,8 @@ void forFactoryMethodWhenNotFoundThrowsException() { RegisteredBean registerBean = source.registerBean(this.beanFactory); assertThatIllegalArgumentException() .isThrownBy(() -> resolver.get(registerBean)).withMessage( - "Factory method 'single' with parameter types [java.io.InputStream] declared on class " - + SingleArgFactory.class.getName() + " cannot be found"); + "Factory method 'single' with parameter types [java.io.InputStream] declared on class " + + SingleArgFactory.class.getName() + " cannot be found"); } @Test diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/DefaultBeanRegistrationCodeFragmentsTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/DefaultBeanRegistrationCodeFragmentsTests.java index 7379fc22262e..e3b0dbf4b8a6 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/DefaultBeanRegistrationCodeFragmentsTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/DefaultBeanRegistrationCodeFragmentsTests.java @@ -86,8 +86,8 @@ public void getTargetWithInstanceSupplierAndResourceDescription() { BeanRegistrationCodeFragments codeFragments = createInstance(registeredBean); assertThatExceptionOfType(AotBeanProcessingException.class) .isThrownBy(() -> codeFragments.getTarget(registeredBean)) - .withMessageContaining("Error processing bean with name 'testBean' defined in my test resource: " - + "instance supplier is not supported"); + .withMessageContaining("Error processing bean with name 'testBean' defined in my test resource: " + + "instance supplier is not supported"); } @Test diff --git a/spring-context-indexer/src/main/java/org/springframework/context/index/processor/MetadataCollector.java b/spring-context-indexer/src/main/java/org/springframework/context/index/processor/MetadataCollector.java index c1442e32677a..7cae029a3730 100644 --- a/spring-context-indexer/src/main/java/org/springframework/context/index/processor/MetadataCollector.java +++ b/spring-context-indexer/src/main/java/org/springframework/context/index/processor/MetadataCollector.java @@ -93,8 +93,8 @@ public CandidateComponentsMetadata getMetadata() { private boolean shouldBeMerged(ItemMetadata itemMetadata) { String sourceType = itemMetadata.getType(); - return (sourceType != null && !deletedInCurrentBuild(sourceType) - && !processedInCurrentBuild(sourceType)); + return (sourceType != null && !deletedInCurrentBuild(sourceType) && + !processedInCurrentBuild(sourceType)); } private boolean deletedInCurrentBuild(String sourceType) { diff --git a/spring-context-indexer/src/test/java/org/springframework/context/index/processor/Metadata.java b/spring-context-indexer/src/test/java/org/springframework/context/index/processor/Metadata.java index 74c39cfedb7b..23ac0c64c5f0 100644 --- a/spring-context-indexer/src/test/java/org/springframework/context/index/processor/Metadata.java +++ b/spring-context-indexer/src/test/java/org/springframework/context/index/processor/Metadata.java @@ -42,8 +42,8 @@ public static Condition of(String type, ItemMetadata itemMetadata = metadata.getItems().stream() .filter(item -> item.getType().equals(type)) .findFirst().orElse(null); - return itemMetadata != null && itemMetadata.getStereotypes().size() == stereotypes.size() - && itemMetadata.getStereotypes().containsAll(stereotypes); + return (itemMetadata != null && itemMetadata.getStereotypes().size() == stereotypes.size() && + itemMetadata.getStereotypes().containsAll(stereotypes)); }, "Candidates with type %s and stereotypes %s", type, stereotypes); } diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheKeyOperation.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheKeyOperation.java index e3ecd6fa3b25..1ecbdfb05cc7 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheKeyOperation.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheKeyOperation.java @@ -79,8 +79,8 @@ public CacheInvocationParameter[] getKeyParameters(Object... values) { for (CacheParameterDetail keyParameterDetail : this.keyParameterDetails) { int parameterPosition = keyParameterDetail.getParameterPosition(); if (parameterPosition >= values.length) { - throw new IllegalStateException("Values mismatch, key parameter at position " - + parameterPosition + " cannot be matched against " + values.length + " value(s)"); + throw new IllegalStateException("Values mismatch, key parameter at position " + + parameterPosition + " cannot be matched against " + values.length + " value(s)"); } result.add(keyParameterDetail.toCacheInvocationParameter(values[parameterPosition])); } diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/JCacheKeyGeneratorTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/JCacheKeyGeneratorTests.java index 232a6b007624..39983d680a2f 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/JCacheKeyGeneratorTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/interceptor/JCacheKeyGeneratorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,6 @@ package org.springframework.cache.jcache.interceptor; import java.lang.reflect.Method; -import java.util.Arrays; import java.util.concurrent.atomic.AtomicLong; import javax.cache.annotation.CacheDefaults; @@ -150,9 +149,9 @@ private void expect(Object... params) { @Override public Object generate(Object target, Method method, Object... params) { - assertThat(Arrays.equals(expectedParams, params)).as("Unexpected parameters: expected: " - + Arrays.toString(this.expectedParams) + " but got: " + Arrays.toString(params)).isTrue(); + assertThat(params).as("Unexpected parameters").isEqualTo(expectedParams); return new SimpleKey(params); } } + } diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java index 8f97d45f70dd..8bf8fc85d3b4 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java @@ -288,8 +288,8 @@ public void afterSingletonsInstantiated() { } } catch (NoSuchBeanDefinitionException ex) { - throw new NoSuchBeanDefinitionException(CacheManager.class, "no CacheResolver specified - " - + "register a CacheManager bean or remove the @EnableCaching annotation from your configuration."); + throw new NoSuchBeanDefinitionException(CacheManager.class, "no CacheResolver specified - " + + "register a CacheManager bean or remove the @EnableCaching annotation from your configuration."); } } this.initialized = true; diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/NameMatchCacheOperationSource.java b/spring-context/src/main/java/org/springframework/cache/interceptor/NameMatchCacheOperationSource.java index 67644f5e92a2..af4fab0e8aa6 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/NameMatchCacheOperationSource.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/NameMatchCacheOperationSource.java @@ -85,8 +85,8 @@ public Collection getCacheOperations(Method method, @Nullable Cl // Look for most specific name match. String bestNameMatch = null; for (String mappedName : this.nameMap.keySet()) { - if (isMatch(methodName, mappedName) - && (bestNameMatch == null || bestNameMatch.length() <= mappedName.length())) { + if (isMatch(methodName, mappedName) && + (bestNameMatch == null || bestNameMatch.length() <= mappedName.length())) { ops = this.nameMap.get(mappedName); bestNameMatch = mappedName; } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java index ba3f926fd74c..92d831655c5f 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassParser.java @@ -105,8 +105,8 @@ class ConfigurationClassParser { (className.startsWith("java.lang.annotation.") || className.startsWith("org.springframework.stereotype.")); private static final Predicate REGISTER_BEAN_CONDITION_FILTER = condition -> - (condition instanceof ConfigurationCondition configurationCondition - && ConfigurationPhase.REGISTER_BEAN.equals(configurationCondition.getConfigurationPhase())); + (condition instanceof ConfigurationCondition configurationCondition && + ConfigurationPhase.REGISTER_BEAN.equals(configurationCondition.getConfigurationPhase())); private static final Comparator DEFERRED_IMPORT_COMPARATOR = (o1, o2) -> AnnotationAwareOrderComparator.INSTANCE.compare(o1.getImportSelector(), o2.getImportSelector()); diff --git a/spring-context/src/main/java/org/springframework/context/aot/ApplicationContextInitializationCodeGenerator.java b/spring-context/src/main/java/org/springframework/context/aot/ApplicationContextInitializationCodeGenerator.java index 5305508b9da9..693b4773cd88 100644 --- a/spring-context/src/main/java/org/springframework/context/aot/ApplicationContextInitializationCodeGenerator.java +++ b/spring-context/src/main/java/org/springframework/context/aot/ApplicationContextInitializationCodeGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 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. @@ -150,12 +150,12 @@ public CodeBlock apply(TypeName typeName) { @Nullable private CodeBlock apply(ClassName className) { String name = className.canonicalName(); - if (name.equals(DefaultListableBeanFactory.class.getName()) - || name.equals(ConfigurableListableBeanFactory.class.getName())) { + if (name.equals(DefaultListableBeanFactory.class.getName()) || + name.equals(ConfigurableListableBeanFactory.class.getName())) { return CodeBlock.of(BEAN_FACTORY_VARIABLE); } - else if (name.equals(ConfigurableEnvironment.class.getName()) - || name.equals(Environment.class.getName())) { + else if (name.equals(ConfigurableEnvironment.class.getName()) || + name.equals(Environment.class.getName())) { return CodeBlock.of("$L.getEnvironment()", APPLICATION_CONTEXT_VARIABLE); } else if (name.equals(ResourceLoader.class.getName())) { diff --git a/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java b/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java index 8b03a9f25d65..decb058d8e48 100644 --- a/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java +++ b/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -201,8 +201,8 @@ private static int retrieveMaxExpressionLength() { try { int maxLength = Integer.parseInt(value.trim()); - Assert.isTrue(maxLength > 0, () -> "Value [" + maxLength + "] for system property [" - + MAX_SPEL_EXPRESSION_LENGTH_PROPERTY_NAME + "] must be positive"); + Assert.isTrue(maxLength > 0, () -> "Value [" + maxLength + "] for system property [" + + MAX_SPEL_EXPRESSION_LENGTH_PROPERTY_NAME + "] must be positive"); return maxLength; } catch (NumberFormatException ex) { diff --git a/spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java b/spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java index 5d6784191ab7..e877d3b0bc6d 100644 --- a/spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java +++ b/spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java @@ -493,8 +493,8 @@ private void postProcessRootBeanDefinition(List postProcessors, BeanDefinitionValueResolver valueResolver, @Nullable Object value) { - if (value instanceof BeanDefinitionHolder bdh - && bdh.getBeanDefinition() instanceof AbstractBeanDefinition innerBd) { + if (value instanceof BeanDefinitionHolder bdh && + bdh.getBeanDefinition() instanceof AbstractBeanDefinition innerBd) { Class innerBeanType = resolveBeanType(innerBd); resolveInnerBeanDefinition(valueResolver, innerBd, (innerBeanName, innerBeanDefinition) diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/DurationFormatterUtils.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/DurationFormatterUtils.java index b1f5f3e58bd4..98f2152c6ca9 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/standard/DurationFormatterUtils.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/DurationFormatterUtils.java @@ -143,8 +143,8 @@ public static DurationFormat.Style detect(String value) { private static final Pattern ISO_8601_PATTERN = Pattern.compile("^[+-]?[pP].*$"); private static final Pattern SIMPLE_PATTERN = Pattern.compile("^([+-]?\\d+)([a-zA-Z]{0,2})$"); - private static final Pattern COMPOSITE_PATTERN = Pattern.compile("^([+-]?)\\(?\\s?(\\d+d)?\\s?(\\d+h)?\\s?(\\d+m)?" - + "\\s?(\\d+s)?\\s?(\\d+ms)?\\s?(\\d+us)?\\s?(\\d+ns)?\\)?$"); + private static final Pattern COMPOSITE_PATTERN = Pattern.compile("^([+-]?)\\(?\\s?(\\d+d)?\\s?(\\d+h)?\\s?(\\d+m)?" + + "\\s?(\\d+s)?\\s?(\\d+ms)?\\s?(\\d+us)?\\s?(\\d+ns)?\\)?$"); private static Duration parseIso8601(String value) { try { diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/DefaultScheduledTaskObservationConvention.java b/spring-context/src/main/java/org/springframework/scheduling/support/DefaultScheduledTaskObservationConvention.java index 9b3c891070f8..511531069b7f 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/DefaultScheduledTaskObservationConvention.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/DefaultScheduledTaskObservationConvention.java @@ -48,8 +48,8 @@ public String getName() { @Override public String getContextualName(ScheduledTaskObservationContext context) { - return "task " + StringUtils.uncapitalize(context.getTargetClass().getSimpleName()) - + "." + context.getMethod().getName(); + return "task " + StringUtils.uncapitalize(context.getTargetClass().getSimpleName()) + + "." + context.getMethod().getName(); } @Override diff --git a/spring-context/src/test/java/org/springframework/aop/aspectj/AspectAndAdvicePrecedenceTests.java b/spring-context/src/test/java/org/springframework/aop/aspectj/AspectAndAdvicePrecedenceTests.java index c7f56212bc4d..16c6659dac1f 100644 --- a/spring-context/src/test/java/org/springframework/aop/aspectj/AspectAndAdvicePrecedenceTests.java +++ b/spring-context/src/test/java/org/springframework/aop/aspectj/AspectAndAdvicePrecedenceTests.java @@ -106,8 +106,8 @@ private static class PrecedenceVerifyingCollaborator implements PrecedenceTestAs private void checkAdvice(String whatJustHappened) { //System.out.println("[" + adviceInvocationNumber + "] " + whatJustHappened + " ==> " + EXPECTED[adviceInvocationNumber]); if (adviceInvocationNumber > (EXPECTED.length - 1)) { - throw new AssertionError("Too many advice invocations, expecting " + EXPECTED.length - + " but had " + adviceInvocationNumber); + throw new AssertionError("Too many advice invocations, expecting " + EXPECTED.length + + " but had " + adviceInvocationNumber); } String expecting = EXPECTED[adviceInvocationNumber++]; if (!whatJustHappened.equals(expecting)) { diff --git a/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptFactoryTests.java b/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptFactoryTests.java index 812f4c442338..18f58f6ba119 100644 --- a/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptFactoryTests.java +++ b/spring-context/src/test/java/org/springframework/scripting/groovy/GroovyScriptFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -277,9 +277,9 @@ void testNonStaticPrototypeScript() { @Test void testScriptCompilationException() { - assertThatExceptionOfType(NestedRuntimeException.class).isThrownBy(() -> - new ClassPathXmlApplicationContext("org/springframework/scripting/groovy/groovyBrokenContext.xml")) - .matches(ex -> ex.contains(ScriptCompilationException.class)); + assertThatExceptionOfType(NestedRuntimeException.class) + .isThrownBy(() -> new ClassPathXmlApplicationContext("org/springframework/scripting/groovy/groovyBrokenContext.xml")) + .matches(ex -> ex.contains(ScriptCompilationException.class)); } @Test @@ -288,11 +288,10 @@ void testScriptedClassThatDoesNotHaveANoArgCtor() throws Exception { String badScript = "class Foo { public Foo(String foo) {}}"; given(script.getScriptAsString()).willReturn(badScript); given(script.suggestedClassName()).willReturn("someName"); - GroovyScriptFactory factory = new GroovyScriptFactory(ScriptFactoryPostProcessor.INLINE_SCRIPT_PREFIX - + badScript); - assertThatExceptionOfType(ScriptCompilationException.class).isThrownBy(() -> - factory.getScriptedObject(script)) - .matches(ex -> ex.contains(NoSuchMethodException.class)); + GroovyScriptFactory factory = new GroovyScriptFactory(ScriptFactoryPostProcessor.INLINE_SCRIPT_PREFIX + badScript); + assertThatExceptionOfType(ScriptCompilationException.class) + .isThrownBy(() -> factory.getScriptedObject(script)) + .matches(ex -> ex.contains(NoSuchMethodException.class)); } @Test @@ -327,27 +326,24 @@ void testWithTwoClassesDefinedInTheOneGroovyFile_WrongClassFirst() { @Test void testCtorWithNullScriptSourceLocator() { - assertThatIllegalArgumentException().isThrownBy(() -> - new GroovyScriptFactory(null)); + assertThatIllegalArgumentException().isThrownBy(() -> new GroovyScriptFactory(null)); } @Test void testCtorWithEmptyScriptSourceLocator() { - assertThatIllegalArgumentException().isThrownBy(() -> - new GroovyScriptFactory("")); + assertThatIllegalArgumentException().isThrownBy(() -> new GroovyScriptFactory("")); } @Test void testCtorWithWhitespacedScriptSourceLocator() { - assertThatIllegalArgumentException().isThrownBy(() -> - new GroovyScriptFactory("\n ")); + assertThatIllegalArgumentException().isThrownBy(() -> new GroovyScriptFactory("\n ")); } @Test void testWithInlineScriptWithLeadingWhitespace() { - assertThatExceptionOfType(BeanCreationException.class).as("'inline:' prefix was preceded by whitespace").isThrownBy(() -> - new ClassPathXmlApplicationContext("lwspBadGroovyContext.xml", getClass())) - .matches(ex -> ex.contains(FileNotFoundException.class)); + assertThatExceptionOfType(BeanCreationException.class).as("'inline:' prefix was preceded by whitespace") + .isThrownBy(() -> new ClassPathXmlApplicationContext("lwspBadGroovyContext.xml", getClass())) + .matches(ex -> ex.contains(FileNotFoundException.class)); } @Test @@ -364,8 +360,8 @@ void testGetScriptedObjectDoesNotChokeOnNullInterfacesBeingPassedIn() throws Exc @Test void testGetScriptedObjectDoesChokeOnNullScriptSourceBeingPassedIn() { GroovyScriptFactory factory = new GroovyScriptFactory("a script source locator (doesn't matter here)"); - assertThatNullPointerException().as("NullPointerException as per contract ('null' ScriptSource supplied)").isThrownBy(() -> - factory.getScriptedObject(null)); + assertThatNullPointerException().as("NullPointerException as per contract ('null' ScriptSource supplied)") + .isThrownBy(() -> factory.getScriptedObject(null)); } @Test diff --git a/spring-core-test/spring-core-test.gradle b/spring-core-test/spring-core-test.gradle index 55f2a8b8f4fb..a398ed30c3bf 100644 --- a/spring-core-test/spring-core-test.gradle +++ b/spring-core-test/spring-core-test.gradle @@ -2,11 +2,10 @@ description = "Spring Core Test" dependencies { api(project(":spring-core")) - api("org.assertj:assertj-core") - api("org.junit.jupiter:junit-jupiter-api") - compileOnly("org.junit.jupiter:junit-jupiter") - compileOnly("org.junit.platform:junit-platform-engine") - compileOnly("org.junit.platform:junit-platform-launcher") + optional("org.assertj:assertj-core") + optional("org.junit.jupiter:junit-jupiter-api") + compileOnly("org.junit.jupiter:junit-jupiter-params") // Used in CompileWithForkedClassLoaderExtension Javadoc + compileOnly("org.junit.platform:junit-platform-launcher") // Used in CompileWithForkedClassLoaderExtension implementation("com.thoughtworks.qdox:qdox") } diff --git a/spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedBridgeMethods.java b/spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedBridgeMethods.java index 35610a92220f..ad3a5166a51b 100644 --- a/spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedBridgeMethods.java +++ b/spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedBridgeMethods.java @@ -338,8 +338,8 @@ public static Object methodinvoke(Method method, Object object, Object... argume Object result = null; boolean accessibilityChanged = false; try { - if (!Modifier.isPublic(method.getModifiers()) - || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) { + if (!Modifier.isPublic(method.getModifiers()) || + !Modifier.isPublic(method.getDeclaringClass().getModifiers())) { method.setAccessible(true); accessibilityChanged = true; } diff --git a/spring-core-test/src/main/java/org/springframework/aot/agent/InvocationsRecorderClassVisitor.java b/spring-core-test/src/main/java/org/springframework/aot/agent/InvocationsRecorderClassVisitor.java index 4e7daa8f4119..6571a2ab61fd 100644 --- a/spring-core-test/src/main/java/org/springframework/aot/agent/InvocationsRecorderClassVisitor.java +++ b/spring-core-test/src/main/java/org/springframework/aot/agent/InvocationsRecorderClassVisitor.java @@ -78,8 +78,8 @@ class InvocationsRecorderMethodVisitor extends MethodVisitor implements Opcodes static { for (InstrumentedMethod method : InstrumentedMethod.values()) { MethodReference methodReference = method.methodReference(); - instrumentedMethods.add(methodReference.getClassName().replace('.', '/') - + "#" + methodReference.getMethodName()); + instrumentedMethods.add(methodReference.getClassName().replace('.', '/') + + "#" + methodReference.getMethodName()); } } diff --git a/spring-core-test/src/main/java/org/springframework/aot/test/agent/RuntimeHintsInvocationsAssert.java b/spring-core-test/src/main/java/org/springframework/aot/test/agent/RuntimeHintsInvocationsAssert.java index febdd622183f..27dd18ad44c3 100644 --- a/spring-core-test/src/main/java/org/springframework/aot/test/agent/RuntimeHintsInvocationsAssert.java +++ b/spring-core-test/src/main/java/org/springframework/aot/test/agent/RuntimeHintsInvocationsAssert.java @@ -108,8 +108,8 @@ private ErrorMessageFactory errorMessageForInvocation(RecordedInvocation invocat private String formatStackTrace(Stream stackTraceElements) { return stackTraceElements - .map(f -> f.getClassName() + "#" + f.getMethodName() - + ", Line " + f.getLineNumber()).collect(Collectors.joining(System.lineSeparator())); + .map(f -> f.getClassName() + "#" + f.getMethodName() + ", Line " + + f.getLineNumber()).collect(Collectors.joining(System.lineSeparator())); } /** diff --git a/spring-core-test/src/main/java/org/springframework/core/test/io/support/MockSpringFactoriesLoader.java b/spring-core-test/src/main/java/org/springframework/core/test/io/support/MockSpringFactoriesLoader.java index 70a6067a6a0d..47ee612b786b 100644 --- a/spring-core-test/src/main/java/org/springframework/core/test/io/support/MockSpringFactoriesLoader.java +++ b/spring-core-test/src/main/java/org/springframework/core/test/io/support/MockSpringFactoriesLoader.java @@ -122,8 +122,8 @@ public void addInstance(Class factoryType, T... factoryInstances) { public void addInstance(String factoryType, T... factoryInstance) { List implementations = this.factories.computeIfAbsent(factoryType, key -> new ArrayList<>()); for (T factoryImplementation : factoryInstance) { - String reference = "!" + factoryType + ":" + factoryImplementation.getClass().getName() - + this.sequence.getAndIncrement(); + String reference = "!" + factoryType + ":" + factoryImplementation.getClass().getName() + + this.sequence.getAndIncrement(); implementations.add(reference); this.implementations.put(reference, factoryImplementation); } diff --git a/spring-core-test/src/main/java/org/springframework/core/test/tools/TestCompiler.java b/spring-core-test/src/main/java/org/springframework/core/test/tools/TestCompiler.java index bb77051b9e7f..8a261f7bd6fd 100644 --- a/spring-core-test/src/main/java/org/springframework/core/test/tools/TestCompiler.java +++ b/spring-core-test/src/main/java/org/springframework/core/test/tools/TestCompiler.java @@ -299,8 +299,8 @@ public void compile(Consumer compiled) throws CompilationException { } private DynamicClassLoader compile() { - ClassLoader classLoaderToUse = (this.classLoader != null ? this.classLoader - : Thread.currentThread().getContextClassLoader()); + ClassLoader classLoaderToUse = (this.classLoader != null ? this.classLoader : + Thread.currentThread().getContextClassLoader()); List compilationUnits = this.sourceFiles.stream().map( DynamicJavaFileObject::new).toList(); StandardJavaFileManager standardFileManager = this.compiler.getStandardFileManager( diff --git a/spring-core/src/main/java/org/springframework/aot/generate/DefaultMethodReference.java b/spring-core/src/main/java/org/springframework/aot/generate/DefaultMethodReference.java index 3018c6407cfc..1079f7539618 100644 --- a/spring-core/src/main/java/org/springframework/aot/generate/DefaultMethodReference.java +++ b/spring-core/src/main/java/org/springframework/aot/generate/DefaultMethodReference.java @@ -102,8 +102,8 @@ protected void addArguments(CodeBlock.Builder code, ArgumentCodeGenerator argume TypeName argumentType = argumentTypes[i]; CodeBlock argumentCode = argumentCodeGenerator.generateCode(argumentType); if (argumentCode == null) { - throw new IllegalArgumentException("Could not generate code for " + this - + ": parameter " + i + " of type " + argumentType + " is not supported"); + throw new IllegalArgumentException("Could not generate code for " + this + + ": parameter " + i + " of type " + argumentType + " is not supported"); } arguments.add(argumentCode); } diff --git a/spring-core/src/main/java/org/springframework/aot/generate/GeneratedFiles.java b/spring-core/src/main/java/org/springframework/aot/generate/GeneratedFiles.java index 98979191a81a..c0c6db2a7361 100644 --- a/spring-core/src/main/java/org/springframework/aot/generate/GeneratedFiles.java +++ b/spring-core/src/main/java/org/springframework/aot/generate/GeneratedFiles.java @@ -192,9 +192,9 @@ private static String getClassNamePath(String className) { private static void validatePackage(String packageName, String className) { if (!StringUtils.hasLength(packageName)) { - throw new IllegalArgumentException("Could not add '" + className + "', " - + "processing classes in the default package is not supported. " - + "Did you forget to add a package statement?"); + throw new IllegalArgumentException("Could not add '" + className + "', " + + "processing classes in the default package is not supported. " + + "Did you forget to add a package statement?"); } } diff --git a/spring-core/src/main/java/org/springframework/aot/generate/ValueCodeGeneratorDelegates.java b/spring-core/src/main/java/org/springframework/aot/generate/ValueCodeGeneratorDelegates.java index 86904a0c30d3..2200c576dabb 100644 --- a/spring-core/src/main/java/org/springframework/aot/generate/ValueCodeGeneratorDelegates.java +++ b/spring-core/src/main/java/org/springframework/aot/generate/ValueCodeGeneratorDelegates.java @@ -240,8 +240,8 @@ private String escape(char ch) { if (escaped != null) { return escaped; } - return (!Character.isISOControl(ch)) ? Character.toString(ch) - : String.format("\\u%04x", (int) ch); + return (!Character.isISOControl(ch)) ? Character.toString(ch) : + String.format("\\u%04x", (int) ch); } } diff --git a/spring-core/src/main/java/org/springframework/aot/hint/BindingReflectionHintsRegistrar.java b/spring-core/src/main/java/org/springframework/aot/hint/BindingReflectionHintsRegistrar.java index 280e02a290fd..c3030f5b20f4 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/BindingReflectionHintsRegistrar.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/BindingReflectionHintsRegistrar.java @@ -108,8 +108,8 @@ private void registerReflectionHints(ReflectionHints hints, Set seen, Type registerPropertyHints(hints, seen, method, 0); } else if ((methodName.startsWith("get") && method.getParameterCount() == 0 && method.getReturnType() != void.class) || - (methodName.startsWith("is") && method.getParameterCount() == 0 - && ClassUtils.resolvePrimitiveIfNecessary(method.getReturnType()) == Boolean.class)) { + (methodName.startsWith("is") && method.getParameterCount() == 0 && + ClassUtils.resolvePrimitiveIfNecessary(method.getReturnType()) == Boolean.class)) { registerPropertyHints(hints, seen, method, -1); } } diff --git a/spring-core/src/main/java/org/springframework/asm/ClassReader.java b/spring-core/src/main/java/org/springframework/asm/ClassReader.java index dca87bcc3207..8ae1e208bb51 100644 --- a/spring-core/src/main/java/org/springframework/asm/ClassReader.java +++ b/spring-core/src/main/java/org/springframework/asm/ClassReader.java @@ -195,7 +195,7 @@ public ClassReader( this.b = classFileBuffer; // Check the class' major_version. This field is after the magic and minor_version fields, which // use 4 and 2 bytes respectively. - if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V24) { + if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V25) { throw new IllegalArgumentException( "Unsupported class file major version " + readShort(classFileOffset + 6)); } diff --git a/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java b/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java index 6016a766a7ff..7fc511d4e625 100644 --- a/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java +++ b/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java @@ -594,7 +594,7 @@ public void visitTableSwitchInsn( * Visits a LOOKUPSWITCH instruction. * * @param dflt beginning of the default handler block. - * @param keys the values of the keys. + * @param keys the values of the keys. Keys must be sorted in increasing order. * @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the * handler block for the {@code keys[i]} key. */ diff --git a/spring-core/src/main/java/org/springframework/asm/Opcodes.java b/spring-core/src/main/java/org/springframework/asm/Opcodes.java index 69192d1aa758..c912933444d6 100644 --- a/spring-core/src/main/java/org/springframework/asm/Opcodes.java +++ b/spring-core/src/main/java/org/springframework/asm/Opcodes.java @@ -289,6 +289,7 @@ public interface Opcodes { int V22 = 0 << 16 | 66; int V23 = 0 << 16 | 67; int V24 = 0 << 16 | 68; + int V25 = 0 << 16 | 69; /** * Version flag indicating that the class is using 'preview' features. diff --git a/spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotation.java b/spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotation.java index 4e3d98bdc7f4..7abce77af907 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotation.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/TypeMappedAnnotation.java @@ -375,8 +375,8 @@ protected T getAttributeValue(String attributeName, Class type) { private Object getRequiredValue(int attributeIndex, String attributeName) { Object value = getValue(attributeIndex, Object.class); if (value == null) { - throw new NoSuchElementException("No element at attribute index " - + attributeIndex + " for name " + attributeName); + throw new NoSuchElementException("No element at attribute index " + + attributeIndex + " for name " + attributeName); } return value; } diff --git a/spring-core/src/main/java/org/springframework/core/codec/ResourceRegionEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/ResourceRegionEncoder.java index 3330ac6e1555..5b55fe2a0ceb 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/ResourceRegionEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/ResourceRegionEncoder.java @@ -71,8 +71,8 @@ public ResourceRegionEncoder(int bufferSize) { @Override public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) { - return super.canEncode(elementType, mimeType) - && ResourceRegion.class.isAssignableFrom(elementType.toClass()); + return super.canEncode(elementType, mimeType) && + ResourceRegion.class.isAssignableFrom(elementType.toClass()); } @Override diff --git a/spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java b/spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java index 84eff6587bea..2dcfb4f322dc 100644 --- a/spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java @@ -56,6 +56,7 @@ public boolean exists() { // Try a URL connection content-length header URLConnection con = url.openConnection(); customizeConnection(con); + HttpURLConnection httpCon = (con instanceof HttpURLConnection huc ? huc : null); if (httpCon != null) { httpCon.setRequestMethod("HEAD"); @@ -81,12 +82,16 @@ else if (code == HttpURLConnection.HTTP_NOT_FOUND) { } } } - // Check content-length entry but not for JarURLConnection where - // this would open the jar file but effectively never close it -> - // for jar entries, always fall back to stream existence instead. - if (!(con instanceof JarURLConnection) && con.getContentLengthLong() > 0) { + + if (con instanceof JarURLConnection jarCon) { + // For JarURLConnection, do not check content-length but rather the + // existence of the entry (or the jar root in case of no entryName). + return (jarCon.getEntryName() == null || jarCon.getJarEntry() != null); + } + else if (con.getContentLengthLong() > 0) { return true; } + if (httpCon != null) { // No HTTP OK status, and no content-length header: give up httpCon.disconnect(); @@ -346,8 +351,8 @@ public long lastModified() throws IOException { */ protected void customizeConnection(URLConnection con) throws IOException { ResourceUtils.useCachesIfNecessary(con); - if (con instanceof HttpURLConnection httpConn) { - customizeConnection(httpConn); + if (con instanceof HttpURLConnection httpCon) { + customizeConnection(httpCon); } } diff --git a/spring-core/src/main/java/org/springframework/core/io/UrlResource.java b/spring-core/src/main/java/org/springframework/core/io/UrlResource.java index 4c5c3e0226d3..0f1005978765 100644 --- a/spring-core/src/main/java/org/springframework/core/io/UrlResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/UrlResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -234,8 +234,8 @@ public InputStream getInputStream() throws IOException { } catch (IOException ex) { // Close the HTTP connection (if applicable). - if (con instanceof HttpURLConnection httpConn) { - httpConn.disconnect(); + if (con instanceof HttpURLConnection httpCon) { + httpCon.disconnect(); } throw ex; } diff --git a/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java b/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java index 2bfefa1c404c..59c583356a6c 100644 --- a/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java +++ b/spring-core/src/main/java/org/springframework/core/io/support/SpringFactoriesLoader.java @@ -472,8 +472,8 @@ static T instantiate(Constructor constructor, Object[] args) throws Excep private static void makeAccessible(Constructor constructor, KFunction kotlinConstructor) { - if ((!Modifier.isPublic(constructor.getModifiers()) - || !Modifier.isPublic(constructor.getDeclaringClass().getModifiers()))) { + if ((!Modifier.isPublic(constructor.getModifiers()) || + !Modifier.isPublic(constructor.getDeclaringClass().getModifiers()))) { KCallablesJvm.setAccessible(kotlinConstructor, true); } } diff --git a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java index 9afaf2532381..ec3a8b3bcedd 100644 --- a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java @@ -275,8 +275,8 @@ else if (!fullMatch && "**".equals(pattDirs[pattIdxStart])) { if (!matchStrings(pattDir, pathDirs[pathIdxEnd], uriTemplateVariables)) { return false; } - if (pattIdxEnd == (pattDirs.length - 1) - && pattern.endsWith(this.pathSeparator) != path.endsWith(this.pathSeparator)) { + if (pattIdxEnd == (pattDirs.length - 1) && + pattern.endsWith(this.pathSeparator) != path.endsWith(this.pathSeparator)) { return false; } pattIdxEnd--; diff --git a/spring-core/src/main/java/org/springframework/util/ConcurrentLruCache.java b/spring-core/src/main/java/org/springframework/util/ConcurrentLruCache.java index 926bb671ce89..5a3e91eda066 100644 --- a/spring-core/src/main/java/org/springframework/util/ConcurrentLruCache.java +++ b/spring-core/src/main/java/org/springframework/util/ConcurrentLruCache.java @@ -557,9 +557,7 @@ void add(Node e) { } private boolean contains(Node e) { - return (e.getPrevious() != null) - || (e.getNext() != null) - || (e == this.first); + return (e.getPrevious() != null) || (e.getNext() != null) || (e == this.first); } private void linkLast(final Node e) { diff --git a/spring-core/src/main/java/org/springframework/util/StringUtils.java b/spring-core/src/main/java/org/springframework/util/StringUtils.java index deed77ff405e..f785767a7846 100644 --- a/spring-core/src/main/java/org/springframework/util/StringUtils.java +++ b/spring-core/src/main/java/org/springframework/util/StringUtils.java @@ -808,7 +808,7 @@ public static boolean pathEquals(String path1, String path2) { *
  • Alphanumeric characters {@code "a"} through {@code "z"}, {@code "A"} through {@code "Z"}, * and {@code "0"} through {@code "9"} stay the same.
  • *
  • Special characters {@code "-"}, {@code "_"}, {@code "."}, and {@code "*"} stay the same.
  • - *
  • A sequence "{@code %xy}" is interpreted as a hexadecimal representation of the character.
  • + *
  • A sequence "{@code %xy}" is interpreted as a hexadecimal representation of the character.
  • *
  • For all other characters (including those already decoded), the output is undefined.
  • * * @param source the encoded String diff --git a/spring-core/src/test/java/org/springframework/aot/generate/GeneratedFilesTests.java b/spring-core/src/test/java/org/springframework/aot/generate/GeneratedFilesTests.java index 5c45bca59941..ac16bec27175 100644 --- a/spring-core/src/test/java/org/springframework/aot/generate/GeneratedFilesTests.java +++ b/spring-core/src/test/java/org/springframework/aot/generate/GeneratedFilesTests.java @@ -71,8 +71,8 @@ void addSourceFileWithJavaFileInTheDefaultPackageThrowsException() { TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld").build(); JavaFile javaFile = JavaFile.builder("", helloWorld).build(); assertThatIllegalArgumentException().isThrownBy(() -> this.generatedFiles.addSourceFile(javaFile)) - .withMessage("Could not add 'HelloWorld', processing classes in the " - + "default package is not supported. Did you forget to add a package statement?"); + .withMessage("Could not add 'HelloWorld', processing classes in the " + + "default package is not supported. Did you forget to add a package statement?"); } @Test @@ -92,8 +92,8 @@ void addSourceFileWithCharSequenceWhenClassNameIsEmptyThrowsException() { void addSourceFileWithCharSequenceWhenClassNameIsInTheDefaultPackageThrowsException() { assertThatIllegalArgumentException() .isThrownBy(() -> this.generatedFiles.addSourceFile("HelloWorld", "{}")) - .withMessage("Could not add 'HelloWorld', processing classes in the " - + "default package is not supported. Did you forget to add a package statement?"); + .withMessage("Could not add 'HelloWorld', processing classes in the " + + "default package is not supported. Did you forget to add a package statement?"); } @Test diff --git a/spring-core/src/test/java/org/springframework/aot/generate/ValueCodeGeneratorTests.java b/spring-core/src/test/java/org/springframework/aot/generate/ValueCodeGeneratorTests.java index dc755467ec1c..f2b3f3e473ba 100644 --- a/spring-core/src/test/java/org/springframework/aot/generate/ValueCodeGeneratorTests.java +++ b/spring-core/src/test/java/org/springframework/aot/generate/ValueCodeGeneratorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,20 +64,17 @@ */ class ValueCodeGeneratorTests { - @Nested class ConfigurationTests { @Test void createWithListOfDelegatesInvokeThemInOrder() { - Delegate first = mock(Delegate.class); - Delegate second = mock(Delegate.class); - Delegate third = mock(Delegate.class); - ValueCodeGenerator codeGenerator = ValueCodeGenerator - .with(List.of(first, second, third)); + Delegate first = mock(); + Delegate second = mock(); + Delegate third = mock(); + ValueCodeGenerator codeGenerator = ValueCodeGenerator.with(List.of(first, second, third)); Object value = ""; - given(third.generateCode(codeGenerator, value)) - .willReturn(CodeBlock.of("test")); + given(third.generateCode(codeGenerator, value)).willReturn(CodeBlock.of("test")); CodeBlock code = codeGenerator.generateCode(value); assertThat(code).hasToString("test"); InOrder ordered = inOrder(first, second, third); @@ -88,13 +85,11 @@ void createWithListOfDelegatesInvokeThemInOrder() { @Test void generateCodeWithMatchingDelegateStops() { - Delegate first = mock(Delegate.class); - Delegate second = mock(Delegate.class); - ValueCodeGenerator codeGenerator = ValueCodeGenerator - .with(List.of(first, second)); + Delegate first = mock(); + Delegate second = mock(); + ValueCodeGenerator codeGenerator = ValueCodeGenerator.with(List.of(first, second)); Object value = ""; - given(first.generateCode(codeGenerator, value)) - .willReturn(CodeBlock.of("test")); + given(first.generateCode(codeGenerator, value)).willReturn(CodeBlock.of("test")); CodeBlock code = codeGenerator.generateCode(value); assertThat(code).hasToString("test"); verify(first).generateCode(codeGenerator, value); @@ -198,7 +193,6 @@ void generateWhenString() { assertThat(generateCode("test")).hasToString("\"test\""); } - @Test void generateWhenStringWithCarriageReturn() { assertThat(generateCode("test\n")).isEqualTo(CodeBlock.of("$S", "test\n")); @@ -285,9 +279,9 @@ void generateWhenNestedGenericResolvableType() { ResolvableType resolvableType = ResolvableType.forClassWithGenerics(Map.class, ResolvableType.forClass(Integer.class), stringList); assertThat(resolve(generateCode(resolvableType))) - .hasImport(ResolvableType.class, List.class, Map.class).hasValueCode( - "ResolvableType.forClassWithGenerics(Map.class, ResolvableType.forClass(Integer.class), " - + "ResolvableType.forClassWithGenerics(List.class, String.class))"); + .hasImport(ResolvableType.class, List.class, Map.class).hasValueCode(""" + ResolvableType.forClassWithGenerics(Map.class, ResolvableType.forClass(Integer.class), \ + ResolvableType.forClassWithGenerics(List.class, String.class))"""); } @Test diff --git a/spring-core/src/test/java/org/springframework/aot/hint/ReflectionHintsTests.java b/spring-core/src/test/java/org/springframework/aot/hint/ReflectionHintsTests.java index 5e4c3cc14f8a..cb4eb24dcab7 100644 --- a/spring-core/src/test/java/org/springframework/aot/hint/ReflectionHintsTests.java +++ b/spring-core/src/test/java/org/springframework/aot/hint/ReflectionHintsTests.java @@ -216,10 +216,10 @@ void registerOnInterfaces() { typeHint -> typeHint.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS)); assertThat(this.reflectionHints.typeHints()).hasSize(2) .noneMatch(typeHint -> typeHint.getType().getCanonicalName().equals(Serializable.class.getCanonicalName())) - .anyMatch(typeHint -> typeHint.getType().getCanonicalName().equals(SecondInterface.class.getCanonicalName()) - && typeHint.getMemberCategories().contains(MemberCategory.INTROSPECT_PUBLIC_METHODS)) - .anyMatch(typeHint -> typeHint.getType().getCanonicalName().equals(FirstInterface.class.getCanonicalName()) - && typeHint.getMemberCategories().contains(MemberCategory.INTROSPECT_PUBLIC_METHODS)); + .anyMatch(typeHint -> typeHint.getType().getCanonicalName().equals(SecondInterface.class.getCanonicalName()) && + typeHint.getMemberCategories().contains(MemberCategory.INTROSPECT_PUBLIC_METHODS)) + .anyMatch(typeHint -> typeHint.getType().getCanonicalName().equals(FirstInterface.class.getCanonicalName()) && + typeHint.getMemberCategories().contains(MemberCategory.INTROSPECT_PUBLIC_METHODS)); } private void assertTestTypeMethodHints(Consumer methodHint) { diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java index 16c5425116ea..988c4e341416 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 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. @@ -54,27 +54,24 @@ void forAnnotationTypeWhenNoMetaAnnotationsReturnsMappings() { AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(SimpleAnnotation.class); assertThat(mappings.size()).isEqualTo(1); assertThat(mappings.get(0).getAnnotationType()).isEqualTo(SimpleAnnotation.class); - assertThat(getAll(mappings)).flatExtracting( - AnnotationTypeMapping::getAnnotationType).containsExactly(SimpleAnnotation.class); + assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType) + .containsExactly(SimpleAnnotation.class); } @Test void forAnnotationTypeWhenMetaAnnotationsReturnsMappings() { AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(MetaAnnotated.class); assertThat(mappings.size()).isEqualTo(6); - assertThat(getAll(mappings)).flatExtracting( - AnnotationTypeMapping::getAnnotationType).containsExactly( - MetaAnnotated.class, A.class, B.class, AA.class, AB.class, - ABC.class); + assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType) + .containsExactly(MetaAnnotated.class, A.class, B.class, AA.class, AB.class, ABC.class); } @Test void forAnnotationTypeWhenHasRepeatingMetaAnnotationReturnsMapping() { AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(WithRepeatedMetaAnnotations.class); assertThat(mappings.size()).isEqualTo(3); - assertThat(getAll(mappings)).flatExtracting( - AnnotationTypeMapping::getAnnotationType).containsExactly( - WithRepeatedMetaAnnotations.class, Repeating.class, Repeating.class); + assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType) + .containsExactly(WithRepeatedMetaAnnotations.class, Repeating.class, Repeating.class); } @Test @@ -89,56 +86,52 @@ void forAnnotationTypeWhenRepeatableMetaAnnotationIsFiltered() { void forAnnotationTypeWhenSelfAnnotatedReturnsMapping() { AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(SelfAnnotated.class); assertThat(mappings.size()).isEqualTo(1); - assertThat(getAll(mappings)).flatExtracting( - AnnotationTypeMapping::getAnnotationType).containsExactly(SelfAnnotated.class); + assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType) + .containsExactly(SelfAnnotated.class); } @Test void forAnnotationTypeWhenFormsLoopReturnsMapping() { AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(LoopA.class); assertThat(mappings.size()).isEqualTo(2); - assertThat(getAll(mappings)).flatExtracting( - AnnotationTypeMapping::getAnnotationType).containsExactly(LoopA.class, LoopB.class); + assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType) + .containsExactly(LoopA.class, LoopB.class); } @Test void forAnnotationTypeWhenHasAliasForWithBothValueAndAttributeThrowsException() { - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - AnnotationTypeMappings.forAnnotationType(AliasForWithBothValueAndAttribute.class)) - .withMessage("In @AliasFor declared on attribute 'test' in annotation [" - + AliasForWithBothValueAndAttribute.class.getName() - + "], attribute 'attribute' and its alias 'value' are present with values of 'foo' and 'bar', but only one is permitted."); + assertThatExceptionOfType(AnnotationConfigurationException.class) + .isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForWithBothValueAndAttribute.class)) + .withMessage("In @AliasFor declared on attribute 'test' in annotation [%s], attribute 'attribute' " + + "and its alias 'value' are present with values of 'foo' and 'bar', but only one is permitted.", + AliasForWithBothValueAndAttribute.class.getName()); } @Test void forAnnotationTypeWhenAliasForToSelfNonExistingAttribute() { - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - AnnotationTypeMappings.forAnnotationType(AliasForToSelfNonExistingAttribute.class)) - .withMessage("@AliasFor declaration on attribute 'test' in annotation [" - + AliasForToSelfNonExistingAttribute.class.getName() - + "] declares an alias for 'missing' which is not present."); + assertThatExceptionOfType(AnnotationConfigurationException.class) + .isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForToSelfNonExistingAttribute.class)) + .withMessage("@AliasFor declaration on attribute 'test' in annotation [%s] " + + "declares an alias for 'missing' which is not present.", + AliasForToSelfNonExistingAttribute.class.getName()); } @Test void forAnnotationTypeWhenAliasForToOtherNonExistingAttribute() { - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - AnnotationTypeMappings.forAnnotationType(AliasForToOtherNonExistingAttribute.class)) - .withMessage("Attribute 'test' in annotation [" - + AliasForToOtherNonExistingAttribute.class.getName() - + "] is declared as an @AliasFor nonexistent " - + "attribute 'missing' in annotation [" - + AliasForToOtherNonExistingAttributeTarget.class.getName() - + "]."); + assertThatExceptionOfType(AnnotationConfigurationException.class) + .isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForToOtherNonExistingAttribute.class)) + .withMessage("Attribute 'test' in annotation [%s] is declared as an @AliasFor nonexistent " + + "attribute 'missing' in annotation [%s].", AliasForToOtherNonExistingAttribute.class.getName(), + AliasForToOtherNonExistingAttributeTarget.class.getName()); } @Test void forAnnotationTypeWhenAliasForToSelf() { - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - AnnotationTypeMappings.forAnnotationType(AliasForToSelf.class)) - .withMessage("@AliasFor declaration on attribute 'test' in annotation [" - + AliasForToSelf.class.getName() - + "] points to itself. Specify 'annotation' to point to " - + "a same-named attribute on a meta-annotation."); + assertThatExceptionOfType(AnnotationConfigurationException.class) + .isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForToSelf.class)) + .withMessage("@AliasFor declaration on attribute 'test' in annotation [%s] points to itself. " + + "Specify 'annotation' to point to a same-named attribute on a meta-annotation.", + AliasForToSelf.class.getName()); } @Test @@ -152,13 +145,12 @@ void forAnnotationTypeWhenAliasForWithArrayCompatibleReturnTypes() { @Test void forAnnotationTypeWhenAliasForWithIncompatibleReturnTypes() { - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - AnnotationTypeMappings.forAnnotationType(AliasForWithIncompatibleReturnTypes.class)) - .withMessage("Misconfigured aliases: attribute 'test' in annotation [" - + AliasForWithIncompatibleReturnTypes.class.getName() - + "] and attribute 'test' in annotation [" - + AliasForWithIncompatibleReturnTypesTarget.class.getName() - + "] must declare the same return type."); + assertThatExceptionOfType(AnnotationConfigurationException.class) + .isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForWithIncompatibleReturnTypes.class)) + .withMessage("Misconfigured aliases: attribute 'test' in annotation [%s] and attribute 'test' " + + "in annotation [%s] must declare the same return type.", + AliasForWithIncompatibleReturnTypes.class.getName(), + AliasForWithIncompatibleReturnTypesTarget.class.getName()); } @Test @@ -166,9 +158,8 @@ void forAnnotationTypeWhenAliasForToSelfAnnotatedToOtherAttribute() { String annotationType = AliasForToSelfAnnotatedToOtherAttribute.class.getName(); assertThatExceptionOfType(AnnotationConfigurationException.class) .isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForToSelfAnnotatedToOtherAttribute.class)) - .withMessage("Attribute 'b' in annotation [" + annotationType - + "] must be declared as an @AliasFor attribute 'a' in annotation [" + annotationType - + "], not attribute 'c' in annotation [" + annotationType + "]."); + .withMessage("Attribute 'b' in annotation [%1$s] must be declared as an @AliasFor attribute 'a' in " + + "annotation [%1$s], not attribute 'c' in annotation [%1$s].", annotationType); } @Test @@ -182,53 +173,45 @@ private void assertMixedImplicitAndExplicitAliases(Class a String metaAnnotationName = AliasPair.class.getName(); assertThatExceptionOfType(AnnotationConfigurationException.class) .isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(annotationType)) - .withMessage("Attribute 'b' in annotation [" + annotationName - + "] must be declared as an @AliasFor attribute 'a' in annotation [" + annotationName - + "], not attribute '" + overriddenAttribute + "' in annotation [" + metaAnnotationName + "]."); + .withMessage("Attribute 'b' in annotation [" + annotationName + + "] must be declared as an @AliasFor attribute 'a' in annotation [" + annotationName + + "], not attribute '" + overriddenAttribute + "' in annotation [" + metaAnnotationName + "]."); } @Test void forAnnotationTypeWhenAliasForNonMetaAnnotated() { - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - AnnotationTypeMappings.forAnnotationType(AliasForNonMetaAnnotated.class)) - .withMessage("@AliasFor declaration on attribute 'test' in annotation [" - + AliasForNonMetaAnnotated.class.getName() - + "] declares an alias for attribute 'test' in annotation [" - + AliasForNonMetaAnnotatedTarget.class.getName() - + "] which is not meta-present."); + assertThatExceptionOfType(AnnotationConfigurationException.class) + .isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForNonMetaAnnotated.class)) + .withMessage("@AliasFor declaration on attribute 'test' in annotation [" + AliasForNonMetaAnnotated.class.getName() + + "] declares an alias for attribute 'test' in annotation [" + AliasForNonMetaAnnotatedTarget.class.getName() + + "] which is not meta-present."); } @Test void forAnnotationTypeWhenAliasForSelfWithDifferentDefaults() { - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - AnnotationTypeMappings.forAnnotationType(AliasForSelfWithDifferentDefaults.class)) - .withMessage("Misconfigured aliases: attribute 'a' in annotation [" - + AliasForSelfWithDifferentDefaults.class.getName() - + "] and attribute 'b' in annotation [" - + AliasForSelfWithDifferentDefaults.class.getName() - + "] must declare the same default value."); + assertThatExceptionOfType(AnnotationConfigurationException.class) + .isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForSelfWithDifferentDefaults.class)) + .withMessage("Misconfigured aliases: attribute 'a' in annotation [" + AliasForSelfWithDifferentDefaults.class.getName() + + "] and attribute 'b' in annotation [" + AliasForSelfWithDifferentDefaults.class.getName() + + "] must declare the same default value."); } @Test void forAnnotationTypeWhenAliasForSelfWithMissingDefault() { - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - AnnotationTypeMappings.forAnnotationType(AliasForSelfWithMissingDefault.class)) - .withMessage("Misconfigured aliases: attribute 'a' in annotation [" - + AliasForSelfWithMissingDefault.class.getName() - + "] and attribute 'b' in annotation [" - + AliasForSelfWithMissingDefault.class.getName() - + "] must declare default values."); + assertThatExceptionOfType(AnnotationConfigurationException.class) + .isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasForSelfWithMissingDefault.class)) + .withMessage("Misconfigured aliases: attribute 'a' in annotation [" + AliasForSelfWithMissingDefault.class.getName() + + "] and attribute 'b' in annotation [" + AliasForSelfWithMissingDefault.class.getName() + + "] must declare default values."); } @Test void forAnnotationTypeWhenAliasWithExplicitMirrorAndDifferentDefaults() { - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - AnnotationTypeMappings.forAnnotationType(AliasWithExplicitMirrorAndDifferentDefaults.class)) - .withMessage("Misconfigured aliases: attribute 'a' in annotation [" - + AliasWithExplicitMirrorAndDifferentDefaults.class.getName() - + "] and attribute 'c' in annotation [" - + AliasWithExplicitMirrorAndDifferentDefaults.class.getName() - + "] must declare the same default value."); + assertThatExceptionOfType(AnnotationConfigurationException.class) + .isThrownBy(() -> AnnotationTypeMappings.forAnnotationType(AliasWithExplicitMirrorAndDifferentDefaults.class)) + .withMessage("Misconfigured aliases: attribute 'a' in annotation [" + AliasWithExplicitMirrorAndDifferentDefaults.class.getName() + + "] and attribute 'c' in annotation [" + AliasWithExplicitMirrorAndDifferentDefaults.class.getName() + + "] must declare the same default value."); } @Test @@ -375,18 +358,16 @@ void resolveMirrorsWhenOnlyHasDefaultValuesUsesFirst() { @Test void resolveMirrorsWhenHasDifferentValuesThrowsException() { AnnotationTypeMapping mapping = AnnotationTypeMappings.forAnnotationType(AliasPair.class).get(0); - assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> - resolveMirrorSets(mapping, WithDifferentValueAliasPair.class, AliasPair.class)) - .withMessage("Different @AliasFor mirror values for annotation [" - + AliasPair.class.getName() + "] declared on " - + WithDifferentValueAliasPair.class.getName() - + "; attribute 'a' and its alias 'b' are declared with values of [test1] and [test2]."); + assertThatExceptionOfType(AnnotationConfigurationException.class) + .isThrownBy(() -> resolveMirrorSets(mapping, WithDifferentValueAliasPair.class, AliasPair.class)) + .withMessage("Different @AliasFor mirror values for annotation [" + AliasPair.class.getName() + "] declared on " + + WithDifferentValueAliasPair.class.getName() + + "; attribute 'a' and its alias 'b' are declared with values of [test1] and [test2]."); } @Test void resolveMirrorsWhenHasWithMultipleRoutesToAliasReturnsMirrors() { - AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType( - MultipleRoutesToAliasA.class); + AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(MultipleRoutesToAliasA.class); AnnotationTypeMapping mappingsA = getMapping(mappings, MultipleRoutesToAliasA.class); assertThat(mappingsA.getMirrorSets().size()).isZero(); AnnotationTypeMapping mappingsB = getMapping(mappings, MultipleRoutesToAliasB.class); @@ -397,8 +378,7 @@ void resolveMirrorsWhenHasWithMultipleRoutesToAliasReturnsMirrors() { @Test void getAliasMappingWhenHasWithMultipleRoutesToAliasReturnsMappedAttributes() { - AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType( - MultipleRoutesToAliasA.class); + AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(MultipleRoutesToAliasA.class); AnnotationTypeMapping mappingsA = getMapping(mappings, MultipleRoutesToAliasA.class); assertThat(getAliasMapping(mappingsA, 0)).isNull(); AnnotationTypeMapping mappingsB = getMapping(mappings, MultipleRoutesToAliasB.class); diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java index 4185df3c4a13..829dabf3ffb7 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationUtilsTests.java @@ -925,8 +925,8 @@ void synthesizeAnnotationFromMapWithAttributeOfIncorrectType() { Map map = Collections.singletonMap(VALUE, 42L); assertThatIllegalStateException().isThrownBy(() -> synthesizeAnnotation(map, Component.class, null).value()) - .withMessageContaining("Attribute 'value' in annotation org.springframework.core.testfixture.stereotype.Component " - + "should be compatible with java.lang.String but a java.lang.Long value was returned"); + .withMessageContaining("Attribute 'value' in annotation org.springframework.core.testfixture.stereotype.Component " + + "should be compatible with java.lang.String but a java.lang.Long value was returned"); } @Test diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationClassLoaderTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationClassLoaderTests.java index d69cc41e7c10..9073adaa336c 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationClassLoaderTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationClassLoaderTests.java @@ -120,9 +120,7 @@ public TestClassLoader(ClassLoader parent) { @Override protected boolean isEligibleForOverriding(String className) { - return WITH_TEST_ANNOTATION.equals(className) - || TEST_ANNOTATION.equals(className) - || TEST_REFERENCE.equals(className); + return WITH_TEST_ANNOTATION.equals(className) || TEST_ANNOTATION.equals(className) || TEST_REFERENCE.equals(className); } } diff --git a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsCollectionTests.java b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsCollectionTests.java index a0bbaa5b234a..6cc0fb64f811 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsCollectionTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsCollectionTests.java @@ -171,8 +171,7 @@ void getWithPredicateReturnsOnlyMatching() { void getWithSelectorReturnsSelected() { MergedAnnotations annotations = getMultiRoute1(); MergedAnnotationSelector deepest = (existing, - candidate) -> candidate.getDistance() > existing.getDistance() ? candidate - : existing; + candidate) -> candidate.getDistance() > existing.getDistance() ? candidate : existing; assertThat(annotations.get(MultiRouteTarget.class, null, deepest).getString( MergedAnnotation.VALUE)).isEqualTo("111"); } diff --git a/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java b/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java index ee8b7352dad8..af1d12e0b4af 100644 --- a/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java @@ -51,8 +51,10 @@ import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; import org.springframework.util.ClassUtils; import org.springframework.util.FileSystemUtils; +import org.springframework.util.ResourceUtils; import org.springframework.util.StreamUtils; import org.springframework.util.StringUtils; @@ -133,6 +135,7 @@ void encodedHashtagInPath() throws IOException { assertExactFilenames("classpath*:scanned/*.txt", "resource#test1.txt", "resource#test2.txt"); } + @Nested class WithHashtagsInTheirFilenames { @@ -299,6 +302,7 @@ void rootPatternRetrievalInJarFiles() throws IOException { } } + @Nested class ClassPathManifestEntries { @@ -313,8 +317,8 @@ void javaDashJarFindsClassPathManifestEntries() throws Exception { writeApplicationJar(this.temp.resolve("app.jar")); String java = ProcessHandle.current().info().command().get(); Process process = new ProcessBuilder(java, "-jar", "app.jar") - .directory(this.temp.toFile()) - .start(); + .directory(this.temp.toFile()) + .start(); assertThat(process.waitFor()).isZero(); String result = StreamUtils.copyToString(process.getInputStream(), StandardCharsets.UTF_8); assertThat(result.replace("\\", "/")).contains("!!!!").contains("/lib/asset.jar!/assets/file.txt"); @@ -328,6 +332,8 @@ private void writeAssetJar(Path path) throws Exception { StreamUtils.copy("test", StandardCharsets.UTF_8, jar); jar.closeEntry(); } + assertThat(new FileSystemResource(path).exists()).isTrue(); + assertThat(new UrlResource(ResourceUtils.JAR_URL_PREFIX + ResourceUtils.FILE_URL_PREFIX + path + ResourceUtils.JAR_URL_SEPARATOR).exists()).isTrue(); } private void writeApplicationJar(Path path) throws Exception { @@ -338,8 +344,7 @@ private void writeApplicationJar(Path path) throws Exception { mainAttributes.put(Name.MANIFEST_VERSION, "1.0"); try (JarOutputStream jar = new JarOutputStream(new FileOutputStream(path.toFile()), manifest)) { String appClassResource = ClassUtils.convertClassNameToResourcePath( - ClassPathManifestEntriesTestApplication.class.getName()) - + ClassUtils.CLASS_FILE_SUFFIX; + ClassPathManifestEntriesTestApplication.class.getName()) + ClassUtils.CLASS_FILE_SUFFIX; String folder = ""; for (String name : appClassResource.split("/")) { if (!name.endsWith(ClassUtils.CLASS_FILE_SUFFIX)) { @@ -356,18 +361,19 @@ private void writeApplicationJar(Path path) throws Exception { } } } + assertThat(new FileSystemResource(path).exists()).isTrue(); + assertThat(new UrlResource(ResourceUtils.JAR_URL_PREFIX + ResourceUtils.FILE_URL_PREFIX + path + ResourceUtils.JAR_URL_SEPARATOR).exists()).isTrue(); } private String buildSpringClassPath() throws Exception { - return copyClasses(PathMatchingResourcePatternResolver.class, "spring-core") - + copyClasses(LogFactory.class, "commons-logging"); + return copyClasses(PathMatchingResourcePatternResolver.class, "spring-core") + + copyClasses(LogFactory.class, "commons-logging"); } - private String copyClasses(Class sourceClass, String destinationName) - throws URISyntaxException, IOException { + private String copyClasses(Class sourceClass, String destinationName) throws URISyntaxException, IOException { Path destination = this.temp.resolve(destinationName); - String resourcePath = ClassUtils.convertClassNameToResourcePath(sourceClass.getName()) - + ClassUtils.CLASS_FILE_SUFFIX; + String resourcePath = ClassUtils.convertClassNameToResourcePath( + sourceClass.getName()) + ClassUtils.CLASS_FILE_SUFFIX; URL resource = getClass().getClassLoader().getResource(resourcePath); URL url = new URL(resource.toString().replace(resourcePath, "")); URLConnection connection = url.openConnection(); @@ -393,7 +399,6 @@ private String copyClasses(Class sourceClass, String destinationName) } return destinationName + "/ "; } - } diff --git a/spring-core/src/test/java/org/springframework/core/io/support/SpringFactoriesLoaderTests.java b/spring-core/src/test/java/org/springframework/core/io/support/SpringFactoriesLoaderTests.java index 541da8c9f20a..06a452932138 100644 --- a/spring-core/src/test/java/org/springframework/core/io/support/SpringFactoriesLoaderTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/support/SpringFactoriesLoaderTests.java @@ -99,8 +99,8 @@ void loadWhenPackagePrivateFactory() { void loadWhenIncompatibleTypeThrowsException() { assertThatIllegalArgumentException() .isThrownBy(() -> SpringFactoriesLoader.forDefaultResourceLocation().load(String.class)) - .withMessageContaining("Unable to instantiate factory class " - + "[org.springframework.core.io.support.MyDummyFactory1] for factory type [java.lang.String]"); + .withMessageContaining("Unable to instantiate factory class " + + "[org.springframework.core.io.support.MyDummyFactory1] for factory type [java.lang.String]"); } @Test @@ -127,8 +127,8 @@ void loadWhenMultipleConstructorsThrowsException() { assertThatIllegalArgumentException() .isThrownBy(() -> SpringFactoriesLoader.forDefaultResourceLocation(LimitedClassLoader.multipleArgumentFactories) .load(DummyFactory.class, resolver)) - .withMessageContaining("Unable to instantiate factory class " - + "[org.springframework.core.io.support.MultipleConstructorArgsDummyFactory] for factory type [org.springframework.core.io.support.DummyFactory]") + .withMessageContaining("Unable to instantiate factory class " + + "[org.springframework.core.io.support.MultipleConstructorArgsDummyFactory] for factory type [org.springframework.core.io.support.DummyFactory]") .havingRootCause().withMessageContaining("Class [org.springframework.core.io.support.MultipleConstructorArgsDummyFactory] has no suitable constructor"); } diff --git a/spring-core/src/test/java/org/springframework/core/log/CompositeLogTests.java b/spring-core/src/test/java/org/springframework/core/log/CompositeLogTests.java index 993c910a6c48..2747daf6d775 100644 --- a/spring-core/src/test/java/org/springframework/core/log/CompositeLogTests.java +++ b/spring-core/src/test/java/org/springframework/core/log/CompositeLogTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,11 +21,10 @@ import org.apache.commons.logging.Log; import org.junit.jupiter.api.Test; -import static org.mockito.BDDMockito.when; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; - +import static org.mockito.Mockito.when; /** * Tests for {@link CompositeLog}. diff --git a/spring-core/src/test/java/org/springframework/util/xml/AbstractStaxXMLReaderTests.java b/spring-core/src/test/java/org/springframework/util/xml/AbstractStaxXMLReaderTests.java index 7f51d8af088a..58626d8c31b8 100644 --- a/spring-core/src/test/java/org/springframework/util/xml/AbstractStaxXMLReaderTests.java +++ b/spring-core/src/test/java/org/springframework/util/xml/AbstractStaxXMLReaderTests.java @@ -218,8 +218,8 @@ private static class CharArrayToStringAdapter implements InvocationArgumentsAdap @Override public Object[] adaptArguments(Object[] arguments) { - if (arguments.length == 3 && arguments[0] instanceof char[] - && arguments[1] instanceof Integer && arguments[2] instanceof Integer) { + if (arguments.length == 3 && arguments[0] instanceof char[] && + arguments[1] instanceof Integer && arguments[2] instanceof Integer) { return new Object[] {new String((char[]) arguments[0], (Integer) arguments[1], (Integer) arguments[2])}; } return arguments; @@ -271,10 +271,10 @@ public boolean equals(@Nullable Object obj) { for (int i = 0; i < other.getLength(); i++) { boolean found = false; for (int j = 0; j < attributes.getLength(); j++) { - if (other.getURI(i).equals(attributes.getURI(j)) - && other.getQName(i).equals(attributes.getQName(j)) - && other.getType(i).equals(attributes.getType(j)) - && other.getValue(i).equals(attributes.getValue(j))) { + if (other.getURI(i).equals(attributes.getURI(j)) && + other.getQName(i).equals(attributes.getQName(j)) && + other.getType(i).equals(attributes.getType(j)) && + other.getValue(i).equals(attributes.getValue(j))) { found = true; break; } diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/IndexingTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/IndexingTests.java index 52b9e4c0203e..028ec3c41cca 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/IndexingTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/IndexingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,8 +57,8 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.doThrow; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/SpelDocumentationTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/SpelDocumentationTests.java index 57cc2168ea15..70ec1c875908 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/SpelDocumentationTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/SpelDocumentationTests.java @@ -737,8 +737,8 @@ void ternary() { parser.parseExpression("Name").setValue(societyContext, "IEEE"); societyContext.setVariable("queryName", "Nikola Tesla"); - String expression = "isMember(#queryName) ? #queryName + ' is a member of the ' " - + "+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'"; + String expression = "isMember(#queryName) ? #queryName + ' is a member of the ' " + + "+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'"; String queryResultString = parser.parseExpression(expression).getValue(societyContext, String.class); assertThat(queryResultString).isEqualTo("Nikola Tesla is a member of the IEEE Society"); diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/StatementCreatorUtilsTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/StatementCreatorUtilsTests.java index b46065d3c63f..01f4143372f1 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/StatementCreatorUtilsTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/StatementCreatorUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,8 +38,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Named.named; -import static org.mockito.BDDMockito.doThrow; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceUtilsTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceUtilsTests.java index 36bd1fc250fc..286095e32be0 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceUtilsTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +25,8 @@ import org.springframework.jdbc.CannotGetJdbcConnectionException; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.BDDMockito.when; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Tests for {@link DataSourceUtils}. diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/ShardingKeyDataSourceAdapterTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/ShardingKeyDataSourceAdapterTests.java index 8f4261547b66..ba617dcedc3b 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/ShardingKeyDataSourceAdapterTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/ShardingKeyDataSourceAdapterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,10 +27,10 @@ import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.RETURNS_DEEP_STUBS; import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Tests for {@link ShardingKeyDataSourceAdapter}. diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulatorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulatorTests.java index 17d125dbb04a..1a2dce315494 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulatorTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.BDDMockito.mock; +import static org.mockito.Mockito.mock; /** * Tests for {@link ResourceDatabasePopulator}. diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/SqlArrayValueTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/SqlArrayValueTests.java index 10fbebeb0751..141713efcba1 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/SqlArrayValueTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/SqlArrayValueTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,8 +24,8 @@ import org.junit.jupiter.api.Test; import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.verify; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; /** * Tests for {@link SqlArrayValue}. diff --git a/spring-jms/src/test/java/org/springframework/jms/config/JmsNamespaceHandlerTests.java b/spring-jms/src/test/java/org/springframework/jms/config/JmsNamespaceHandlerTests.java index 6fde3769d90c..ed146ca0f908 100644 --- a/spring-jms/src/test/java/org/springframework/jms/config/JmsNamespaceHandlerTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/config/JmsNamespaceHandlerTests.java @@ -293,10 +293,10 @@ void testComponentRegistration() { assertThat(context.containsComponentDefinition("listener1")).as("Parser should have registered a component named 'listener1'").isTrue(); assertThat(context.containsComponentDefinition("listener2")).as("Parser should have registered a component named 'listener2'").isTrue(); assertThat(context.containsComponentDefinition("listener3")).as("Parser should have registered a component named 'listener3'").isTrue(); - assertThat(context.containsComponentDefinition(DefaultMessageListenerContainer.class.getName() + "#0")).as("Parser should have registered a component named '" - + DefaultMessageListenerContainer.class.getName() + "#0'").isTrue(); - assertThat(context.containsComponentDefinition(JmsMessageEndpointManager.class.getName() + "#0")).as("Parser should have registered a component named '" - + JmsMessageEndpointManager.class.getName() + "#0'").isTrue(); + assertThat(context.containsComponentDefinition(DefaultMessageListenerContainer.class.getName() + "#0")).as("Parser should have registered a component named '" + + DefaultMessageListenerContainer.class.getName() + "#0'").isTrue(); + assertThat(context.containsComponentDefinition(JmsMessageEndpointManager.class.getName() + "#0")).as("Parser should have registered a component named '" + + JmsMessageEndpointManager.class.getName() + "#0'").isTrue(); assertThat(context.containsComponentDefinition("testJmsFactory")).as("Parser should have registered a component named 'testJmsFactory").isTrue(); assertThat(context.containsComponentDefinition("testJcaFactory")).as("Parser should have registered a component named 'testJcaFactory").isTrue(); assertThat(context.containsComponentDefinition("onlyJmsFactory")).as("Parser should have registered a component named 'testJcaFactory").isTrue(); diff --git a/spring-jms/src/test/java/org/springframework/jms/core/JmsTemplateTests.java b/spring-jms/src/test/java/org/springframework/jms/core/JmsTemplateTests.java index 290c4c9c58a8..4440b71d48db 100644 --- a/spring-jms/src/test/java/org/springframework/jms/core/JmsTemplateTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/core/JmsTemplateTests.java @@ -530,8 +530,7 @@ private void doTestReceive( if (!useTransactedTemplate() && !useTransactedSession()) { given(this.session.getAcknowledgeMode()).willReturn( - clientAcknowledge ? Session.CLIENT_ACKNOWLEDGE - : Session.AUTO_ACKNOWLEDGE); + clientAcknowledge ? Session.CLIENT_ACKNOWLEDGE : Session.AUTO_ACKNOWLEDGE); } TextMessage textMessage = mock(); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/MessagingException.java b/spring-messaging/src/main/java/org/springframework/messaging/MessagingException.java index bd2f8d26af1d..ef0d8e8e7f81 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/MessagingException.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/MessagingException.java @@ -71,8 +71,8 @@ public Message getFailedMessage() { @Override public String toString() { - return super.toString() + (this.failedMessage == null ? "" - : (", failedMessage=" + this.failedMessage)); + return super.toString() + (this.failedMessage == null ? "" : + (", failedMessage=" + this.failedMessage)); } } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java index d43e991870fb..84d237ecef69 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java @@ -202,8 +202,8 @@ protected void logWarningIfNecessary(Type type, @Nullable Throwable cause) { } // Do not log warning for serializer not found (note: different message wording on Jackson 2.9) - boolean debugLevel = (cause instanceof JsonMappingException && cause.getMessage() != null - && cause.getMessage().startsWith("Cannot find")); + boolean debugLevel = (cause instanceof JsonMappingException && cause.getMessage() != null && + cause.getMessage().startsWith("Cannot find")); if (debugLevel ? logger.isDebugEnabled() : logger.isWarnEnabled()) { String msg = "Failed to evaluate Jackson " + (type instanceof JavaType ? "de" : "") + diff --git a/spring-messaging/src/main/java/org/springframework/messaging/core/GenericMessagingTemplate.java b/spring-messaging/src/main/java/org/springframework/messaging/core/GenericMessagingTemplate.java index 95952f4b0b9f..1a3a3271b4c1 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/core/GenericMessagingTemplate.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/core/GenericMessagingTemplate.java @@ -176,8 +176,8 @@ protected final void doSend(MessageChannel channel, Message message, long tim accessor.removeHeader(this.receiveTimeoutHeader); accessor.setImmutable(); } - else if (message.getHeaders().containsKey(this.sendTimeoutHeader) - || message.getHeaders().containsKey(this.receiveTimeoutHeader)) { + else if (message.getHeaders().containsKey(this.sendTimeoutHeader) || + message.getHeaders().containsKey(this.receiveTimeoutHeader)) { messageToSend = MessageBuilder.fromMessage(message) .setHeader(this.sendTimeoutHeader, null) .setHeader(this.receiveTimeoutHeader, null) diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/HandlerMethod.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/HandlerMethod.java index 7dfd09c6f4dc..9209c2f43504 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/HandlerMethod.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/HandlerMethod.java @@ -196,8 +196,8 @@ public String getShortLogMessage() { @Override public boolean equals(@Nullable Object other) { - return (this == other || (super.equals(other) && other instanceof HandlerMethod otherMethod - && this.bean.equals(otherMethod.bean))); + return (this == other || (super.equals(other) && other instanceof HandlerMethod otherMethod && + this.bean.equals(otherMethod.bean))); } @Override diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompEncoder.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompEncoder.java index 8d9da03c4252..fb6bb7d3ec4b 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompEncoder.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompEncoder.java @@ -126,8 +126,8 @@ private void writeHeaders( return; } - boolean shouldEscape = (command != StompCommand.CONNECT && command != StompCommand.STOMP - && command != StompCommand.CONNECTED); + boolean shouldEscape = (command != StompCommand.CONNECT && command != StompCommand.STOMP && + command != StompCommand.CONNECTED); for (Entry> entry : nativeHeaders.entrySet()) { if (command.requiresContentLength() && "content-length".equals(entry.getKey())) { diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/AbstractStompBrokerRelayIntegrationTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/AbstractStompBrokerRelayIntegrationTests.java index ed1fe62fa92d..0314c08d8c0d 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/AbstractStompBrokerRelayIntegrationTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/AbstractStompBrokerRelayIntegrationTests.java @@ -538,8 +538,8 @@ protected boolean matchInternal(StompHeaderAccessor headers, Object payload) { @Override public String toString() { - return super.toString() + ", subscriptionId=\"" + this.subscriptionId - + "\", destination=\"" + this.destination + "\", payload=\"" + getPayloadAsText() + "\""; + return super.toString() + ", subscriptionId=\"" + this.subscriptionId + + "\", destination=\"" + this.destination + "\", payload=\"" + getPayloadAsText() + "\""; } protected String getPayloadAsText() { diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/DelegatingConnectionFactoryTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/DelegatingConnectionFactoryTests.java index 8f120de9e433..a0cb5232461b 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/DelegatingConnectionFactoryTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/DelegatingConnectionFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,8 +22,8 @@ import reactor.core.publisher.Mono; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Tests for {@link DelegatingConnectionFactory}. diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/R2dbcTransactionManagerTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/R2dbcTransactionManagerTests.java index 040c4359cbeb..b383b633b01b 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/R2dbcTransactionManagerTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/R2dbcTransactionManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,7 @@ import io.r2dbc.spi.ConnectionFactory; import io.r2dbc.spi.IsolationLevel; import io.r2dbc.spi.R2dbcBadGrammarException; +import io.r2dbc.spi.R2dbcTransientResourceException; import io.r2dbc.spi.Statement; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -32,6 +33,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.r2dbc.BadSqlGrammarException; import org.springframework.transaction.CannotCreateTransactionException; import org.springframework.transaction.IllegalTransactionStateException; @@ -46,13 +48,13 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.BDDMockito.inOrder; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.never; -import static org.mockito.BDDMockito.reset; -import static org.mockito.BDDMockito.verify; -import static org.mockito.BDDMockito.verifyNoMoreInteractions; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; /** * Tests for {@link R2dbcTransactionManager}. @@ -315,6 +317,31 @@ void testConnectionReleasedWhenRollbackFails() { verify(connectionMock).close(); } + @Test + void testCommitAndRollbackFails() { + when(connectionMock.isAutoCommit()).thenReturn(false); + when(connectionMock.commitTransaction()).thenReturn(Mono.defer(() -> + Mono.error(new R2dbcBadGrammarException("Commit should fail")))); + when(connectionMock.rollbackTransaction()).thenReturn(Mono.defer(() -> + Mono.error(new R2dbcTransientResourceException("Rollback should also fail")))); + + TransactionalOperator operator = TransactionalOperator.create(tm); + + ConnectionFactoryUtils.getConnection(connectionFactoryMock) + .doOnNext(connection -> connection.createStatement("foo")).then() + .as(operator::transactional) + .as(StepVerifier::create) + .verifyError(TransientDataAccessResourceException.class); + + verify(connectionMock).isAutoCommit(); + verify(connectionMock).beginTransaction(any(io.r2dbc.spi.TransactionDefinition.class)); + verify(connectionMock).createStatement("foo"); + verify(connectionMock).commitTransaction(); + verify(connectionMock).rollbackTransaction(); + verify(connectionMock).close(); + verifyNoMoreInteractions(connectionMock); + } + @Test void testTransactionSetRollbackOnly() { when(connectionMock.isAutoCommit()).thenReturn(false); diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/SingleConnectionFactoryTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/SingleConnectionFactoryTests.java index a445abe3ce2a..773e01ce5330 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/SingleConnectionFactoryTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/SingleConnectionFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,10 +27,10 @@ import reactor.test.StepVerifier; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.never; -import static org.mockito.BDDMockito.verify; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** * Tests for {@link SingleConnectionFactory}. diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxyTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxyTests.java index fec9fbe626db..751b59db2a37 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxyTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/TransactionAwareConnectionFactoryProxyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,11 +31,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.times; -import static org.mockito.BDDMockito.verify; -import static org.mockito.BDDMockito.verifyNoInteractions; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; /** * Tests for {@link TransactionAwareConnectionFactoryProxy}. diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/CompositeDatabasePopulatorTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/CompositeDatabasePopulatorTests.java index 3bd7f268082f..d5ffd97179d0 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/CompositeDatabasePopulatorTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/CompositeDatabasePopulatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,10 +25,10 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.times; -import static org.mockito.BDDMockito.verify; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** * Tests for {@link CompositeDatabasePopulator}. diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/ConnectionFactoryInitializerTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/ConnectionFactoryInitializerTests.java index 5e79730624ad..90dded294894 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/ConnectionFactoryInitializerTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/ConnectionFactoryInitializerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,8 +24,8 @@ import reactor.core.publisher.Mono; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Tests for {@link ConnectionFactoryInitializer}. diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/ResourceDatabasePopulatorTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/ResourceDatabasePopulatorTests.java index eaf39d60c87c..bd8b7f03e337 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/ResourceDatabasePopulatorTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/init/ResourceDatabasePopulatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.BDDMockito.mock; +import static org.mockito.Mockito.mock; /** * Tests for {@link ResourceDatabasePopulator}. diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/BeanFactoryConnectionFactoryLookupTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/BeanFactoryConnectionFactoryLookupTests.java index 9674fd77d2e2..389ed6f81f2e 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/BeanFactoryConnectionFactoryLookupTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/lookup/BeanFactoryConnectionFactoryLookupTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,8 +28,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Tests for {@link BeanFactoryConnectionFactoryLookup}. diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/DefaultDatabaseClientTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/DefaultDatabaseClientTests.java index 93f9a65d97fb..b2f51a1bc438 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/DefaultDatabaseClientTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/DefaultDatabaseClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,14 +50,14 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.doReturn; -import static org.mockito.BDDMockito.inOrder; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.times; -import static org.mockito.BDDMockito.verify; -import static org.mockito.BDDMockito.verifyNoInteractions; -import static org.mockito.BDDMockito.verifyNoMoreInteractions; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; /** * Tests for {@link DefaultDatabaseClient}. diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/R2dbcBeanPropertyRowMapperTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/R2dbcBeanPropertyRowMapperTests.java index 192b9f655b1b..e718d0cdf1c4 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/R2dbcBeanPropertyRowMapperTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/R2dbcBeanPropertyRowMapperTests.java @@ -96,8 +96,8 @@ void rowTypeAndMappingTypeMisaligned() { assertThatExceptionOfType(TypeMismatchException.class) .isThrownBy(() -> mapper.apply(EXTENDED_PERSON_ROW)) - .withMessage("Failed to convert property value of type 'java.lang.String' to required type " - + "'java.lang.String' for property 'address'; simulating type mismatch for address"); + .withMessage("Failed to convert property value of type 'java.lang.String' to required type " + + "'java.lang.String' for property 'address'; simulating type mismatch for address"); } @ParameterizedTest diff --git a/spring-test/src/main/java/org/springframework/mock/web/server/MockServerWebExchange.java b/spring-test/src/main/java/org/springframework/mock/web/server/MockServerWebExchange.java index e2cf0fae8f54..bf5f0b37ba80 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/server/MockServerWebExchange.java +++ b/spring-test/src/main/java/org/springframework/mock/web/server/MockServerWebExchange.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2025 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,6 +18,7 @@ import reactor.core.publisher.Mono; +import org.springframework.context.ApplicationContext; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.lang.Nullable; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; @@ -39,9 +40,15 @@ */ public final class MockServerWebExchange extends DefaultServerWebExchange { - private MockServerWebExchange(MockServerHttpRequest request, WebSessionManager sessionManager) { - super(request, new MockServerHttpResponse(), sessionManager, - ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver()); + + private MockServerWebExchange( + MockServerHttpRequest request, @Nullable WebSessionManager sessionManager, + @Nullable ApplicationContext applicationContext) { + + super(request, new MockServerHttpResponse(), + sessionManager != null ? sessionManager : new DefaultWebSessionManager(), + ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver(), + applicationContext); } @@ -101,6 +108,9 @@ public static class Builder { @Nullable private WebSessionManager sessionManager; + @Nullable + private ApplicationContext applicationContext; + public Builder(MockServerHttpRequest request) { this.request = request; } @@ -127,12 +137,21 @@ public Builder sessionManager(WebSessionManager sessionManager) { return this; } + /** + * Provide the {@code ApplicationContext} to expose through the exchange. + * @param applicationContext the context to use + * @since 6.2.5 + */ + public Builder applicationContext(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + return this; + } + /** * Build the {@code MockServerWebExchange} instance. */ public MockServerWebExchange build() { - return new MockServerWebExchange(this.request, - this.sessionManager != null ? this.sessionManager : new DefaultWebSessionManager()); + return new MockServerWebExchange(this.request, this.sessionManager, this.applicationContext); } } diff --git a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/AbstractExpressionEvaluatingCondition.java b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/AbstractExpressionEvaluatingCondition.java index c93f477b5555..2e48fbc561f1 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/AbstractExpressionEvaluatingCondition.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/AbstractExpressionEvaluatingCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -118,8 +118,8 @@ protected ConditionEvaluationResult evaluateAnnotation(Cl if (logger.isInfoEnabled()) { logger.info(reason); } - result = (enabledOnTrue ? ConditionEvaluationResult.enabled(reason) - : ConditionEvaluationResult.disabled(reason)); + result = (enabledOnTrue ? ConditionEvaluationResult.enabled(reason) : + ConditionEvaluationResult.disabled(reason)); } else { String adjective = (enabledOnTrue ? "disabled" : "enabled"); diff --git a/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java index d768a8cfaf2e..c435c199b2b7 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java @@ -252,8 +252,8 @@ static List resolveContextConfigurationAttribute // annotated class. if (currentAnnotation.equals(previousAnnotation) && hasResources(currentAnnotation)) { if (logger.isDebugEnabled()) { - logger.debug(String.format("Ignoring duplicate %s declaration on [%s], " - + "since it is also declared on [%s].", currentAnnotation, + logger.debug(String.format("Ignoring duplicate %s declaration on [%s], " + + "since it is also declared on [%s].", currentAnnotation, previousDeclaringClass.getName(), descriptor.getRootDeclaringClass().getName())); } } diff --git a/spring-test/src/main/java/org/springframework/test/context/support/DelegatingSmartContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/support/DelegatingSmartContextLoader.java index 26a4cad9a31c..9773943a2eda 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/DelegatingSmartContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/DelegatingSmartContextLoader.java @@ -36,12 +36,14 @@ */ public class DelegatingSmartContextLoader extends AbstractDelegatingSmartContextLoader { - private static final String GROOVY_XML_CONTEXT_LOADER_CLASS_NAME = "org.springframework.test.context.support.GenericGroovyXmlContextLoader"; + private static final String GROOVY_XML_CONTEXT_LOADER_CLASS_NAME = + "org.springframework.test.context.support.GenericGroovyXmlContextLoader"; private static final boolean groovyPresent = ClassUtils.isPresent("groovy.lang.Closure", - DelegatingSmartContextLoader.class.getClassLoader()) - && ClassUtils.isPresent(GROOVY_XML_CONTEXT_LOADER_CLASS_NAME, - DelegatingSmartContextLoader.class.getClassLoader()); + DelegatingSmartContextLoader.class.getClassLoader()) && + ClassUtils.isPresent(GROOVY_XML_CONTEXT_LOADER_CLASS_NAME, + DelegatingSmartContextLoader.class.getClassLoader()); + private final SmartContextLoader xmlLoader; private final SmartContextLoader annotationConfigLoader; @@ -55,8 +57,8 @@ public DelegatingSmartContextLoader() { this.xmlLoader = (SmartContextLoader) BeanUtils.instantiateClass(loaderClass); } catch (Throwable ex) { - throw new IllegalStateException("Failed to enable support for Groovy scripts; " - + "could not load class: " + GROOVY_XML_CONTEXT_LOADER_CLASS_NAME, ex); + throw new IllegalStateException("Failed to enable support for Groovy scripts; " + + "could not load class: " + GROOVY_XML_CONTEXT_LOADER_CLASS_NAME, ex); } } else { diff --git a/spring-test/src/main/java/org/springframework/test/context/support/TestPropertySourceAttributes.java b/spring-test/src/main/java/org/springframework/test/context/support/TestPropertySourceAttributes.java index c3a43e594dc8..f9dfacac4a4c 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/TestPropertySourceAttributes.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/TestPropertySourceAttributes.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -92,9 +92,9 @@ class TestPropertySourceAttributes { */ void mergeWith(TestPropertySourceAttributes attributes) { Assert.state(attributes.declaringClass == this.declaringClass, - () -> "Detected @TestPropertySource declarations within an aggregate index " - + "with different sources: " + this.declaringClass.getName() + " and " - + attributes.declaringClass.getName()); + () -> "Detected @TestPropertySource declarations within an aggregate index " + + "with different sources: " + this.declaringClass.getName() + " and " + + attributes.declaringClass.getName()); logger.trace(LogMessage.format("Retrieved %s for declaring class [%s].", attributes, this.declaringClass.getName())); assertSameBooleanAttribute(this.inheritLocations, attributes.inheritLocations, diff --git a/spring-test/src/main/java/org/springframework/test/context/web/WebDelegatingSmartContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/web/WebDelegatingSmartContextLoader.java index 7298a632ff4d..9973298602c7 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/WebDelegatingSmartContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/WebDelegatingSmartContextLoader.java @@ -39,9 +39,9 @@ public class WebDelegatingSmartContextLoader extends AbstractDelegatingSmartCont private static final String GROOVY_XML_WEB_CONTEXT_LOADER_CLASS_NAME = "org.springframework.test.context.web.GenericGroovyXmlWebContextLoader"; private static final boolean groovyPresent = ClassUtils.isPresent("groovy.lang.Closure", - WebDelegatingSmartContextLoader.class.getClassLoader()) - && ClassUtils.isPresent(GROOVY_XML_WEB_CONTEXT_LOADER_CLASS_NAME, - WebDelegatingSmartContextLoader.class.getClassLoader()); + WebDelegatingSmartContextLoader.class.getClassLoader()) && + ClassUtils.isPresent(GROOVY_XML_WEB_CONTEXT_LOADER_CLASS_NAME, + WebDelegatingSmartContextLoader.class.getClassLoader()); private final SmartContextLoader xmlLoader; private final SmartContextLoader annotationConfigLoader; @@ -55,8 +55,8 @@ public WebDelegatingSmartContextLoader() { this.xmlLoader = (SmartContextLoader) BeanUtils.instantiateClass(loaderClass); } catch (Throwable ex) { - throw new IllegalStateException("Failed to enable support for Groovy scripts; " - + "could not load class: " + GROOVY_XML_WEB_CONTEXT_LOADER_CLASS_NAME, ex); + throw new IllegalStateException("Failed to enable support for Groovy scripts; " + + "could not load class: " + GROOVY_XML_WEB_CONTEXT_LOADER_CLASS_NAME, ex); } } else { diff --git a/spring-test/src/main/java/org/springframework/test/json/JsonAssert.java b/spring-test/src/main/java/org/springframework/test/json/JsonAssert.java index a8d2bf404aca..78e3fcd75af5 100644 --- a/spring-test/src/main/java/org/springframework/test/json/JsonAssert.java +++ b/spring-test/src/main/java/org/springframework/test/json/JsonAssert.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,8 +41,8 @@ public abstract class JsonAssert { * @see JSONCompareMode#LENIENT */ public static JsonComparator comparator(JsonCompareMode compareMode) { - JSONCompareMode jsonAssertCompareMode = (compareMode != JsonCompareMode.LENIENT - ? JSONCompareMode.STRICT : JSONCompareMode.LENIENT); + JSONCompareMode jsonAssertCompareMode = (compareMode != JsonCompareMode.LENIENT ? + JSONCompareMode.STRICT : JSONCompareMode.LENIENT); return comparator(jsonAssertCompareMode); } @@ -81,18 +81,14 @@ private static class JsonAssertJsonComparator implements JsonComparator { @Override public JsonComparison compare(@Nullable String expectedJson, @Nullable String actualJson) { if (actualJson == null) { - return (expectedJson != null) - ? JsonComparison.mismatch("Expected null JSON") - : JsonComparison.match(); + return (expectedJson != null) ? JsonComparison.mismatch("Expected null JSON") : JsonComparison.match(); } if (expectedJson == null) { return JsonComparison.mismatch("Expected non-null JSON"); } try { JSONCompareResult result = JSONCompare.compareJSON(expectedJson, actualJson, this.jsonAssertComparator); - return (!result.passed()) - ? JsonComparison.mismatch(result.getMessage()) - : JsonComparison.match(); + return (!result.passed()) ? JsonComparison.mismatch(result.getMessage()) : JsonComparison.match(); } catch (JSONException ex) { throw new IllegalStateException(ex); diff --git a/spring-test/src/test/java/org/springframework/test/annotation/ProfileValueUtilsTests.java b/spring-test/src/test/java/org/springframework/test/annotation/ProfileValueUtilsTests.java index cda7ef180522..c5c82c39729e 100644 --- a/spring-test/src/test/java/org/springframework/test/annotation/ProfileValueUtilsTests.java +++ b/spring-test/src/test/java/org/springframework/test/annotation/ProfileValueUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -47,35 +47,45 @@ static void setProfileValue() { } private void assertClassIsEnabled(Class testClass) { - assertThat(ProfileValueUtils.isTestEnabledInThisEnvironment(testClass)).as("Test class [" + testClass + "] should be enabled.").isTrue(); + assertThat(ProfileValueUtils.isTestEnabledInThisEnvironment(testClass)) + .as("Test class [" + testClass + "] should be enabled.") + .isTrue(); } private void assertClassIsDisabled(Class testClass) { - assertThat(ProfileValueUtils.isTestEnabledInThisEnvironment(testClass)).as("Test class [" + testClass + "] should be disabled.").isFalse(); + assertThat(ProfileValueUtils.isTestEnabledInThisEnvironment(testClass)) + .as("Test class [" + testClass + "] should be disabled.") + .isFalse(); } private void assertMethodIsEnabled(String methodName, Class testClass) throws Exception { Method testMethod = testClass.getMethod(methodName); - assertThat(ProfileValueUtils.isTestEnabledInThisEnvironment(testMethod, testClass)).as("Test method [" + testMethod + "] should be enabled.").isTrue(); + assertThat(ProfileValueUtils.isTestEnabledInThisEnvironment(testMethod, testClass)) + .as("Test method [" + testMethod + "] should be enabled.") + .isTrue(); } private void assertMethodIsDisabled(String methodName, Class testClass) throws Exception { Method testMethod = testClass.getMethod(methodName); - assertThat(ProfileValueUtils.isTestEnabledInThisEnvironment(testMethod, testClass)).as("Test method [" + testMethod + "] should be disabled.").isFalse(); + assertThat(ProfileValueUtils.isTestEnabledInThisEnvironment(testMethod, testClass)) + .as("Test method [" + testMethod + "] should be disabled.") + .isFalse(); } private void assertMethodIsEnabled(ProfileValueSource profileValueSource, String methodName, Class testClass) throws Exception { Method testMethod = testClass.getMethod(methodName); - assertThat(ProfileValueUtils.isTestEnabledInThisEnvironment(profileValueSource, testMethod, testClass)).as("Test method [" + testMethod + "] should be enabled for ProfileValueSource [" + profileValueSource - + "].").isTrue(); + assertThat(ProfileValueUtils.isTestEnabledInThisEnvironment(profileValueSource, testMethod, testClass)) + .as("Test method [" + testMethod + "] should be enabled for ProfileValueSource [" + profileValueSource + "].") + .isTrue(); } private void assertMethodIsDisabled(ProfileValueSource profileValueSource, String methodName, Class testClass) throws Exception { Method testMethod = testClass.getMethod(methodName); - assertThat(ProfileValueUtils.isTestEnabledInThisEnvironment(profileValueSource, testMethod, testClass)).as("Test method [" + testMethod + "] should be disabled for ProfileValueSource [" + profileValueSource - + "].").isFalse(); + assertThat(ProfileValueUtils.isTestEnabledInThisEnvironment(profileValueSource, testMethod, testClass)) + .as("Test method [" + testMethod + "] should be disabled for ProfileValueSource [" + profileValueSource + "].") + .isFalse(); } // ------------------------------------------------------------------- diff --git a/spring-test/src/test/java/org/springframework/test/context/aot/AotContextLoaderTests.java b/spring-test/src/test/java/org/springframework/test/context/aot/AotContextLoaderTests.java index e82ff54f1f86..4fa2de4a5b31 100644 --- a/spring-test/src/test/java/org/springframework/test/context/aot/AotContextLoaderTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/aot/AotContextLoaderTests.java @@ -25,9 +25,9 @@ import org.springframework.test.context.MergedContextConfiguration; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.never; -import static org.mockito.BDDMockito.spy; import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; /** * Unit tests for {@link AotContextLoader}. diff --git a/spring-test/src/test/java/org/springframework/test/context/aot/samples/bean/override/MockitoBeanJupiterTests.java b/spring-test/src/test/java/org/springframework/test/context/aot/samples/bean/override/MockitoBeanJupiterTests.java index f914c84c5d6b..709c9e82c0dd 100644 --- a/spring-test/src/test/java/org/springframework/test/context/aot/samples/bean/override/MockitoBeanJupiterTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/aot/samples/bean/override/MockitoBeanJupiterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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.context.junit.jupiter.SpringJUnitConfig; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.when; /** * @author Sam Brannen diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForBrokenFactoryBeanIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForBrokenFactoryBeanIntegrationTests.java index 4f8d76b0557b..fcd8535c39e8 100644 --- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForBrokenFactoryBeanIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForBrokenFactoryBeanIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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.springframework.test.context.junit.jupiter.SpringJUnitConfig; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.when; /** * Test {@link MockitoBean @MockitoBean} for a {@link FactoryBean} that is diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForByTypeLookupIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForByTypeLookupIntegrationTests.java index 72f2d03435be..36414c8d878e 100644 --- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForByTypeLookupIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForByTypeLookupIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -33,10 +33,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.BDDMockito.when; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; import static org.springframework.test.mockito.MockitoAssertions.assertIsMock; /** diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForFactoryBeanIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForFactoryBeanIntegrationTests.java index c8722a8a4a32..41fe6a15e4fe 100644 --- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForFactoryBeanIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanForFactoryBeanIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.when; /** * Test {@link MockitoBean @MockitoBean} for a factory bean configuration. diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanManuallyRegisteredSingletonTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanManuallyRegisteredSingletonTests.java index 4cb2d8cfecdc..621312abf1f4 100644 --- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanManuallyRegisteredSingletonTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanManuallyRegisteredSingletonTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,7 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.when; /** * Verifies support for overriding a manually registered singleton bean with diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanAndGenericsIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanAndGenericsIntegrationTests.java index 50f7d09e6634..9879755f29ad 100644 --- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanAndGenericsIntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanAndGenericsIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ import org.springframework.test.context.bean.override.mockito.integration.AbstractMockitoBeanAndGenericsIntegrationTests.ThingImpl; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.when; /** * Concrete implementation of {@link AbstractMockitoBeanAndGenericsIntegrationTests}. diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanAndSpringMethodRuleWithRepeatJUnit4IntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanAndSpringMethodRuleWithRepeatJUnit4IntegrationTests.java index a58e75041748..588e7ac01057 100644 --- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanAndSpringMethodRuleWithRepeatJUnit4IntegrationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/integration/MockitoBeanAndSpringMethodRuleWithRepeatJUnit4IntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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.springframework.test.context.junit4.rules.SpringMethodRule; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.when; /** * Tests for {@link MockitoBean @MockitoBean}, {@link SpringMethodRule}, and diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/FailingBeforeAndAfterMethodsSpringExtensionTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/FailingBeforeAndAfterMethodsSpringExtensionTests.java index 89df44bb8aec..8221b203d9c5 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/FailingBeforeAndAfterMethodsSpringExtensionTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/FailingBeforeAndAfterMethodsSpringExtensionTests.java @@ -106,8 +106,8 @@ private int getExpectedSucceededCount(Class testClass) { } private int getExpectedFailedCount(Class testClass) { - if (testClass == AlwaysFailingBeforeTestClassTestCase.class - || testClass == AlwaysFailingAfterTestClassTestCase.class) { + if (testClass == AlwaysFailingBeforeTestClassTestCase.class || + testClass == AlwaysFailingAfterTestClassTestCase.class) { return 0; } return 1; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/BeforeAndAfterTransactionAnnotationTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/BeforeAndAfterTransactionAnnotationTests.java index 2a1041965ead..8c2b877ecbeb 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/BeforeAndAfterTransactionAnnotationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/BeforeAndAfterTransactionAnnotationTests.java @@ -98,8 +98,7 @@ void afterTransaction() { @Before public void before() { assertShouldBeInTransaction(); - long expected = (this.inTransaction ? 1 - : 0); + long expected = (this.inTransaction ? 1 : 0); assertThat(countRowsInPersonTable(jdbcTemplate)).as("Verifying the number of rows in the person table before a test method.").isEqualTo(expected); } diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/ClassPathResourceSpringJUnit4ClassRunnerAppCtxTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/ClassPathResourceSpringJUnit4ClassRunnerAppCtxTests.java index 869664fe0b9e..cbdc15cf9cac 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/ClassPathResourceSpringJUnit4ClassRunnerAppCtxTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/ClassPathResourceSpringJUnit4ClassRunnerAppCtxTests.java @@ -42,8 +42,9 @@ public class ClassPathResourceSpringJUnit4ClassRunnerAppCtxTests extends SpringJ * @see SpringJUnit4ClassRunnerAppCtxTests#DEFAULT_CONTEXT_RESOURCE_PATH * @see ResourceUtils#CLASSPATH_URL_PREFIX */ - public static final String CLASSPATH_CONTEXT_RESOURCE_PATH = ResourceUtils.CLASSPATH_URL_PREFIX - + SpringJUnit4ClassRunnerAppCtxTests.DEFAULT_CONTEXT_RESOURCE_PATH; + public static final String CLASSPATH_CONTEXT_RESOURCE_PATH = ResourceUtils.CLASSPATH_URL_PREFIX + + SpringJUnit4ClassRunnerAppCtxTests.DEFAULT_CONTEXT_RESOURCE_PATH; /* all tests are in the parent class. */ + } diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests.java index 2ecbf57c5801..0206d6f39a07 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests.java @@ -37,10 +37,11 @@ MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests.ABSOLUTE_RESOURCE_PATH }) public class MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests extends SpringJUnit4ClassRunnerAppCtxTests { - public static final String CLASSPATH_RESOURCE_PATH = ResourceUtils.CLASSPATH_URL_PREFIX - + "/org/springframework/test/context/junit4/MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests-context1.xml"; + public static final String CLASSPATH_RESOURCE_PATH = ResourceUtils.CLASSPATH_URL_PREFIX + + "/org/springframework/test/context/junit4/MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests-context1.xml"; public static final String LOCAL_RESOURCE_PATH = "MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests-context2.xml"; public static final String ABSOLUTE_RESOURCE_PATH = "/org/springframework/test/context/junit4/MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests-context3.xml"; /* all tests are in the parent class. */ + } diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig.java index a7a1fc8bf802..3da514898986 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig.java @@ -84,8 +84,8 @@ class CustomResolver implements ActiveProfilesResolver { @Override public String[] resolve(Class testClass) { - return testClass.getSimpleName().equals("ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests") ? new String[] { "resolver" } - : new String[] {}; + return testClass.getSimpleName().equals("ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests") ? + new String[] { "resolver" } : new String[] {}; } } diff --git a/spring-test/src/test/java/org/springframework/test/context/support/ActiveProfilesUtilsTests.java b/spring-test/src/test/java/org/springframework/test/context/support/ActiveProfilesUtilsTests.java index ce233f7cb775..0a9113f3b9d5 100644 --- a/spring-test/src/test/java/org/springframework/test/context/support/ActiveProfilesUtilsTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/support/ActiveProfilesUtilsTests.java @@ -372,8 +372,8 @@ private static class TestClassVerifyingActiveProfilesResolver implements ActiveP @Override public String[] resolve(Class testClass) { - return testClass.isAnnotation() ? new String[] { "@" + testClass.getSimpleName() } - : new String[] { testClass.getSimpleName() }; + return testClass.isAnnotation() ? new String[] { "@" + testClass.getSimpleName() } : + new String[] { testClass.getSimpleName() }; } } diff --git a/spring-test/src/test/java/org/springframework/test/context/web/AbstractBasicWacTests.java b/spring-test/src/test/java/org/springframework/test/context/web/AbstractBasicWacTests.java index 32a13490a22e..70d7aca3197b 100644 --- a/spring-test/src/test/java/org/springframework/test/context/web/AbstractBasicWacTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/web/AbstractBasicWacTests.java @@ -84,8 +84,7 @@ public void basicWacFeatures() throws Exception { assertThat(webRequest).as("ServletWebRequest should have been autowired from the WAC.").isNotNull(); Object rootWac = mockServletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); - assertThat(rootWac).as("Root WAC must be stored in the ServletContext as: " - + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE).isNotNull(); + assertThat(rootWac).as("Root WAC must be stored in the ServletContext as: " + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE).isNotNull(); assertThat(rootWac).as("test WAC and Root WAC in ServletContext must be the same object.").isSameAs(wac); assertThat(wac.getServletContext()).as("ServletContext instances must be the same object.").isSameAs(mockServletContext); assertThat(request.getServletContext()).as("ServletContext in the WAC and in the mock request").isSameAs(mockServletContext); diff --git a/spring-test/src/test/java/org/springframework/test/context/web/JUnit4SpringContextWebTests.java b/spring-test/src/test/java/org/springframework/test/context/web/JUnit4SpringContextWebTests.java index a24e430b87d2..b512ceefdfea 100644 --- a/spring-test/src/test/java/org/springframework/test/context/web/JUnit4SpringContextWebTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/web/JUnit4SpringContextWebTests.java @@ -99,8 +99,7 @@ public void basicWacFeatures() throws Exception { assertThat(webRequest).as("ServletWebRequest should have been autowired from the WAC.").isNotNull(); Object rootWac = mockServletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); - assertThat(rootWac).as("Root WAC must be stored in the ServletContext as: " - + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE).isNotNull(); + assertThat(rootWac).as("Root WAC must be stored in the ServletContext as: " + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE).isNotNull(); assertThat(rootWac).as("test WAC and Root WAC in ServletContext must be the same object.").isSameAs(wac); assertThat(wac.getServletContext()).as("ServletContext instances must be the same object.").isSameAs(mockServletContext); assertThat(request.getServletContext()).as("ServletContext in the WAC and in the mock request").isSameAs(mockServletContext); diff --git a/spring-test/src/test/java/org/springframework/test/context/web/MetaAnnotationConfigWacTests.java b/spring-test/src/test/java/org/springframework/test/context/web/MetaAnnotationConfigWacTests.java index 373780b0768f..d821d4e49e89 100644 --- a/spring-test/src/test/java/org/springframework/test/context/web/MetaAnnotationConfigWacTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/web/MetaAnnotationConfigWacTests.java @@ -63,8 +63,7 @@ void basicWacFeatures() throws Exception { assertThat(mockServletContext).as("ServletContext should have been autowired from the WAC.").isNotNull(); Object rootWac = mockServletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); - assertThat(rootWac).as("Root WAC must be stored in the ServletContext as: " - + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE).isNotNull(); + assertThat(rootWac).as("Root WAC must be stored in the ServletContext as: " + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE).isNotNull(); assertThat(rootWac).as("test WAC and Root WAC in ServletContext must be the same object.").isSameAs(wac); assertThat(wac.getServletContext()).as("ServletContext instances must be the same object.").isSameAs(mockServletContext); diff --git a/spring-test/src/test/java/org/springframework/test/web/Person.java b/spring-test/src/test/java/org/springframework/test/web/Person.java index c3f11753b7b8..9a5f2381cae5 100644 --- a/spring-test/src/test/java/org/springframework/test/web/Person.java +++ b/spring-test/src/test/java/org/springframework/test/web/Person.java @@ -81,8 +81,8 @@ public int hashCode() { @Override public String toString() { - return "Person [name=" + this.name + ", someDouble=" + this.someDouble - + ", someBoolean=" + this.someBoolean + "]"; + return "Person [name=" + this.name + ", someDouble=" + this.someDouble + + ", someBoolean=" + this.someBoolean + "]"; } } diff --git a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/XmlContentTests.java b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/XmlContentTests.java index c913d3235229..a420cc4a2136 100644 --- a/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/XmlContentTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/reactive/server/samples/XmlContentTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,13 +48,14 @@ */ class XmlContentTests { - private static final String persons_XML = - "" - + "" - + "Jane" - + "Jason" - + "John" - + ""; + private static final String persons_XML = """ + + + Jane + Jason + John + + """; private final WebTestClient client = WebTestClient.bindToController(new PersonController()).build(); diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilderTests.java index 96073fa71d33..718fb1702eeb 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilderTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilderTests.java @@ -706,8 +706,7 @@ void buildRequestSessionWithExistingSession() { webRequest.setAdditionalHeader("Cookie", "JSESSIONID=" + sessionId + "NEW"); actualRequest = requestBuilder.buildRequest(servletContext); assertThat(actualRequest.getSession()).isNotEqualTo(session); - assertSingleSessionCookie("JSESSIONID=" + actualRequest.getSession().getId() - + "; Path=/test; Domain=example.com"); + assertSingleSessionCookie("JSESSIONID=" + actualRequest.getSession().getId() + "; Path=/test; Domain=example.com"); } @Test @@ -763,8 +762,8 @@ void buildRequestSessionInvalidate() { sessionToRemove.invalidate(); assertThat(sessions.containsKey(sessionToRemove.getId())).isFalse(); - assertSingleSessionCookie("JSESSIONID=" + sessionToRemove.getId() - + "; Expires=Thu, 01-Jan-1970 00:00:01 GMT; Path=/test; Domain=example.com"); + assertSingleSessionCookie("JSESSIONID=" + sessionToRemove.getId() + + "; Expires=Thu, 01-Jan-1970 00:00:01 GMT; Path=/test; Domain=example.com"); webRequest.removeAdditionalHeader("Cookie"); requestBuilder = new HtmlUnitRequestBuilder(sessions, webClient, webRequest); diff --git a/spring-tx/src/main/java/org/springframework/transaction/reactive/AbstractReactiveTransactionManager.java b/spring-tx/src/main/java/org/springframework/transaction/reactive/AbstractReactiveTransactionManager.java index 8a3a5056b6a7..ce08817223bc 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/reactive/AbstractReactiveTransactionManager.java +++ b/spring-tx/src/main/java/org/springframework/transaction/reactive/AbstractReactiveTransactionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -494,21 +494,17 @@ else if (ErrorPredicates.TRANSACTION_EXCEPTION.test(ex)) { })); } else if (ErrorPredicates.RUNTIME_OR_ERROR.test(ex)) { - Mono mono; + Mono mono = Mono.empty(); if (!beforeCompletionInvoked.get()) { mono = triggerBeforeCompletion(synchronizationManager, status); } - else { - mono = Mono.empty(); - } result = mono.then(doRollbackOnCommitException(synchronizationManager, status, ex)) .then(propagateException); } - return result; }) .then(Mono.defer(() -> triggerAfterCommit(synchronizationManager, status).onErrorResume(ex -> - triggerAfterCompletion(synchronizationManager, status, TransactionSynchronization.STATUS_COMMITTED).then(Mono.error(ex))) + triggerAfterCompletion(synchronizationManager, status, TransactionSynchronization.STATUS_COMMITTED).then(Mono.error(ex))) .then(triggerAfterCompletion(synchronizationManager, status, TransactionSynchronization.STATUS_COMMITTED)) .then(Mono.defer(() -> { if (status.isNewTransaction()) { @@ -518,8 +514,8 @@ else if (ErrorPredicates.RUNTIME_OR_ERROR.test(ex)) { })))); return commit - .onErrorResume(ex -> cleanupAfterCompletion(synchronizationManager, status) - .then(Mono.error(ex))).then(cleanupAfterCompletion(synchronizationManager, status)); + .onErrorResume(ex -> cleanupAfterCompletion(synchronizationManager, status).then(Mono.error(ex))) + .then(cleanupAfterCompletion(synchronizationManager, status)); } /** @@ -571,8 +567,8 @@ private Mono processRollback(TransactionSynchronizationManager synchroniza } return beforeCompletion; } - })).onErrorResume(ErrorPredicates.RUNTIME_OR_ERROR, ex -> triggerAfterCompletion( - synchronizationManager, status, TransactionSynchronization.STATUS_UNKNOWN) + })).onErrorResume(ErrorPredicates.RUNTIME_OR_ERROR, ex -> + triggerAfterCompletion(synchronizationManager, status, TransactionSynchronization.STATUS_UNKNOWN) .then(Mono.defer(() -> { if (status.isNewTransaction()) { this.transactionExecutionListeners.forEach(listener -> listener.afterRollback(status, ex)); @@ -623,7 +619,7 @@ else if (status.hasTransaction()) { return Mono.empty(); })) .then(Mono.error(rbex)); - }).then(triggerAfterCompletion(synchronizationManager, status, TransactionSynchronization.STATUS_ROLLED_BACK)) + }).then(Mono.defer(() -> triggerAfterCompletion(synchronizationManager, status, TransactionSynchronization.STATUS_ROLLED_BACK))) .then(Mono.defer(() -> { this.transactionExecutionListeners.forEach(listener -> listener.afterRollback(status, null)); return Mono.empty(); diff --git a/spring-tx/src/test/java/org/springframework/transaction/reactive/TransactionalOperatorTests.java b/spring-tx/src/test/java/org/springframework/transaction/reactive/TransactionalOperatorTests.java index fc5b15ecf837..4bfce2fee8b3 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/reactive/TransactionalOperatorTests.java +++ b/spring-tx/src/test/java/org/springframework/transaction/reactive/TransactionalOperatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,8 +30,8 @@ import org.springframework.transaction.support.DefaultTransactionDefinition; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; /** diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartParser.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartParser.java index 04a658e01adf..25390ad7a7db 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartParser.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartParser.java @@ -416,14 +416,13 @@ public void onNext(DataBuffer buf) { */ private boolean isLastBoundary(DataBuffer buf) { return (this.buffers.isEmpty() && - buf.readableByteCount() >= 2 && - buf.getByte(0) == HYPHEN && buf.getByte(1) == HYPHEN) - || + buf.readableByteCount() >= 2 && + buf.getByte(0) == HYPHEN && buf.getByte(1) == HYPHEN) || (this.buffers.size() == 1 && - this.buffers.get(0).readableByteCount() == 1 && - this.buffers.get(0).getByte(0) == HYPHEN && - buf.readableByteCount() >= 1 && - buf.getByte(0) == HYPHEN); + this.buffers.get(0).readableByteCount() == 1 && + this.buffers.get(0).getByte(0) == HYPHEN && + buf.readableByteCount() >= 1 && + buf.getByte(0) == HYPHEN); } /** diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartUtils.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartUtils.java index b7e4d07db0f5..0bb5f715888b 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartUtils.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/MultipartUtils.java @@ -104,7 +104,7 @@ public static void deleteFile(Path file) { public static boolean isFormField(HttpHeaders headers) { MediaType contentType = headers.getContentType(); - return (contentType == null || MediaType.TEXT_PLAIN.equalsTypeAndSubtype(contentType)) - && headers.getContentDisposition().getFilename() == null; + return (contentType == null || MediaType.TEXT_PLAIN.equalsTypeAndSubtype(contentType)) && + headers.getContentDisposition().getFilename() == null; } } diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/PartEventHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/PartEventHttpMessageReader.java index 68dc17e57fb7..964d124e2b9b 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/PartEventHttpMessageReader.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/PartEventHttpMessageReader.java @@ -212,8 +212,8 @@ private Publisher createEvents(HttpHeaders headers, Flux diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java index cb7b94b8bdb1..62838ef7bbf7 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/PartGenerator.java @@ -163,9 +163,8 @@ boolean changeState(State oldState, State newState) { return true; } else { - logger.warn("Could not switch from " + oldState + - " to " + newState + "; current state:" - + this.state.get()); + logger.warn("Could not switch from " + oldState + " to " + newState + + "; current state:" + this.state.get()); return false; } } diff --git a/spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java index 34062542faa4..38295f2895f5 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,17 +350,22 @@ public MultiValueMap read(@Nullable Class result = new LinkedMultiValueMap<>(pairs.length); - for (String pair : pairs) { - int idx = pair.indexOf('='); - if (idx == -1) { - result.add(URLDecoder.decode(pair, charset), null); - } - else { - String name = URLDecoder.decode(pair.substring(0, idx), charset); - String value = URLDecoder.decode(pair.substring(idx + 1), charset); - result.add(name, value); + try { + for (String pair : pairs) { + int idx = pair.indexOf('='); + if (idx == -1) { + result.add(URLDecoder.decode(pair, charset), null); + } + else { + String name = URLDecoder.decode(pair.substring(0, idx), charset); + String value = URLDecoder.decode(pair.substring(idx + 1), charset); + result.add(name, value); + } } } + catch (IllegalArgumentException ex) { + throw new HttpMessageNotReadableException("Could not decode HTTP form payload", ex, inputMessage); + } return result; } diff --git a/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java b/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java index bef29cf0e2b4..609bab7e980b 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java +++ b/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -297,14 +297,7 @@ private static void parseCommaDelimitedOrigin(String rawValue, Consumer * allowCredentials} is set to {@code true}, that combination is handled * by copying the method specified in the CORS preflight request. *

    If not set, only {@code "GET"} and {@code "HEAD"} are allowed. - *

    By default this is not set. - *

    Note: CORS checks use values from "Forwarded" - * (RFC 7239), - * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, - * if present, in order to reflect the client-originated address. - * Consider using the {@code ForwardedHeaderFilter} in order to choose from a - * central place whether to extract and use, or to discard such headers. - * See the Spring Framework reference for more on this filter. + *

    By default, this is not set. */ public void setAllowedMethods(@Nullable List allowedMethods) { this.allowedMethods = (allowedMethods != null ? new ArrayList<>(allowedMethods) : null); @@ -456,7 +449,7 @@ public void addExposedHeader(String exposedHeader) { * level of trust with the configured domains and also increases the surface * attack of the web application by exposing sensitive user-specific * information such as cookies and CSRF tokens. - *

    By default this is not set (i.e. user credentials are not supported). + *

    By default, this is not set (i.e. user credentials are not supported). */ public void setAllowCredentials(@Nullable Boolean allowCredentials) { this.allowCredentials = allowCredentials; @@ -480,7 +473,7 @@ public Boolean getAllowCredentials() { *

    Setting this property has an impact on how {@link #setAllowedOrigins(List) * origins} and {@link #setAllowedOriginPatterns(List) originPatterns} are processed, * see related API documentation for more details. - *

    By default this is not set (i.e. private network access is not supported). + *

    By default, this is not set (i.e. private network access is not supported). * @since 5.3.32 * @see Private network access specifications */ @@ -759,8 +752,8 @@ public List checkHeaders(@Nullable List requestHeaders) { } boolean allowAnyHeader = this.allowedHeaders.contains(ALL); - int maxResultSize = allowAnyHeader ? requestHeaders.size() - : Math.min(requestHeaders.size(), this.allowedHeaders.size()); + int maxResultSize = (allowAnyHeader ? requestHeaders.size() : + Math.min(requestHeaders.size(), this.allowedHeaders.size())); List result = new ArrayList<>(maxResultSize); for (String requestHeader : requestHeaders) { if (StringUtils.hasText(requestHeader)) { diff --git a/spring-web/src/main/java/org/springframework/web/cors/reactive/CorsUtils.java b/spring-web/src/main/java/org/springframework/web/cors/reactive/CorsUtils.java index c5256f24d6fa..394df76441e3 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/reactive/CorsUtils.java +++ b/spring-web/src/main/java/org/springframework/web/cors/reactive/CorsUtils.java @@ -50,9 +50,8 @@ public static boolean isCorsRequest(ServerHttpRequest request) { */ public static boolean isPreFlightRequest(ServerHttpRequest request) { HttpHeaders headers = request.getHeaders(); - return (request.getMethod() == HttpMethod.OPTIONS - && headers.containsKey(HttpHeaders.ORIGIN) - && headers.containsKey(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD)); + return (request.getMethod() == HttpMethod.OPTIONS && headers.containsKey(HttpHeaders.ORIGIN) && + headers.containsKey(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD)); } /** diff --git a/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java index 6f14f487aee8..5ef91ce2226f 100644 --- a/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,6 +20,7 @@ import java.lang.reflect.Method; import java.util.Arrays; import java.util.Map; +import java.util.Objects; import kotlin.Unit; import kotlin.jvm.JvmClassMappingKt; @@ -320,13 +321,10 @@ public static Object invokeFunction(Method method, Object target, Object[] args) Object arg = args[index]; if (!(parameter.isOptional() && arg == null)) { KType type = parameter.getType(); - if (!(type.isMarkedNullable() && arg == null) && type.getClassifier() instanceof KClass kClass - && KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass))) { - KFunction constructor = KClasses.getPrimaryConstructor(kClass); - if (!KCallablesJvm.isAccessible(constructor)) { - KCallablesJvm.setAccessible(constructor, true); - } - arg = constructor.call(arg); + if (!(type.isMarkedNullable() && arg == null) && + type.getClassifier() instanceof KClass kClass && + KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass))) { + arg = box(kClass, arg); } argMap.put(parameter, arg); } @@ -341,6 +339,20 @@ public static Object invokeFunction(Method method, Object target, Object[] args) return (result == Unit.INSTANCE ? null : result); } + private static Object box(KClass kClass, @Nullable Object arg) { + KFunction constructor = Objects.requireNonNull(KClasses.getPrimaryConstructor(kClass)); + KType type = constructor.getParameters().get(0).getType(); + if (!(type.isMarkedNullable() && arg == null) && + type.getClassifier() instanceof KClass parameterClass && + KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(parameterClass))) { + arg = box(parameterClass, arg); + } + if (!KCallablesJvm.isAccessible(constructor)) { + KCallablesJvm.setAccessible(constructor, true); + } + return constructor.call(arg); + } + private static void handleResult(Object result, SynchronousSink sink) { if (KotlinDetector.isInlineClass(result.getClass())) { try { @@ -361,7 +373,11 @@ private static void handleResult(Object result, SynchronousSink sink) { } private static Object unbox(Object result) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException { - return result.getClass().getDeclaredMethod("unbox-impl").invoke(result); + Object unboxed = result.getClass().getDeclaredMethod("unbox-impl").invoke(result); + if (KotlinDetector.isInlineClass(unboxed.getClass())) { + return unbox(unboxed); + } + return unboxed; } } diff --git a/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java b/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java index 0500180897b1..0c84ef9d0055 100644 --- a/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java +++ b/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -119,7 +119,7 @@ public DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse re this(request, response, sessionManager, codecConfigurer, localeContextResolver, null); } - DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse response, + protected DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse response, WebSessionManager sessionManager, ServerCodecConfigurer codecConfigurer, LocaleContextResolver localeContextResolver, @Nullable ApplicationContext applicationContext) { diff --git a/spring-web/src/test/java/org/springframework/http/converter/FormHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/FormHttpMessageConverterTests.java index 98c937bc7339..e0ac599e3f57 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/FormHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/FormHttpMessageConverterTests.java @@ -49,6 +49,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED; import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.MULTIPART_FORM_DATA; @@ -132,6 +133,27 @@ void readForm() throws Exception { assertThat(result.getFirst("name 3")).as("Invalid result").isNull(); } + @Test + void readInvalidFormWithValueThatWontUrlDecode() { + //java.net.URLDecoder doesn't like negative integer values after a % character + String body = "name+1=value+1&name+2=value+2%" + ((char)-1); + assertInvalidFormIsRejectedWithSpecificException(body); + } + + @Test + void readInvalidFormWithNameThatWontUrlDecode() { + //java.net.URLDecoder doesn't like negative integer values after a % character + String body = "name+1=value+1&name+2%" + ((char)-1) + "=value+2"; + assertInvalidFormIsRejectedWithSpecificException(body); + } + + @Test + void readInvalidFormWithNameWithNoValueThatWontUrlDecode() { + //java.net.URLDecoder doesn't like negative integer values after a % character + String body = "name+1=value+1&name+2%" + ((char)-1); + assertInvalidFormIsRejectedWithSpecificException(body); + } + @Test void writeForm() throws IOException { MultiValueMap body = new LinkedMultiValueMap<>(); @@ -410,6 +432,17 @@ private void assertCannotWrite(MediaType mediaType) { assertThat(this.converter.canWrite(clazz, mediaType)).as(clazz.getSimpleName() + " : " + mediaType).isFalse(); } + private void assertInvalidFormIsRejectedWithSpecificException(String body) { + MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.ISO_8859_1)); + inputMessage.getHeaders().setContentType( + new MediaType("application", "x-www-form-urlencoded", StandardCharsets.ISO_8859_1)); + + assertThatThrownBy(() -> this.converter.read(null, inputMessage)) + .isInstanceOf(HttpMessageNotReadableException.class) + .hasCauseInstanceOf(IllegalArgumentException.class) + .hasMessage("Could not decode HTTP form payload"); + } + private static class MockHttpOutputMessageRequestContext implements UploadContext { diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilderTests.java b/spring-web/src/test/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilderTests.java index f7621a5268b1..bfe5aa74b7d6 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatRuntimeException; import static org.junit.jupiter.params.provider.Arguments.argumentSet; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.when; class DefaultServerHttpRequestBuilderTests { diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/ErrorHandlerIntegrationTests.java b/spring-web/src/test/java/org/springframework/http/server/reactive/ErrorHandlerIntegrationTests.java index 145d6a8cedc8..6bf4bc549778 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/ErrorHandlerIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/ErrorHandlerIntegrationTests.java @@ -88,8 +88,8 @@ void emptyPathSegments(HttpServer httpServer) throws Exception { // but an application can apply CompactPathRule via RewriteHandler: // https://www.eclipse.org/jetty/documentation/jetty-11/programming_guide.php - HttpStatus expectedStatus = (httpServer instanceof JettyHttpServer || httpServer instanceof JettyCoreHttpServer - ? HttpStatus.BAD_REQUEST : HttpStatus.OK); + HttpStatus expectedStatus = (httpServer instanceof JettyHttpServer || httpServer instanceof JettyCoreHttpServer ? + HttpStatus.BAD_REQUEST : HttpStatus.OK); assertThat(response.getStatusCode()).isEqualTo(expectedStatus); } diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/ZeroCopyIntegrationTests.java b/spring-web/src/test/java/org/springframework/http/server/reactive/ZeroCopyIntegrationTests.java index eb243953e085..82e7652b0a4f 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/ZeroCopyIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/ZeroCopyIntegrationTests.java @@ -55,8 +55,8 @@ protected HttpHandler createHttpHandler() { @ParameterizedHttpServerTest void zeroCopy(HttpServer httpServer) throws Exception { - assumeTrue(httpServer instanceof ReactorHttpServer || httpServer instanceof UndertowHttpServer - || httpServer instanceof JettyCoreHttpServer, "Zero-copy does not support Servlet"); + assumeTrue(httpServer instanceof ReactorHttpServer || httpServer instanceof UndertowHttpServer || + httpServer instanceof JettyCoreHttpServer, "Zero-copy does not support Servlet"); startServer(httpServer); diff --git a/spring-web/src/test/java/org/springframework/web/ErrorResponseExceptionTests.java b/spring-web/src/test/java/org/springframework/web/ErrorResponseExceptionTests.java index 9ad7ee09b98e..ff963a44a796 100644 --- a/spring-web/src/test/java/org/springframework/web/ErrorResponseExceptionTests.java +++ b/spring-web/src/test/java/org/springframework/web/ErrorResponseExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,9 +60,9 @@ import org.springframework.web.util.BindErrorUtils; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.reset; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.when; /** * Unit tests that verify the HTTP response details exposed by exceptions in the diff --git a/spring-web/src/test/java/org/springframework/web/bind/support/DefaultDataBinderFactoryTests.java b/spring-web/src/test/java/org/springframework/web/bind/support/DefaultDataBinderFactoryTests.java index 046fe7ab4c4b..d0a372723a71 100644 --- a/spring-web/src/test/java/org/springframework/web/bind/support/DefaultDataBinderFactoryTests.java +++ b/spring-web/src/test/java/org/springframework/web/bind/support/DefaultDataBinderFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,8 +31,8 @@ import org.springframework.web.testfixture.servlet.MockHttpServletRequest; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Tests for {@link DefaultDataBinderFactory}. diff --git a/spring-web/src/test/java/org/springframework/web/context/request/async/AsyncRequestNotUsableTests.java b/spring-web/src/test/java/org/springframework/web/context/request/async/AsyncRequestNotUsableTests.java index 0033627dfb9a..b5e23efd12fb 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/async/AsyncRequestNotUsableTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/async/AsyncRequestNotUsableTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,12 +34,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.BDDMockito.doAnswer; -import static org.mockito.BDDMockito.doThrow; import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.verify; -import static org.mockito.BDDMockito.verifyNoInteractions; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; /** * {@link StandardServletAsyncWebRequest} tests related to response wrapping in diff --git a/spring-web/src/test/java/org/springframework/web/filter/RequestLoggingFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/RequestLoggingFilterTests.java index f8d66ba991c0..f7d10f97669c 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/RequestLoggingFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/RequestLoggingFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -258,23 +258,25 @@ void allOptions() throws Exception { filter.doFilter(request, response, filterChain); assertThat(filter.beforeRequestMessage) - .isEqualTo("Before request [" - + "POST /hotels?booking=42" - + ", client=4.2.2.2" - + ", session=42" - + ", user=Arthur" - + ", headers=[Content-Type:\"application/json;charset=ISO-8859-1\", Content-Length:\"22\"]" - + "]"); + .isEqualTo(""" + Before request [\ + POST /hotels?booking=42, \ + client=4.2.2.2, \ + session=42, \ + user=Arthur, \ + headers=[Content-Type:"application/json;charset=ISO-8859-1", Content-Length:"22"]\ + ]"""); assertThat(filter.afterRequestMessage) - .isEqualTo("After request [" - + "POST /hotels?booking=42" - + ", client=4.2.2.2" - + ", session=42" - + ", user=Arthur" - + ", headers=[Content-Type:\"application/json;charset=ISO-8859-1\", Content-Length:\"22\"]" - + ", payload={\"msg\": \"Hello World\"}" - + "]"); + .isEqualTo(""" + After request [\ + POST /hotels?booking=42, \ + client=4.2.2.2, \ + session=42, \ + user=Arthur, \ + headers=[Content-Type:"application/json;charset=ISO-8859-1", Content-Length:"22"], \ + payload={"msg": "Hello World"}\ + ]"""); } private void applyFilter() throws Exception { diff --git a/spring-web/src/test/kotlin/org/springframework/web/method/support/InvocableHandlerMethodKotlinTests.kt b/spring-web/src/test/kotlin/org/springframework/web/method/support/InvocableHandlerMethodKotlinTests.kt index c1f63e8b30cc..a47f54f4ba3d 100644 --- a/spring-web/src/test/kotlin/org/springframework/web/method/support/InvocableHandlerMethodKotlinTests.kt +++ b/spring-web/src/test/kotlin/org/springframework/web/method/support/InvocableHandlerMethodKotlinTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -109,12 +109,25 @@ class InvocableHandlerMethodKotlinTests { Assertions.assertThat(value).isEqualTo(1L) } + @Test + fun nestedValueClass() { + composite.addResolver(StubArgumentResolver(Long::class.java, 1L)) + val value = getInvocable(ValueClassHandler::nestedValueClass.javaMethod!!).invokeForRequest(request, null) + Assertions.assertThat(value).isEqualTo(1L) + } + @Test fun valueClassReturnValue() { val value = getInvocable(ValueClassHandler::valueClassReturnValue.javaMethod!!).invokeForRequest(request, null) Assertions.assertThat(value).isEqualTo("foo") } + @Test + fun nestedValueClassReturnValue() { + val value = getInvocable(ValueClassHandler::nestedValueClassReturnValue.javaMethod!!).invokeForRequest(request, null) + Assertions.assertThat(value).isEqualTo("foo") + } + @Test fun resultOfUnitReturnValue() { val value = getInvocable(ValueClassHandler::resultOfUnitReturnValue.javaMethod!!).invokeForRequest(request, null) @@ -273,10 +286,14 @@ class InvocableHandlerMethodKotlinTests { fun valueClassReturnValue() = StringValueClass("foo") + fun nestedValueClassReturnValue() = NestedStringValueClass(StringValueClass("foo")) + fun resultOfUnitReturnValue() = Result.success(Unit) fun longValueClass(limit: LongValueClass) = limit.value + fun nestedValueClass(limit: ULongValueClass) = limit.value + fun doubleValueClass(limit: DoubleValueClass = DoubleValueClass(3.1)) = limit.value fun valueClassWithInit(valueClass: ValueClassWithInit) = valueClass @@ -358,9 +375,15 @@ class InvocableHandlerMethodKotlinTests { @JvmInline value class StringValueClass(val value: String) + @JvmInline + value class NestedStringValueClass(val value: StringValueClass) + @JvmInline value class LongValueClass(val value: Long) + @JvmInline + value class ULongValueClass(val value: ULong) + @JvmInline value class DoubleValueClass(val value: Double) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilder.java index b74cc841f959..bb9087ca82d3 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/accept/RequestedContentTypeResolverBuilder.java @@ -103,8 +103,7 @@ public RequestedContentTypeResolver build() { } private boolean isMediaTypeAll(List mediaTypes) { - return mediaTypes.size() == 1 - && mediaTypes.get(0).removeQualityValue().equals(MediaType.ALL); + return mediaTypes.size() == 1 && mediaTypes.get(0).removeQualityValue().equals(MediaType.ALL); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java index 32ae18c6d08f..2508a55a0e54 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Stream; import kotlin.Unit; @@ -359,13 +360,10 @@ public static Object invokeFunction(Method method, Object target, Object[] args, Object arg = args[index]; if (!(parameter.isOptional() && arg == null)) { KType type = parameter.getType(); - if (!(type.isMarkedNullable() && arg == null) && type.getClassifier() instanceof KClass kClass - && KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass))) { - KFunction constructor = KClasses.getPrimaryConstructor(kClass); - if (!KCallablesJvm.isAccessible(constructor)) { - KCallablesJvm.setAccessible(constructor, true); - } - arg = constructor.call(arg); + if (!(type.isMarkedNullable() && arg == null) && + type.getClassifier() instanceof KClass kClass && + KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass))) { + arg = box(kClass, arg); } argMap.put(parameter, arg); } @@ -381,6 +379,20 @@ public static Object invokeFunction(Method method, Object target, Object[] args, } } + private static Object box(KClass kClass, @Nullable Object arg) { + KFunction constructor = Objects.requireNonNull(KClasses.getPrimaryConstructor(kClass)); + KType type = constructor.getParameters().get(0).getType(); + if (!(type.isMarkedNullable() && arg == null) && + type.getClassifier() instanceof KClass parameterClass && + KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(parameterClass))) { + arg = box(parameterClass, arg); + } + if (!KCallablesJvm.isAccessible(constructor)) { + KCallablesJvm.setAccessible(constructor, true); + } + return constructor.call(arg); + } + private static void handleResult(Object result, SynchronousSink sink) { if (KotlinDetector.isInlineClass(result.getClass())) { try { @@ -401,7 +413,11 @@ private static void handleResult(Object result, SynchronousSink sink) { } private static Object unbox(Object result) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException { - return result.getClass().getDeclaredMethod("unbox-impl").invoke(result); + Object unboxed = result.getClass().getDeclaredMethod("unbox-impl").invoke(result); + if (KotlinDetector.isInlineClass(unboxed.getClass())) { + return unbox(unboxed); + } + return unboxed; } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java index 071ddc37c89c..a867ae9fc652 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java @@ -373,8 +373,8 @@ private record NonReactiveHandlerMethodPredicate(ReactiveAdapterRegistry adapter @Override public boolean test(HandlerMethod handlerMethod) { Class returnType = handlerMethod.getReturnType().getParameterType(); - return (this.adapterRegistry.getAdapter(returnType) == null - && !KotlinDetector.isSuspendingFunction(handlerMethod.getMethod())); + return (this.adapterRegistry.getAdapter(returnType) == null && + !KotlinDetector.isSuspendingFunction(handlerMethod.getMethod())); } } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/BindingContextTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/BindingContextTests.java index dab582a98c24..c7e6a69d1ca7 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/BindingContextTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/BindingContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,8 +31,8 @@ import org.springframework.web.testfixture.server.MockServerWebExchange; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.mock; -import static org.mockito.BDDMockito.when; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Tests for {@link BindingContext}. diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultWebClientTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultWebClientTests.java index 16c433429f42..6bbd653d7f10 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultWebClientTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/DefaultWebClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,11 +48,11 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.when; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; /** * Tests for {@link DefaultWebClient}. diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientObservationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientObservationTests.java index 1e5699e367ca..96c6d3a3ff0f 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientObservationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientObservationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -42,11 +42,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.when; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; /** * Tests for the {@link WebClient} {@link io.micrometer.observation.Observation observations}. @@ -72,7 +71,7 @@ void setup() { when(mockResponse.bodyToMono(Void.class)).thenReturn(Mono.empty()); when(mockResponse.bodyToFlux(String.class)).thenReturn(Flux.just("first", "second")); when(mockResponse.releaseBody()).thenReturn(Mono.empty()); - given(this.exchangeFunction.exchange(this.request.capture())).willReturn(Mono.just(mockResponse)); + when(this.exchangeFunction.exchange(this.request.capture())).thenReturn(Mono.just(mockResponse)); this.builder = WebClient.builder().baseUrl("/base").exchangeFunction(this.exchangeFunction).observationRegistry(this.observationRegistry); this.observationRegistry.observationConfig().observationHandler(new HeaderInjectingHandler()); } @@ -113,7 +112,7 @@ void recordsObservationForSuccessfulExchangeWithParentObservationInReactorContex @Test void recordsObservationForErrorExchange() { ExchangeFunction exchangeFunction = mock(); - given(exchangeFunction.exchange(any())).willReturn(Mono.error(new IllegalStateException())); + when(exchangeFunction.exchange(any())).thenReturn(Mono.error(new IllegalStateException())); WebClient client = WebClient.builder().observationRegistry(observationRegistry).exchangeFunction(exchangeFunction).build(); StepVerifier.create(client.get().uri("/path").retrieve().bodyToMono(Void.class)) .expectError(IllegalStateException.class) diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/NestedRouteIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/NestedRouteIntegrationTests.java index 6d9d35cee97a..ff6b999961b9 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/NestedRouteIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/NestedRouteIntegrationTests.java @@ -149,8 +149,8 @@ public Mono variables(ServerRequest request) { Map pathVariables = request.pathVariables(); Map attributePathVariables = (Map) request.attributes().get(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE); - assertThat((pathVariables.equals(attributePathVariables)) - || (pathVariables.isEmpty() && (attributePathVariables == null))).isTrue(); + assertThat((pathVariables.equals(attributePathVariables)) || + (pathVariables.isEmpty() && (attributePathVariables == null))).isTrue(); PathPattern pathPattern = matchingPattern(request); String pattern = pathPattern != null ? pathPattern.getPatternString() : ""; diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityExceptionHandlerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityExceptionHandlerTests.java index c8bc65ad25fe..8fa0fb913018 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityExceptionHandlerTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityExceptionHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -56,7 +56,7 @@ import org.springframework.web.testfixture.server.MockServerWebExchange; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.mock; +import static org.mockito.Mockito.mock; /** * Tests for {@link ResponseEntityExceptionHandler}. diff --git a/spring-webflux/src/test/kotlin/org/springframework/web/reactive/result/InvocableHandlerMethodKotlinTests.kt b/spring-webflux/src/test/kotlin/org/springframework/web/reactive/result/InvocableHandlerMethodKotlinTests.kt index 595928ec134e..cfdc3f17068f 100644 --- a/spring-webflux/src/test/kotlin/org/springframework/web/reactive/result/InvocableHandlerMethodKotlinTests.kt +++ b/spring-webflux/src/test/kotlin/org/springframework/web/reactive/result/InvocableHandlerMethodKotlinTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -205,6 +205,14 @@ class InvocableHandlerMethodKotlinTests { assertHandlerResultValue(result, "1") } + @Test + fun nestedValueClass() { + this.resolvers.add(stubResolver(1L, Long::class.java)) + val method = ValueClassController::nestedValueClass.javaMethod!! + val result = invoke(ValueClassController(), method,1L) + assertHandlerResultValue(result, "1") + } + @Test fun valueClassReturnValue() { val method = ValueClassController::valueClassReturnValue.javaMethod!! @@ -212,6 +220,13 @@ class InvocableHandlerMethodKotlinTests { assertHandlerResultValue(result, "foo") } + @Test + fun nestedValueClassReturnValue() { + val method = ValueClassController::nestedValueClassReturnValue.javaMethod!! + val result = invoke(ValueClassController(), method) + assertHandlerResultValue(result, "foo") + } + @Test fun resultOfUnitReturnValue() { val method = ValueClassController::resultOfUnitReturnValue.javaMethod!! @@ -448,8 +463,12 @@ class InvocableHandlerMethodKotlinTests { fun valueClass(limit: LongValueClass) = "${limit.value}" + fun nestedValueClass(limit: ULongValueClass) = "${limit.value}" + fun valueClassReturnValue() = StringValueClass("foo") + fun nestedValueClassReturnValue() = NestedStringValueClass(StringValueClass("foo")) + fun resultOfUnitReturnValue() = Result.success(Unit) fun valueClassWithDefault(limit: DoubleValueClass = DoubleValueClass(3.1)) = "${limit.value}" @@ -533,9 +552,15 @@ class InvocableHandlerMethodKotlinTests { @JvmInline value class StringValueClass(val value: String) + @JvmInline + value class NestedStringValueClass(val value: StringValueClass) + @JvmInline value class LongValueClass(val value: Long) + @JvmInline + value class ULongValueClass(val value: ULong) + @JvmInline value class DoubleValueClass(val value: Double) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/SseServerResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/SseServerResponse.java index 38d5cc8ff043..fcf687a067db 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/SseServerResponse.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/SseServerResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -173,7 +173,6 @@ public SseBuilder retry(Duration duration) { @Override public SseBuilder comment(String comment) { - Assert.hasLength(comment, "Comment must not be empty"); String[] lines = comment.split("\n"); for (String line : lines) { field("", line); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessor.java index 31323f81e8b6..6169489ca0e6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessor.java @@ -245,8 +245,8 @@ else if (returnValue instanceof ProblemDetail detail) { outputMessage.getServletResponse().setStatus(returnStatus.value()); if (returnStatus.value() == HttpStatus.OK.value()) { HttpMethod method = inputMessage.getMethod(); - if ((HttpMethod.GET.equals(method) || HttpMethod.HEAD.equals(method)) - && isResourceNotModified(inputMessage, outputMessage)) { + if ((HttpMethod.GET.equals(method) || HttpMethod.HEAD.equals(method)) && + isResourceNotModified(inputMessage, outputMessage)) { outputMessage.flush(); return; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java index c66bb0652ed4..062e6f38ef06 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,12 @@ * {@link #relativeTo(org.springframework.web.util.UriComponentsBuilder)}. * * - *

    Note: This class uses values from "Forwarded" - * (RFC 7239), - * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, - * if present, in order to reflect the client-originated protocol and address. - * Consider using the {@code ForwardedHeaderFilter} in order to choose from a - * central place whether to extract and use, or to discard such headers. - * See the Spring Framework reference for more on this filter. + *

    Note: As of 5.1, methods in this class do not extract + * {@code "Forwarded"} and {@code "X-Forwarded-*"} headers that specify the + * client-originated address. Please, use + * {@link org.springframework.web.filter.ForwardedHeaderFilter + * ForwardedHeaderFilter}, or similar from the underlying server, to extract + * and use such headers, or to discard them. * * @author Oliver Gierke * @author Rossen Stoyanchev @@ -667,8 +666,8 @@ private static CompositeUriComponentsContributor getUriComponentsContributor() { private static String resolveEmbeddedValue(String value) { if (value.contains(SystemPropertyUtils.PLACEHOLDER_PREFIX)) { WebApplicationContext webApplicationContext = getWebApplicationContext(); - if (webApplicationContext != null - && webApplicationContext.getAutowireCapableBeanFactory() instanceof ConfigurableBeanFactory cbf) { + if (webApplicationContext != null && + webApplicationContext.getAutowireCapableBeanFactory() instanceof ConfigurableBeanFactory cbf) { String resolvedEmbeddedValue = cbf.resolveEmbeddedValue(value); if (resolvedEmbeddedValue != null) { return resolvedEmbeddedValue; diff --git a/spring-webmvc/src/test/java/org/springframework/web/context/ContextLoaderTests.java b/spring-webmvc/src/test/java/org/springframework/web/context/ContextLoaderTests.java index 2f5a1d8eca99..4b5dba4e6443 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/context/ContextLoaderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/context/ContextLoaderTests.java @@ -294,8 +294,8 @@ void frameworkServletWithDefaultLocation() { @Test void frameworkServletWithCustomLocation() throws Exception { DispatcherServlet servlet = new DispatcherServlet(); - servlet.setContextConfigLocation("/org/springframework/web/context/WEB-INF/testNamespace.xml " - + "/org/springframework/web/context/WEB-INF/context-addition.xml"); + servlet.setContextConfigLocation("/org/springframework/web/context/WEB-INF/testNamespace.xml " + + "/org/springframework/web/context/WEB-INF/context-addition.xml"); servlet.init(new MockServletConfig(new MockServletContext(""), "test")); assertThat(servlet.getWebApplicationContext().containsBean("kerry")).isTrue(); assertThat(servlet.getWebApplicationContext().containsBean("kerryX")).isTrue(); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/SseServerResponseTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/SseServerResponseTests.java index fc7ea6f9f107..2a2bf761e6bd 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/SseServerResponseTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/SseServerResponseTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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. @@ -173,6 +173,26 @@ void sendWithoutData() throws Exception { assertThat(this.mockResponse.getContentAsString()).isEqualTo(expected); } + @Test // gh-34608 + void sendHeartbeat() throws Exception { + ServerResponse response = ServerResponse.sse(sse -> { + try { + sse.comment("").send(); + } + catch (IOException ex) { + throw new UncheckedIOException(ex); + } + }); + + ServerResponse.Context context = Collections::emptyList; + + ModelAndView mav = response.writeTo(this.mockRequest, this.mockResponse, context); + assertThat(mav).isNull(); + + String expected = ":\n\n"; + assertThat(this.mockResponse.getContentAsString()).isEqualTo(expected); + } + private static final class Person { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/support/HandlerFunctionAdapterTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/support/HandlerFunctionAdapterTests.java index 555c45cdddfb..f97b67b1bc52 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/support/HandlerFunctionAdapterTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/support/HandlerFunctionAdapterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 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,8 +38,8 @@ import org.springframework.web.testfixture.servlet.MockHttpServletResponse; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.BDDMockito.doThrow; -import static org.mockito.BDDMockito.mock; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; /** * Unit tests for {@link HandlerFunctionAdapter}. diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java index 3b47c09bc7f9..e2e54d3307f1 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,7 +74,7 @@ import org.springframework.web.testfixture.servlet.MockServletConfig; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.mock; +import static org.mockito.Mockito.mock; /** * Tests for {@link ResponseEntityExceptionHandler}. diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/InternalResourceViewTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/InternalResourceViewTests.java index 2c782869a614..5d017ae19441 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/InternalResourceViewTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/InternalResourceViewTests.java @@ -82,8 +82,8 @@ public int getMinorVersion() { view.render(model, request, response); assertThat(response.getForwardedUrl()).isEqualTo(url); - model.forEach((key, value) -> assertThat(request.getAttribute(key)).as("Values for model key '" + key - + "' must match").isEqualTo(value)); + model.forEach((key, value) -> assertThat(request.getAttribute(key)) + .as("Values for model key '%s' must match", key).isEqualTo(value)); } @Test diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/SockJsMessageDeliveryException.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/SockJsMessageDeliveryException.java index 59a988daa62c..f7ca9351fee5 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/SockJsMessageDeliveryException.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/SockJsMessageDeliveryException.java @@ -41,8 +41,8 @@ public SockJsMessageDeliveryException(String sessionId, List undelivered } public SockJsMessageDeliveryException(String sessionId, List undeliveredMessages, String message) { - super("Failed to deliver message(s) " + undeliveredMessages + " for session " - + sessionId + ": " + message, sessionId, null); + super("Failed to deliver message(s) " + undeliveredMessages + " for session " + sessionId + ": " + message, + sessionId, null); this.undeliveredMessages = undeliveredMessages; } diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index 2337e87c697a..791d70867892 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -55,6 +55,7 @@ + @@ -140,6 +141,7 @@ + diff --git a/src/checkstyle/checkstyle.xml b/src/checkstyle/checkstyle.xml index 2701517a0d33..0115fddad2b4 100644 --- a/src/checkstyle/checkstyle.xml +++ b/src/checkstyle/checkstyle.xml @@ -215,6 +215,14 @@ + + + + + + + @@ -263,13 +271,6 @@ value="Please use specialized AssertJ assertThat*Exception method."/> - - - - - - - diff --git a/src/nohttp/allowlist.lines b/src/nohttp/allowlist.lines index 9ef9fdc7e212..2c7592521288 100644 --- a/src/nohttp/allowlist.lines +++ b/src/nohttp/allowlist.lines @@ -2,6 +2,5 @@ ^http://jibx.sourceforge.net.* ^http://mx4j.sourceforge.net.* ^http://objenesis.org.* -^http://www.mockobjects.com.* ^http://www.w3.org/2000/xmlns/ ^http://xunitpatterns.com.*